(try_scrolling): If scroll-up-aggressively or scroll-down-aggressively
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
3 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
30
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the description of direct update
37 operations, below.)
38
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
48
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
62 |
63 expose_window (asynchronous) |
64 |
65 X expose events -----+
66
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
71
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
81
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
87
88
89 Direct operations.
90
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
95
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
102
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
108
109
110 Desired matrices.
111
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
118
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
124 argument.
125
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
131
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
137 see in dispextern.h.
138
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
146
147
148 Frame matrices.
149
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
156
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
168
169 #include <config.h>
170 #include <stdio.h>
171
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "keymap.h"
183 #include "macros.h"
184 #include "disptab.h"
185 #include "termhooks.h"
186 #include "intervals.h"
187 #include "coding.h"
188 #include "process.h"
189 #include "region-cache.h"
190 #include "fontset.h"
191 #include "blockinput.h"
192
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196 #ifdef WINDOWSNT
197 #include "w32term.h"
198 #endif
199 #ifdef MAC_OS
200 #include "macterm.h"
201
202 Cursor No_Cursor;
203 #endif
204
205 #ifndef FRAME_X_OUTPUT
206 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207 #endif
208
209 #define INFINITY 10000000
210
211 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
212 || defined (USE_GTK)
213 extern void set_frame_menubar P_ ((struct frame *f, int, int));
214 extern int pending_menu_activation;
215 #endif
216
217 extern int interrupt_input;
218 extern int command_loop_level;
219
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
222
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
225
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
231
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
241
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
244
245 /* Pointer shapes */
246 Lisp_Object Qarrow, Qhand, Qtext;
247
248 Lisp_Object Qrisky_local_variable;
249
250 /* Holds the list (error). */
251 Lisp_Object list_of_error;
252
253 /* Functions called to fontify regions of text. */
254
255 Lisp_Object Vfontification_functions;
256 Lisp_Object Qfontification_functions;
257
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window;
261
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 over them. */
264
265 int auto_raise_tool_bar_buttons_p;
266
267 /* Margin around tool bar buttons in pixels. */
268
269 Lisp_Object Vtool_bar_button_margin;
270
271 /* Thickness of shadow to draw around tool bar buttons. */
272
273 EMACS_INT tool_bar_button_relief;
274
275 /* Non-zero means automatically resize tool-bars so that all tool-bar
276 items are visible, and no blank lines remain. */
277
278 int auto_resize_tool_bars_p;
279
280 /* Non-zero means draw block and hollow cursor as wide as the glyph
281 under it. For example, if a block cursor is over a tab, it will be
282 drawn as wide as that tab on the display. */
283
284 int x_stretch_cursor_p;
285
286 /* Non-nil means don't actually do any redisplay. */
287
288 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
289
290 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
291
292 int inhibit_eval_during_redisplay;
293
294 /* Names of text properties relevant for redisplay. */
295
296 Lisp_Object Qdisplay;
297 extern Lisp_Object Qface, Qinvisible, Qwidth;
298
299 /* Symbols used in text property values. */
300
301 Lisp_Object Vdisplay_pixels_per_inch;
302 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
303 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
304 Lisp_Object Qslice;
305 Lisp_Object Qcenter;
306 Lisp_Object Qmargin, Qpointer;
307 Lisp_Object Qline_height, Qtotal;
308 extern Lisp_Object Qheight;
309 extern Lisp_Object QCwidth, QCheight, QCascent;
310 extern Lisp_Object Qscroll_bar;
311
312 /* Non-nil means highlight trailing whitespace. */
313
314 Lisp_Object Vshow_trailing_whitespace;
315
316 #ifdef HAVE_WINDOW_SYSTEM
317 extern Lisp_Object Voverflow_newline_into_fringe;
318
319 /* Test if overflow newline into fringe. Called with iterator IT
320 at or past right window margin, and with IT->current_x set. */
321
322 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
323 (!NILP (Voverflow_newline_into_fringe) \
324 && FRAME_WINDOW_P (it->f) \
325 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
326 && it->current_x == it->last_visible_x)
327
328 #endif /* HAVE_WINDOW_SYSTEM */
329
330 /* Non-nil means show the text cursor in void text areas
331 i.e. in blank areas after eol and eob. This used to be
332 the default in 21.3. */
333
334 Lisp_Object Vvoid_text_area_pointer;
335
336 /* Name of the face used to highlight trailing whitespace. */
337
338 Lisp_Object Qtrailing_whitespace;
339
340 /* The symbol `image' which is the car of the lists used to represent
341 images in Lisp. */
342
343 Lisp_Object Qimage;
344
345 /* The image map types. */
346 Lisp_Object QCmap, QCpointer;
347 Lisp_Object Qrect, Qcircle, Qpoly;
348
349 /* Non-zero means print newline to stdout before next mini-buffer
350 message. */
351
352 int noninteractive_need_newline;
353
354 /* Non-zero means print newline to message log before next message. */
355
356 static int message_log_need_newline;
357
358 /* Three markers that message_dolog uses.
359 It could allocate them itself, but that causes trouble
360 in handling memory-full errors. */
361 static Lisp_Object message_dolog_marker1;
362 static Lisp_Object message_dolog_marker2;
363 static Lisp_Object message_dolog_marker3;
364 \f
365 /* The buffer position of the first character appearing entirely or
366 partially on the line of the selected window which contains the
367 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
368 redisplay optimization in redisplay_internal. */
369
370 static struct text_pos this_line_start_pos;
371
372 /* Number of characters past the end of the line above, including the
373 terminating newline. */
374
375 static struct text_pos this_line_end_pos;
376
377 /* The vertical positions and the height of this line. */
378
379 static int this_line_vpos;
380 static int this_line_y;
381 static int this_line_pixel_height;
382
383 /* X position at which this display line starts. Usually zero;
384 negative if first character is partially visible. */
385
386 static int this_line_start_x;
387
388 /* Buffer that this_line_.* variables are referring to. */
389
390 static struct buffer *this_line_buffer;
391
392 /* Nonzero means truncate lines in all windows less wide than the
393 frame. */
394
395 int truncate_partial_width_windows;
396
397 /* A flag to control how to display unibyte 8-bit character. */
398
399 int unibyte_display_via_language_environment;
400
401 /* Nonzero means we have more than one non-mini-buffer-only frame.
402 Not guaranteed to be accurate except while parsing
403 frame-title-format. */
404
405 int multiple_frames;
406
407 Lisp_Object Vglobal_mode_string;
408
409
410 /* List of variables (symbols) which hold markers for overlay arrows.
411 The symbols on this list are examined during redisplay to determine
412 where to display overlay arrows. */
413
414 Lisp_Object Voverlay_arrow_variable_list;
415
416 /* Marker for where to display an arrow on top of the buffer text. */
417
418 Lisp_Object Voverlay_arrow_position;
419
420 /* String to display for the arrow. Only used on terminal frames. */
421
422 Lisp_Object Voverlay_arrow_string;
423
424 /* Values of those variables at last redisplay are stored as
425 properties on `overlay-arrow-position' symbol. However, if
426 Voverlay_arrow_position is a marker, last-arrow-position is its
427 numerical position. */
428
429 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
430
431 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
432 properties on a symbol in overlay-arrow-variable-list. */
433
434 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
435
436 /* Like mode-line-format, but for the title bar on a visible frame. */
437
438 Lisp_Object Vframe_title_format;
439
440 /* Like mode-line-format, but for the title bar on an iconified frame. */
441
442 Lisp_Object Vicon_title_format;
443
444 /* List of functions to call when a window's size changes. These
445 functions get one arg, a frame on which one or more windows' sizes
446 have changed. */
447
448 static Lisp_Object Vwindow_size_change_functions;
449
450 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
451
452 /* Nonzero if overlay arrow has been displayed once in this window. */
453
454 static int overlay_arrow_seen;
455
456 /* Nonzero means highlight the region even in nonselected windows. */
457
458 int highlight_nonselected_windows;
459
460 /* If cursor motion alone moves point off frame, try scrolling this
461 many lines up or down if that will bring it back. */
462
463 static EMACS_INT scroll_step;
464
465 /* Nonzero means scroll just far enough to bring point back on the
466 screen, when appropriate. */
467
468 static EMACS_INT scroll_conservatively;
469
470 /* Recenter the window whenever point gets within this many lines of
471 the top or bottom of the window. This value is translated into a
472 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
473 that there is really a fixed pixel height scroll margin. */
474
475 EMACS_INT scroll_margin;
476
477 /* Number of windows showing the buffer of the selected window (or
478 another buffer with the same base buffer). keyboard.c refers to
479 this. */
480
481 int buffer_shared;
482
483 /* Vector containing glyphs for an ellipsis `...'. */
484
485 static Lisp_Object default_invis_vector[3];
486
487 /* Zero means display the mode-line/header-line/menu-bar in the default face
488 (this slightly odd definition is for compatibility with previous versions
489 of emacs), non-zero means display them using their respective faces.
490
491 This variable is deprecated. */
492
493 int mode_line_inverse_video;
494
495 /* Prompt to display in front of the mini-buffer contents. */
496
497 Lisp_Object minibuf_prompt;
498
499 /* Width of current mini-buffer prompt. Only set after display_line
500 of the line that contains the prompt. */
501
502 int minibuf_prompt_width;
503
504 /* This is the window where the echo area message was displayed. It
505 is always a mini-buffer window, but it may not be the same window
506 currently active as a mini-buffer. */
507
508 Lisp_Object echo_area_window;
509
510 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
511 pushes the current message and the value of
512 message_enable_multibyte on the stack, the function restore_message
513 pops the stack and displays MESSAGE again. */
514
515 Lisp_Object Vmessage_stack;
516
517 /* Nonzero means multibyte characters were enabled when the echo area
518 message was specified. */
519
520 int message_enable_multibyte;
521
522 /* Nonzero if we should redraw the mode lines on the next redisplay. */
523
524 int update_mode_lines;
525
526 /* Nonzero if window sizes or contents have changed since last
527 redisplay that finished. */
528
529 int windows_or_buffers_changed;
530
531 /* Nonzero means a frame's cursor type has been changed. */
532
533 int cursor_type_changed;
534
535 /* Nonzero after display_mode_line if %l was used and it displayed a
536 line number. */
537
538 int line_number_displayed;
539
540 /* Maximum buffer size for which to display line numbers. */
541
542 Lisp_Object Vline_number_display_limit;
543
544 /* Line width to consider when repositioning for line number display. */
545
546 static EMACS_INT line_number_display_limit_width;
547
548 /* Number of lines to keep in the message log buffer. t means
549 infinite. nil means don't log at all. */
550
551 Lisp_Object Vmessage_log_max;
552
553 /* The name of the *Messages* buffer, a string. */
554
555 static Lisp_Object Vmessages_buffer_name;
556
557 /* Current, index 0, and last displayed echo area message. Either
558 buffers from echo_buffers, or nil to indicate no message. */
559
560 Lisp_Object echo_area_buffer[2];
561
562 /* The buffers referenced from echo_area_buffer. */
563
564 static Lisp_Object echo_buffer[2];
565
566 /* A vector saved used in with_area_buffer to reduce consing. */
567
568 static Lisp_Object Vwith_echo_area_save_vector;
569
570 /* Non-zero means display_echo_area should display the last echo area
571 message again. Set by redisplay_preserve_echo_area. */
572
573 static int display_last_displayed_message_p;
574
575 /* Nonzero if echo area is being used by print; zero if being used by
576 message. */
577
578 int message_buf_print;
579
580 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
581
582 Lisp_Object Qinhibit_menubar_update;
583 int inhibit_menubar_update;
584
585 /* Maximum height for resizing mini-windows. Either a float
586 specifying a fraction of the available height, or an integer
587 specifying a number of lines. */
588
589 Lisp_Object Vmax_mini_window_height;
590
591 /* Non-zero means messages should be displayed with truncated
592 lines instead of being continued. */
593
594 int message_truncate_lines;
595 Lisp_Object Qmessage_truncate_lines;
596
597 /* Set to 1 in clear_message to make redisplay_internal aware
598 of an emptied echo area. */
599
600 static int message_cleared_p;
601
602 /* Non-zero means we want a hollow cursor in windows that are not
603 selected. Zero means there's no cursor in such windows. */
604
605 Lisp_Object Vcursor_in_non_selected_windows;
606 Lisp_Object Qcursor_in_non_selected_windows;
607
608 /* How to blink the default frame cursor off. */
609 Lisp_Object Vblink_cursor_alist;
610
611 /* A scratch glyph row with contents used for generating truncation
612 glyphs. Also used in direct_output_for_insert. */
613
614 #define MAX_SCRATCH_GLYPHS 100
615 struct glyph_row scratch_glyph_row;
616 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
617
618 /* Ascent and height of the last line processed by move_it_to. */
619
620 static int last_max_ascent, last_height;
621
622 /* Non-zero if there's a help-echo in the echo area. */
623
624 int help_echo_showing_p;
625
626 /* If >= 0, computed, exact values of mode-line and header-line height
627 to use in the macros CURRENT_MODE_LINE_HEIGHT and
628 CURRENT_HEADER_LINE_HEIGHT. */
629
630 int current_mode_line_height, current_header_line_height;
631
632 /* The maximum distance to look ahead for text properties. Values
633 that are too small let us call compute_char_face and similar
634 functions too often which is expensive. Values that are too large
635 let us call compute_char_face and alike too often because we
636 might not be interested in text properties that far away. */
637
638 #define TEXT_PROP_DISTANCE_LIMIT 100
639
640 #if GLYPH_DEBUG
641
642 /* Variables to turn off display optimizations from Lisp. */
643
644 int inhibit_try_window_id, inhibit_try_window_reusing;
645 int inhibit_try_cursor_movement;
646
647 /* Non-zero means print traces of redisplay if compiled with
648 GLYPH_DEBUG != 0. */
649
650 int trace_redisplay_p;
651
652 #endif /* GLYPH_DEBUG */
653
654 #ifdef DEBUG_TRACE_MOVE
655 /* Non-zero means trace with TRACE_MOVE to stderr. */
656 int trace_move;
657
658 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
659 #else
660 #define TRACE_MOVE(x) (void) 0
661 #endif
662
663 /* Non-zero means automatically scroll windows horizontally to make
664 point visible. */
665
666 int automatic_hscrolling_p;
667
668 /* How close to the margin can point get before the window is scrolled
669 horizontally. */
670 EMACS_INT hscroll_margin;
671
672 /* How much to scroll horizontally when point is inside the above margin. */
673 Lisp_Object Vhscroll_step;
674
675 /* A list of symbols, one for each supported image type. */
676
677 Lisp_Object Vimage_types;
678
679 /* The variable `resize-mini-windows'. If nil, don't resize
680 mini-windows. If t, always resize them to fit the text they
681 display. If `grow-only', let mini-windows grow only until they
682 become empty. */
683
684 Lisp_Object Vresize_mini_windows;
685
686 /* Buffer being redisplayed -- for redisplay_window_error. */
687
688 struct buffer *displayed_buffer;
689
690 /* Value returned from text property handlers (see below). */
691
692 enum prop_handled
693 {
694 HANDLED_NORMALLY,
695 HANDLED_RECOMPUTE_PROPS,
696 HANDLED_OVERLAY_STRING_CONSUMED,
697 HANDLED_RETURN
698 };
699
700 /* A description of text properties that redisplay is interested
701 in. */
702
703 struct props
704 {
705 /* The name of the property. */
706 Lisp_Object *name;
707
708 /* A unique index for the property. */
709 enum prop_idx idx;
710
711 /* A handler function called to set up iterator IT from the property
712 at IT's current position. Value is used to steer handle_stop. */
713 enum prop_handled (*handler) P_ ((struct it *it));
714 };
715
716 static enum prop_handled handle_face_prop P_ ((struct it *));
717 static enum prop_handled handle_invisible_prop P_ ((struct it *));
718 static enum prop_handled handle_display_prop P_ ((struct it *));
719 static enum prop_handled handle_composition_prop P_ ((struct it *));
720 static enum prop_handled handle_overlay_change P_ ((struct it *));
721 static enum prop_handled handle_fontified_prop P_ ((struct it *));
722
723 /* Properties handled by iterators. */
724
725 static struct props it_props[] =
726 {
727 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
728 /* Handle `face' before `display' because some sub-properties of
729 `display' need to know the face. */
730 {&Qface, FACE_PROP_IDX, handle_face_prop},
731 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
732 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
733 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
734 {NULL, 0, NULL}
735 };
736
737 /* Value is the position described by X. If X is a marker, value is
738 the marker_position of X. Otherwise, value is X. */
739
740 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
741
742 /* Enumeration returned by some move_it_.* functions internally. */
743
744 enum move_it_result
745 {
746 /* Not used. Undefined value. */
747 MOVE_UNDEFINED,
748
749 /* Move ended at the requested buffer position or ZV. */
750 MOVE_POS_MATCH_OR_ZV,
751
752 /* Move ended at the requested X pixel position. */
753 MOVE_X_REACHED,
754
755 /* Move within a line ended at the end of a line that must be
756 continued. */
757 MOVE_LINE_CONTINUED,
758
759 /* Move within a line ended at the end of a line that would
760 be displayed truncated. */
761 MOVE_LINE_TRUNCATED,
762
763 /* Move within a line ended at a line end. */
764 MOVE_NEWLINE_OR_CR
765 };
766
767 /* This counter is used to clear the face cache every once in a while
768 in redisplay_internal. It is incremented for each redisplay.
769 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
770 cleared. */
771
772 #define CLEAR_FACE_CACHE_COUNT 500
773 static int clear_face_cache_count;
774
775 /* Record the previous terminal frame we displayed. */
776
777 static struct frame *previous_terminal_frame;
778
779 /* Non-zero while redisplay_internal is in progress. */
780
781 int redisplaying_p;
782
783 /* Non-zero means don't free realized faces. Bound while freeing
784 realized faces is dangerous because glyph matrices might still
785 reference them. */
786
787 int inhibit_free_realized_faces;
788 Lisp_Object Qinhibit_free_realized_faces;
789
790 /* If a string, XTread_socket generates an event to display that string.
791 (The display is done in read_char.) */
792
793 Lisp_Object help_echo_string;
794 Lisp_Object help_echo_window;
795 Lisp_Object help_echo_object;
796 int help_echo_pos;
797
798 /* Temporary variable for XTread_socket. */
799
800 Lisp_Object previous_help_echo_string;
801
802 /* Null glyph slice */
803
804 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
805
806 \f
807 /* Function prototypes. */
808
809 static void setup_for_ellipsis P_ ((struct it *));
810 static void mark_window_display_accurate_1 P_ ((struct window *, int));
811 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
812 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
813 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
814 static int redisplay_mode_lines P_ ((Lisp_Object, int));
815 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
816
817 #if 0
818 static int invisible_text_between_p P_ ((struct it *, int, int));
819 #endif
820
821 static int next_element_from_ellipsis P_ ((struct it *));
822 static void pint2str P_ ((char *, int, int));
823 static void pint2hrstr P_ ((char *, int, int));
824 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
825 struct text_pos));
826 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
827 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
828 static void store_frame_title_char P_ ((char));
829 static int store_frame_title P_ ((const unsigned char *, int, int));
830 static void x_consider_frame_title P_ ((Lisp_Object));
831 static void handle_stop P_ ((struct it *));
832 static int tool_bar_lines_needed P_ ((struct frame *));
833 static int single_display_prop_intangible_p P_ ((Lisp_Object));
834 static void ensure_echo_area_buffers P_ ((void));
835 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
836 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
837 static int with_echo_area_buffer P_ ((struct window *, int,
838 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
839 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
840 static void clear_garbaged_frames P_ ((void));
841 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
842 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
843 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
844 static int display_echo_area P_ ((struct window *));
845 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
846 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
847 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
848 static int string_char_and_length P_ ((const unsigned char *, int, int *));
849 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
850 struct text_pos));
851 static int compute_window_start_on_continuation_line P_ ((struct window *));
852 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
853 static void insert_left_trunc_glyphs P_ ((struct it *));
854 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
855 Lisp_Object));
856 static void extend_face_to_end_of_line P_ ((struct it *));
857 static int append_space_for_newline P_ ((struct it *, int));
858 static int make_cursor_line_fully_visible P_ ((struct window *, int));
859 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
860 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
861 static int trailing_whitespace_p P_ ((int));
862 static int message_log_check_duplicate P_ ((int, int, int, int));
863 static void push_it P_ ((struct it *));
864 static void pop_it P_ ((struct it *));
865 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
866 static void select_frame_for_redisplay P_ ((Lisp_Object));
867 static void redisplay_internal P_ ((int));
868 static int echo_area_display P_ ((int));
869 static void redisplay_windows P_ ((Lisp_Object));
870 static void redisplay_window P_ ((Lisp_Object, int));
871 static Lisp_Object redisplay_window_error ();
872 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
873 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
874 static void update_menu_bar P_ ((struct frame *, int));
875 static int try_window_reusing_current_matrix P_ ((struct window *));
876 static int try_window_id P_ ((struct window *));
877 static int display_line P_ ((struct it *));
878 static int display_mode_lines P_ ((struct window *));
879 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
880 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
881 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
882 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
883 static void display_menu_bar P_ ((struct window *));
884 static int display_count_lines P_ ((int, int, int, int, int *));
885 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
886 int, int, struct it *, int, int, int, int));
887 static void compute_line_metrics P_ ((struct it *));
888 static void run_redisplay_end_trigger_hook P_ ((struct it *));
889 static int get_overlay_strings P_ ((struct it *, int));
890 static void next_overlay_string P_ ((struct it *));
891 static void reseat P_ ((struct it *, struct text_pos, int));
892 static void reseat_1 P_ ((struct it *, struct text_pos, int));
893 static void back_to_previous_visible_line_start P_ ((struct it *));
894 static void reseat_at_previous_visible_line_start P_ ((struct it *));
895 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
896 static int next_element_from_display_vector P_ ((struct it *));
897 static int next_element_from_string P_ ((struct it *));
898 static int next_element_from_c_string P_ ((struct it *));
899 static int next_element_from_buffer P_ ((struct it *));
900 static int next_element_from_composition P_ ((struct it *));
901 static int next_element_from_image P_ ((struct it *));
902 static int next_element_from_stretch P_ ((struct it *));
903 static void load_overlay_strings P_ ((struct it *, int));
904 static int init_from_display_pos P_ ((struct it *, struct window *,
905 struct display_pos *));
906 static void reseat_to_string P_ ((struct it *, unsigned char *,
907 Lisp_Object, int, int, int, int));
908 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
909 int, int, int));
910 void move_it_vertically_backward P_ ((struct it *, int));
911 static void init_to_row_start P_ ((struct it *, struct window *,
912 struct glyph_row *));
913 static int init_to_row_end P_ ((struct it *, struct window *,
914 struct glyph_row *));
915 static void back_to_previous_line_start P_ ((struct it *));
916 static int forward_to_next_line_start P_ ((struct it *, int *));
917 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
918 Lisp_Object, int));
919 static struct text_pos string_pos P_ ((int, Lisp_Object));
920 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
921 static int number_of_chars P_ ((unsigned char *, int));
922 static void compute_stop_pos P_ ((struct it *));
923 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
924 Lisp_Object));
925 static int face_before_or_after_it_pos P_ ((struct it *, int));
926 static int next_overlay_change P_ ((int));
927 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
928 Lisp_Object, struct text_pos *,
929 int));
930 static int underlying_face_id P_ ((struct it *));
931 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
932 struct window *));
933
934 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
935 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
936
937 #ifdef HAVE_WINDOW_SYSTEM
938
939 static void update_tool_bar P_ ((struct frame *, int));
940 static void build_desired_tool_bar_string P_ ((struct frame *f));
941 static int redisplay_tool_bar P_ ((struct frame *));
942 static void display_tool_bar_line P_ ((struct it *));
943 static void notice_overwritten_cursor P_ ((struct window *,
944 enum glyph_row_area,
945 int, int, int, int));
946
947
948
949 #endif /* HAVE_WINDOW_SYSTEM */
950
951 \f
952 /***********************************************************************
953 Window display dimensions
954 ***********************************************************************/
955
956 /* Return the bottom boundary y-position for text lines in window W.
957 This is the first y position at which a line cannot start.
958 It is relative to the top of the window.
959
960 This is the height of W minus the height of a mode line, if any. */
961
962 INLINE int
963 window_text_bottom_y (w)
964 struct window *w;
965 {
966 int height = WINDOW_TOTAL_HEIGHT (w);
967
968 if (WINDOW_WANTS_MODELINE_P (w))
969 height -= CURRENT_MODE_LINE_HEIGHT (w);
970 return height;
971 }
972
973 /* Return the pixel width of display area AREA of window W. AREA < 0
974 means return the total width of W, not including fringes to
975 the left and right of the window. */
976
977 INLINE int
978 window_box_width (w, area)
979 struct window *w;
980 int area;
981 {
982 int cols = XFASTINT (w->total_cols);
983 int pixels = 0;
984
985 if (!w->pseudo_window_p)
986 {
987 cols -= WINDOW_SCROLL_BAR_COLS (w);
988
989 if (area == TEXT_AREA)
990 {
991 if (INTEGERP (w->left_margin_cols))
992 cols -= XFASTINT (w->left_margin_cols);
993 if (INTEGERP (w->right_margin_cols))
994 cols -= XFASTINT (w->right_margin_cols);
995 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
996 }
997 else if (area == LEFT_MARGIN_AREA)
998 {
999 cols = (INTEGERP (w->left_margin_cols)
1000 ? XFASTINT (w->left_margin_cols) : 0);
1001 pixels = 0;
1002 }
1003 else if (area == RIGHT_MARGIN_AREA)
1004 {
1005 cols = (INTEGERP (w->right_margin_cols)
1006 ? XFASTINT (w->right_margin_cols) : 0);
1007 pixels = 0;
1008 }
1009 }
1010
1011 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1012 }
1013
1014
1015 /* Return the pixel height of the display area of window W, not
1016 including mode lines of W, if any. */
1017
1018 INLINE int
1019 window_box_height (w)
1020 struct window *w;
1021 {
1022 struct frame *f = XFRAME (w->frame);
1023 int height = WINDOW_TOTAL_HEIGHT (w);
1024
1025 xassert (height >= 0);
1026
1027 /* Note: the code below that determines the mode-line/header-line
1028 height is essentially the same as that contained in the macro
1029 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1030 the appropriate glyph row has its `mode_line_p' flag set,
1031 and if it doesn't, uses estimate_mode_line_height instead. */
1032
1033 if (WINDOW_WANTS_MODELINE_P (w))
1034 {
1035 struct glyph_row *ml_row
1036 = (w->current_matrix && w->current_matrix->rows
1037 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1038 : 0);
1039 if (ml_row && ml_row->mode_line_p)
1040 height -= ml_row->height;
1041 else
1042 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1043 }
1044
1045 if (WINDOW_WANTS_HEADER_LINE_P (w))
1046 {
1047 struct glyph_row *hl_row
1048 = (w->current_matrix && w->current_matrix->rows
1049 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1050 : 0);
1051 if (hl_row && hl_row->mode_line_p)
1052 height -= hl_row->height;
1053 else
1054 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1055 }
1056
1057 /* With a very small font and a mode-line that's taller than
1058 default, we might end up with a negative height. */
1059 return max (0, height);
1060 }
1061
1062 /* Return the window-relative coordinate of the left edge of display
1063 area AREA of window W. AREA < 0 means return the left edge of the
1064 whole window, to the right of the left fringe of W. */
1065
1066 INLINE int
1067 window_box_left_offset (w, area)
1068 struct window *w;
1069 int area;
1070 {
1071 int x;
1072
1073 if (w->pseudo_window_p)
1074 return 0;
1075
1076 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1077
1078 if (area == TEXT_AREA)
1079 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1080 + window_box_width (w, LEFT_MARGIN_AREA));
1081 else if (area == RIGHT_MARGIN_AREA)
1082 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1083 + window_box_width (w, LEFT_MARGIN_AREA)
1084 + window_box_width (w, TEXT_AREA)
1085 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1086 ? 0
1087 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1088 else if (area == LEFT_MARGIN_AREA
1089 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1090 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1091
1092 return x;
1093 }
1094
1095
1096 /* Return the window-relative coordinate of the right edge of display
1097 area AREA of window W. AREA < 0 means return the left edge of the
1098 whole window, to the left of the right fringe of W. */
1099
1100 INLINE int
1101 window_box_right_offset (w, area)
1102 struct window *w;
1103 int area;
1104 {
1105 return window_box_left_offset (w, area) + window_box_width (w, area);
1106 }
1107
1108 /* Return the frame-relative coordinate of the left edge of display
1109 area AREA of window W. AREA < 0 means return the left edge of the
1110 whole window, to the right of the left fringe of W. */
1111
1112 INLINE int
1113 window_box_left (w, area)
1114 struct window *w;
1115 int area;
1116 {
1117 struct frame *f = XFRAME (w->frame);
1118 int x;
1119
1120 if (w->pseudo_window_p)
1121 return FRAME_INTERNAL_BORDER_WIDTH (f);
1122
1123 x = (WINDOW_LEFT_EDGE_X (w)
1124 + window_box_left_offset (w, area));
1125
1126 return x;
1127 }
1128
1129
1130 /* Return the frame-relative coordinate of the right edge of display
1131 area AREA of window W. AREA < 0 means return the left edge of the
1132 whole window, to the left of the right fringe of W. */
1133
1134 INLINE int
1135 window_box_right (w, area)
1136 struct window *w;
1137 int area;
1138 {
1139 return window_box_left (w, area) + window_box_width (w, area);
1140 }
1141
1142 /* Get the bounding box of the display area AREA of window W, without
1143 mode lines, in frame-relative coordinates. AREA < 0 means the
1144 whole window, not including the left and right fringes of
1145 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1146 coordinates of the upper-left corner of the box. Return in
1147 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1148
1149 INLINE void
1150 window_box (w, area, box_x, box_y, box_width, box_height)
1151 struct window *w;
1152 int area;
1153 int *box_x, *box_y, *box_width, *box_height;
1154 {
1155 if (box_width)
1156 *box_width = window_box_width (w, area);
1157 if (box_height)
1158 *box_height = window_box_height (w);
1159 if (box_x)
1160 *box_x = window_box_left (w, area);
1161 if (box_y)
1162 {
1163 *box_y = WINDOW_TOP_EDGE_Y (w);
1164 if (WINDOW_WANTS_HEADER_LINE_P (w))
1165 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1166 }
1167 }
1168
1169
1170 /* Get the bounding box of the display area AREA of window W, without
1171 mode lines. AREA < 0 means the whole window, not including the
1172 left and right fringe of the window. Return in *TOP_LEFT_X
1173 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1174 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1175 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1176 box. */
1177
1178 INLINE void
1179 window_box_edges (w, area, top_left_x, top_left_y,
1180 bottom_right_x, bottom_right_y)
1181 struct window *w;
1182 int area;
1183 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1184 {
1185 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1186 bottom_right_y);
1187 *bottom_right_x += *top_left_x;
1188 *bottom_right_y += *top_left_y;
1189 }
1190
1191
1192 \f
1193 /***********************************************************************
1194 Utilities
1195 ***********************************************************************/
1196
1197 /* Return the bottom y-position of the line the iterator IT is in.
1198 This can modify IT's settings. */
1199
1200 int
1201 line_bottom_y (it)
1202 struct it *it;
1203 {
1204 int line_height = it->max_ascent + it->max_descent;
1205 int line_top_y = it->current_y;
1206
1207 if (line_height == 0)
1208 {
1209 if (last_height)
1210 line_height = last_height;
1211 else if (IT_CHARPOS (*it) < ZV)
1212 {
1213 move_it_by_lines (it, 1, 1);
1214 line_height = (it->max_ascent || it->max_descent
1215 ? it->max_ascent + it->max_descent
1216 : last_height);
1217 }
1218 else
1219 {
1220 struct glyph_row *row = it->glyph_row;
1221
1222 /* Use the default character height. */
1223 it->glyph_row = NULL;
1224 it->what = IT_CHARACTER;
1225 it->c = ' ';
1226 it->len = 1;
1227 PRODUCE_GLYPHS (it);
1228 line_height = it->ascent + it->descent;
1229 it->glyph_row = row;
1230 }
1231 }
1232
1233 return line_top_y + line_height;
1234 }
1235
1236
1237 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1238 1 if POS is visible and the line containing POS is fully visible.
1239 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1240 and header-lines heights. */
1241
1242 int
1243 pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
1244 struct window *w;
1245 int charpos, *fully, *x, *y, exact_mode_line_heights_p;
1246 {
1247 struct it it;
1248 struct text_pos top;
1249 int visible_p;
1250 struct buffer *old_buffer = NULL;
1251
1252 if (XBUFFER (w->buffer) != current_buffer)
1253 {
1254 old_buffer = current_buffer;
1255 set_buffer_internal_1 (XBUFFER (w->buffer));
1256 }
1257
1258 *fully = visible_p = 0;
1259 SET_TEXT_POS_FROM_MARKER (top, w->start);
1260
1261 /* Compute exact mode line heights, if requested. */
1262 if (exact_mode_line_heights_p)
1263 {
1264 if (WINDOW_WANTS_MODELINE_P (w))
1265 current_mode_line_height
1266 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1267 current_buffer->mode_line_format);
1268
1269 if (WINDOW_WANTS_HEADER_LINE_P (w))
1270 current_header_line_height
1271 = display_mode_line (w, HEADER_LINE_FACE_ID,
1272 current_buffer->header_line_format);
1273 }
1274
1275 start_display (&it, w, top);
1276 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1277 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1278
1279 /* Note that we may overshoot because of invisible text. */
1280 if (IT_CHARPOS (it) >= charpos)
1281 {
1282 int top_y = it.current_y;
1283 int bottom_y = line_bottom_y (&it);
1284 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1285
1286 if (top_y < window_top_y)
1287 visible_p = bottom_y > window_top_y;
1288 else if (top_y < it.last_visible_y)
1289 {
1290 visible_p = 1;
1291 *fully = bottom_y <= it.last_visible_y;
1292 }
1293 if (visible_p && x)
1294 {
1295 *x = it.current_x;
1296 *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
1297 }
1298 }
1299 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1300 {
1301 struct it it2;
1302
1303 it2 = it;
1304 move_it_by_lines (&it, 1, 0);
1305 if (charpos < IT_CHARPOS (it))
1306 {
1307 visible_p = 1;
1308 if (x)
1309 {
1310 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1311 *x = it2.current_x;
1312 *y = it2.current_y + it2.max_ascent - it2.ascent;
1313 }
1314 }
1315 }
1316
1317 if (old_buffer)
1318 set_buffer_internal_1 (old_buffer);
1319
1320 current_header_line_height = current_mode_line_height = -1;
1321
1322 return visible_p;
1323 }
1324
1325
1326 /* Return the next character from STR which is MAXLEN bytes long.
1327 Return in *LEN the length of the character. This is like
1328 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1329 we find one, we return a `?', but with the length of the invalid
1330 character. */
1331
1332 static INLINE int
1333 string_char_and_length (str, maxlen, len)
1334 const unsigned char *str;
1335 int maxlen, *len;
1336 {
1337 int c;
1338
1339 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1340 if (!CHAR_VALID_P (c, 1))
1341 /* We may not change the length here because other places in Emacs
1342 don't use this function, i.e. they silently accept invalid
1343 characters. */
1344 c = '?';
1345
1346 return c;
1347 }
1348
1349
1350
1351 /* Given a position POS containing a valid character and byte position
1352 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1353
1354 static struct text_pos
1355 string_pos_nchars_ahead (pos, string, nchars)
1356 struct text_pos pos;
1357 Lisp_Object string;
1358 int nchars;
1359 {
1360 xassert (STRINGP (string) && nchars >= 0);
1361
1362 if (STRING_MULTIBYTE (string))
1363 {
1364 int rest = SBYTES (string) - BYTEPOS (pos);
1365 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1366 int len;
1367
1368 while (nchars--)
1369 {
1370 string_char_and_length (p, rest, &len);
1371 p += len, rest -= len;
1372 xassert (rest >= 0);
1373 CHARPOS (pos) += 1;
1374 BYTEPOS (pos) += len;
1375 }
1376 }
1377 else
1378 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1379
1380 return pos;
1381 }
1382
1383
1384 /* Value is the text position, i.e. character and byte position,
1385 for character position CHARPOS in STRING. */
1386
1387 static INLINE struct text_pos
1388 string_pos (charpos, string)
1389 int charpos;
1390 Lisp_Object string;
1391 {
1392 struct text_pos pos;
1393 xassert (STRINGP (string));
1394 xassert (charpos >= 0);
1395 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1396 return pos;
1397 }
1398
1399
1400 /* Value is a text position, i.e. character and byte position, for
1401 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1402 means recognize multibyte characters. */
1403
1404 static struct text_pos
1405 c_string_pos (charpos, s, multibyte_p)
1406 int charpos;
1407 unsigned char *s;
1408 int multibyte_p;
1409 {
1410 struct text_pos pos;
1411
1412 xassert (s != NULL);
1413 xassert (charpos >= 0);
1414
1415 if (multibyte_p)
1416 {
1417 int rest = strlen (s), len;
1418
1419 SET_TEXT_POS (pos, 0, 0);
1420 while (charpos--)
1421 {
1422 string_char_and_length (s, rest, &len);
1423 s += len, rest -= len;
1424 xassert (rest >= 0);
1425 CHARPOS (pos) += 1;
1426 BYTEPOS (pos) += len;
1427 }
1428 }
1429 else
1430 SET_TEXT_POS (pos, charpos, charpos);
1431
1432 return pos;
1433 }
1434
1435
1436 /* Value is the number of characters in C string S. MULTIBYTE_P
1437 non-zero means recognize multibyte characters. */
1438
1439 static int
1440 number_of_chars (s, multibyte_p)
1441 unsigned char *s;
1442 int multibyte_p;
1443 {
1444 int nchars;
1445
1446 if (multibyte_p)
1447 {
1448 int rest = strlen (s), len;
1449 unsigned char *p = (unsigned char *) s;
1450
1451 for (nchars = 0; rest > 0; ++nchars)
1452 {
1453 string_char_and_length (p, rest, &len);
1454 rest -= len, p += len;
1455 }
1456 }
1457 else
1458 nchars = strlen (s);
1459
1460 return nchars;
1461 }
1462
1463
1464 /* Compute byte position NEWPOS->bytepos corresponding to
1465 NEWPOS->charpos. POS is a known position in string STRING.
1466 NEWPOS->charpos must be >= POS.charpos. */
1467
1468 static void
1469 compute_string_pos (newpos, pos, string)
1470 struct text_pos *newpos, pos;
1471 Lisp_Object string;
1472 {
1473 xassert (STRINGP (string));
1474 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1475
1476 if (STRING_MULTIBYTE (string))
1477 *newpos = string_pos_nchars_ahead (pos, string,
1478 CHARPOS (*newpos) - CHARPOS (pos));
1479 else
1480 BYTEPOS (*newpos) = CHARPOS (*newpos);
1481 }
1482
1483 /* EXPORT:
1484 Return an estimation of the pixel height of mode or top lines on
1485 frame F. FACE_ID specifies what line's height to estimate. */
1486
1487 int
1488 estimate_mode_line_height (f, face_id)
1489 struct frame *f;
1490 enum face_id face_id;
1491 {
1492 #ifdef HAVE_WINDOW_SYSTEM
1493 if (FRAME_WINDOW_P (f))
1494 {
1495 int height = FONT_HEIGHT (FRAME_FONT (f));
1496
1497 /* This function is called so early when Emacs starts that the face
1498 cache and mode line face are not yet initialized. */
1499 if (FRAME_FACE_CACHE (f))
1500 {
1501 struct face *face = FACE_FROM_ID (f, face_id);
1502 if (face)
1503 {
1504 if (face->font)
1505 height = FONT_HEIGHT (face->font);
1506 if (face->box_line_width > 0)
1507 height += 2 * face->box_line_width;
1508 }
1509 }
1510
1511 return height;
1512 }
1513 #endif
1514
1515 return 1;
1516 }
1517
1518 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1519 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1520 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1521 not force the value into range. */
1522
1523 void
1524 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1525 FRAME_PTR f;
1526 register int pix_x, pix_y;
1527 int *x, *y;
1528 NativeRectangle *bounds;
1529 int noclip;
1530 {
1531
1532 #ifdef HAVE_WINDOW_SYSTEM
1533 if (FRAME_WINDOW_P (f))
1534 {
1535 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1536 even for negative values. */
1537 if (pix_x < 0)
1538 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1539 if (pix_y < 0)
1540 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1541
1542 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1543 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1544
1545 if (bounds)
1546 STORE_NATIVE_RECT (*bounds,
1547 FRAME_COL_TO_PIXEL_X (f, pix_x),
1548 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1549 FRAME_COLUMN_WIDTH (f) - 1,
1550 FRAME_LINE_HEIGHT (f) - 1);
1551
1552 if (!noclip)
1553 {
1554 if (pix_x < 0)
1555 pix_x = 0;
1556 else if (pix_x > FRAME_TOTAL_COLS (f))
1557 pix_x = FRAME_TOTAL_COLS (f);
1558
1559 if (pix_y < 0)
1560 pix_y = 0;
1561 else if (pix_y > FRAME_LINES (f))
1562 pix_y = FRAME_LINES (f);
1563 }
1564 }
1565 #endif
1566
1567 *x = pix_x;
1568 *y = pix_y;
1569 }
1570
1571
1572 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1573 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1574 can't tell the positions because W's display is not up to date,
1575 return 0. */
1576
1577 int
1578 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1579 struct window *w;
1580 int hpos, vpos;
1581 int *frame_x, *frame_y;
1582 {
1583 #ifdef HAVE_WINDOW_SYSTEM
1584 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1585 {
1586 int success_p;
1587
1588 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1589 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1590
1591 if (display_completed)
1592 {
1593 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1594 struct glyph *glyph = row->glyphs[TEXT_AREA];
1595 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1596
1597 hpos = row->x;
1598 vpos = row->y;
1599 while (glyph < end)
1600 {
1601 hpos += glyph->pixel_width;
1602 ++glyph;
1603 }
1604
1605 /* If first glyph is partially visible, its first visible position is still 0. */
1606 if (hpos < 0)
1607 hpos = 0;
1608
1609 success_p = 1;
1610 }
1611 else
1612 {
1613 hpos = vpos = 0;
1614 success_p = 0;
1615 }
1616
1617 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1618 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1619 return success_p;
1620 }
1621 #endif
1622
1623 *frame_x = hpos;
1624 *frame_y = vpos;
1625 return 1;
1626 }
1627
1628
1629 #ifdef HAVE_WINDOW_SYSTEM
1630
1631 /* Find the glyph under window-relative coordinates X/Y in window W.
1632 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1633 strings. Return in *HPOS and *VPOS the row and column number of
1634 the glyph found. Return in *AREA the glyph area containing X.
1635 Value is a pointer to the glyph found or null if X/Y is not on
1636 text, or we can't tell because W's current matrix is not up to
1637 date. */
1638
1639 static struct glyph *
1640 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1641 struct window *w;
1642 int x, y;
1643 int *hpos, *vpos, *dx, *dy, *area;
1644 {
1645 struct glyph *glyph, *end;
1646 struct glyph_row *row = NULL;
1647 int x0, i;
1648
1649 /* Find row containing Y. Give up if some row is not enabled. */
1650 for (i = 0; i < w->current_matrix->nrows; ++i)
1651 {
1652 row = MATRIX_ROW (w->current_matrix, i);
1653 if (!row->enabled_p)
1654 return NULL;
1655 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1656 break;
1657 }
1658
1659 *vpos = i;
1660 *hpos = 0;
1661
1662 /* Give up if Y is not in the window. */
1663 if (i == w->current_matrix->nrows)
1664 return NULL;
1665
1666 /* Get the glyph area containing X. */
1667 if (w->pseudo_window_p)
1668 {
1669 *area = TEXT_AREA;
1670 x0 = 0;
1671 }
1672 else
1673 {
1674 if (x < window_box_left_offset (w, TEXT_AREA))
1675 {
1676 *area = LEFT_MARGIN_AREA;
1677 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1678 }
1679 else if (x < window_box_right_offset (w, TEXT_AREA))
1680 {
1681 *area = TEXT_AREA;
1682 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1683 }
1684 else
1685 {
1686 *area = RIGHT_MARGIN_AREA;
1687 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1688 }
1689 }
1690
1691 /* Find glyph containing X. */
1692 glyph = row->glyphs[*area];
1693 end = glyph + row->used[*area];
1694 x -= x0;
1695 while (glyph < end && x >= glyph->pixel_width)
1696 {
1697 x -= glyph->pixel_width;
1698 ++glyph;
1699 }
1700
1701 if (glyph == end)
1702 return NULL;
1703
1704 if (dx)
1705 {
1706 *dx = x;
1707 *dy = y - (row->y + row->ascent - glyph->ascent);
1708 }
1709
1710 *hpos = glyph - row->glyphs[*area];
1711 return glyph;
1712 }
1713
1714
1715 /* EXPORT:
1716 Convert frame-relative x/y to coordinates relative to window W.
1717 Takes pseudo-windows into account. */
1718
1719 void
1720 frame_to_window_pixel_xy (w, x, y)
1721 struct window *w;
1722 int *x, *y;
1723 {
1724 if (w->pseudo_window_p)
1725 {
1726 /* A pseudo-window is always full-width, and starts at the
1727 left edge of the frame, plus a frame border. */
1728 struct frame *f = XFRAME (w->frame);
1729 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1730 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1731 }
1732 else
1733 {
1734 *x -= WINDOW_LEFT_EDGE_X (w);
1735 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1736 }
1737 }
1738
1739 /* EXPORT:
1740 Return in *R the clipping rectangle for glyph string S. */
1741
1742 void
1743 get_glyph_string_clip_rect (s, nr)
1744 struct glyph_string *s;
1745 NativeRectangle *nr;
1746 {
1747 XRectangle r;
1748
1749 if (s->row->full_width_p)
1750 {
1751 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1752 r.x = WINDOW_LEFT_EDGE_X (s->w);
1753 r.width = WINDOW_TOTAL_WIDTH (s->w);
1754
1755 /* Unless displaying a mode or menu bar line, which are always
1756 fully visible, clip to the visible part of the row. */
1757 if (s->w->pseudo_window_p)
1758 r.height = s->row->visible_height;
1759 else
1760 r.height = s->height;
1761 }
1762 else
1763 {
1764 /* This is a text line that may be partially visible. */
1765 r.x = window_box_left (s->w, s->area);
1766 r.width = window_box_width (s->w, s->area);
1767 r.height = s->row->visible_height;
1768 }
1769
1770 /* If S draws overlapping rows, it's sufficient to use the top and
1771 bottom of the window for clipping because this glyph string
1772 intentionally draws over other lines. */
1773 if (s->for_overlaps_p)
1774 {
1775 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1776 r.height = window_text_bottom_y (s->w) - r.y;
1777 }
1778 else
1779 {
1780 /* Don't use S->y for clipping because it doesn't take partially
1781 visible lines into account. For example, it can be negative for
1782 partially visible lines at the top of a window. */
1783 if (!s->row->full_width_p
1784 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1785 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1786 else
1787 r.y = max (0, s->row->y);
1788
1789 /* If drawing a tool-bar window, draw it over the internal border
1790 at the top of the window. */
1791 if (s->w == XWINDOW (s->f->tool_bar_window))
1792 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1793 }
1794
1795 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1796
1797 /* If drawing the cursor, don't let glyph draw outside its
1798 advertised boundaries. Cleartype does this under some circumstances. */
1799 if (s->hl == DRAW_CURSOR)
1800 {
1801 struct glyph *glyph = s->first_glyph;
1802 int height;
1803
1804 if (s->x > r.x)
1805 {
1806 r.width -= s->x - r.x;
1807 r.x = s->x;
1808 }
1809 r.width = min (r.width, glyph->pixel_width);
1810
1811 /* Don't draw cursor glyph taller than our actual glyph. */
1812 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1813 if (height < r.height)
1814 {
1815 int max_y = r.y + r.height;
1816 r.y = min (max_y, s->ybase + glyph->descent - height);
1817 r.height = min (max_y - r.y, height);
1818 }
1819 }
1820
1821 #ifdef CONVERT_FROM_XRECT
1822 CONVERT_FROM_XRECT (r, *nr);
1823 #else
1824 *nr = r;
1825 #endif
1826 }
1827
1828 #endif /* HAVE_WINDOW_SYSTEM */
1829
1830 \f
1831 /***********************************************************************
1832 Lisp form evaluation
1833 ***********************************************************************/
1834
1835 /* Error handler for safe_eval and safe_call. */
1836
1837 static Lisp_Object
1838 safe_eval_handler (arg)
1839 Lisp_Object arg;
1840 {
1841 add_to_log ("Error during redisplay: %s", arg, Qnil);
1842 return Qnil;
1843 }
1844
1845
1846 /* Evaluate SEXPR and return the result, or nil if something went
1847 wrong. Prevent redisplay during the evaluation. */
1848
1849 Lisp_Object
1850 safe_eval (sexpr)
1851 Lisp_Object sexpr;
1852 {
1853 Lisp_Object val;
1854
1855 if (inhibit_eval_during_redisplay)
1856 val = Qnil;
1857 else
1858 {
1859 int count = SPECPDL_INDEX ();
1860 struct gcpro gcpro1;
1861
1862 GCPRO1 (sexpr);
1863 specbind (Qinhibit_redisplay, Qt);
1864 /* Use Qt to ensure debugger does not run,
1865 so there is no possibility of wanting to redisplay. */
1866 val = internal_condition_case_1 (Feval, sexpr, Qt,
1867 safe_eval_handler);
1868 UNGCPRO;
1869 val = unbind_to (count, val);
1870 }
1871
1872 return val;
1873 }
1874
1875
1876 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1877 Return the result, or nil if something went wrong. Prevent
1878 redisplay during the evaluation. */
1879
1880 Lisp_Object
1881 safe_call (nargs, args)
1882 int nargs;
1883 Lisp_Object *args;
1884 {
1885 Lisp_Object val;
1886
1887 if (inhibit_eval_during_redisplay)
1888 val = Qnil;
1889 else
1890 {
1891 int count = SPECPDL_INDEX ();
1892 struct gcpro gcpro1;
1893
1894 GCPRO1 (args[0]);
1895 gcpro1.nvars = nargs;
1896 specbind (Qinhibit_redisplay, Qt);
1897 /* Use Qt to ensure debugger does not run,
1898 so there is no possibility of wanting to redisplay. */
1899 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1900 safe_eval_handler);
1901 UNGCPRO;
1902 val = unbind_to (count, val);
1903 }
1904
1905 return val;
1906 }
1907
1908
1909 /* Call function FN with one argument ARG.
1910 Return the result, or nil if something went wrong. */
1911
1912 Lisp_Object
1913 safe_call1 (fn, arg)
1914 Lisp_Object fn, arg;
1915 {
1916 Lisp_Object args[2];
1917 args[0] = fn;
1918 args[1] = arg;
1919 return safe_call (2, args);
1920 }
1921
1922
1923 \f
1924 /***********************************************************************
1925 Debugging
1926 ***********************************************************************/
1927
1928 #if 0
1929
1930 /* Define CHECK_IT to perform sanity checks on iterators.
1931 This is for debugging. It is too slow to do unconditionally. */
1932
1933 static void
1934 check_it (it)
1935 struct it *it;
1936 {
1937 if (it->method == next_element_from_string)
1938 {
1939 xassert (STRINGP (it->string));
1940 xassert (IT_STRING_CHARPOS (*it) >= 0);
1941 }
1942 else
1943 {
1944 xassert (IT_STRING_CHARPOS (*it) < 0);
1945 if (it->method == next_element_from_buffer)
1946 {
1947 /* Check that character and byte positions agree. */
1948 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1949 }
1950 }
1951
1952 if (it->dpvec)
1953 xassert (it->current.dpvec_index >= 0);
1954 else
1955 xassert (it->current.dpvec_index < 0);
1956 }
1957
1958 #define CHECK_IT(IT) check_it ((IT))
1959
1960 #else /* not 0 */
1961
1962 #define CHECK_IT(IT) (void) 0
1963
1964 #endif /* not 0 */
1965
1966
1967 #if GLYPH_DEBUG
1968
1969 /* Check that the window end of window W is what we expect it
1970 to be---the last row in the current matrix displaying text. */
1971
1972 static void
1973 check_window_end (w)
1974 struct window *w;
1975 {
1976 if (!MINI_WINDOW_P (w)
1977 && !NILP (w->window_end_valid))
1978 {
1979 struct glyph_row *row;
1980 xassert ((row = MATRIX_ROW (w->current_matrix,
1981 XFASTINT (w->window_end_vpos)),
1982 !row->enabled_p
1983 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1984 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1985 }
1986 }
1987
1988 #define CHECK_WINDOW_END(W) check_window_end ((W))
1989
1990 #else /* not GLYPH_DEBUG */
1991
1992 #define CHECK_WINDOW_END(W) (void) 0
1993
1994 #endif /* not GLYPH_DEBUG */
1995
1996
1997 \f
1998 /***********************************************************************
1999 Iterator initialization
2000 ***********************************************************************/
2001
2002 /* Initialize IT for displaying current_buffer in window W, starting
2003 at character position CHARPOS. CHARPOS < 0 means that no buffer
2004 position is specified which is useful when the iterator is assigned
2005 a position later. BYTEPOS is the byte position corresponding to
2006 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2007
2008 If ROW is not null, calls to produce_glyphs with IT as parameter
2009 will produce glyphs in that row.
2010
2011 BASE_FACE_ID is the id of a base face to use. It must be one of
2012 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2013 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2014 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2015
2016 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2017 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2018 will be initialized to use the corresponding mode line glyph row of
2019 the desired matrix of W. */
2020
2021 void
2022 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2023 struct it *it;
2024 struct window *w;
2025 int charpos, bytepos;
2026 struct glyph_row *row;
2027 enum face_id base_face_id;
2028 {
2029 int highlight_region_p;
2030
2031 /* Some precondition checks. */
2032 xassert (w != NULL && it != NULL);
2033 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2034 && charpos <= ZV));
2035
2036 /* If face attributes have been changed since the last redisplay,
2037 free realized faces now because they depend on face definitions
2038 that might have changed. Don't free faces while there might be
2039 desired matrices pending which reference these faces. */
2040 if (face_change_count && !inhibit_free_realized_faces)
2041 {
2042 face_change_count = 0;
2043 free_all_realized_faces (Qnil);
2044 }
2045
2046 /* Use one of the mode line rows of W's desired matrix if
2047 appropriate. */
2048 if (row == NULL)
2049 {
2050 if (base_face_id == MODE_LINE_FACE_ID
2051 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2052 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2053 else if (base_face_id == HEADER_LINE_FACE_ID)
2054 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2055 }
2056
2057 /* Clear IT. */
2058 bzero (it, sizeof *it);
2059 it->current.overlay_string_index = -1;
2060 it->current.dpvec_index = -1;
2061 it->base_face_id = base_face_id;
2062 it->string = Qnil;
2063 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2064
2065 /* The window in which we iterate over current_buffer: */
2066 XSETWINDOW (it->window, w);
2067 it->w = w;
2068 it->f = XFRAME (w->frame);
2069
2070 /* Extra space between lines (on window systems only). */
2071 if (base_face_id == DEFAULT_FACE_ID
2072 && FRAME_WINDOW_P (it->f))
2073 {
2074 if (NATNUMP (current_buffer->extra_line_spacing))
2075 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2076 else if (FLOATP (current_buffer->extra_line_spacing))
2077 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2078 * FRAME_LINE_HEIGHT (it->f));
2079 else if (it->f->extra_line_spacing > 0)
2080 it->extra_line_spacing = it->f->extra_line_spacing;
2081 }
2082
2083 /* If realized faces have been removed, e.g. because of face
2084 attribute changes of named faces, recompute them. When running
2085 in batch mode, the face cache of Vterminal_frame is null. If
2086 we happen to get called, make a dummy face cache. */
2087 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2088 init_frame_faces (it->f);
2089 if (FRAME_FACE_CACHE (it->f)->used == 0)
2090 recompute_basic_faces (it->f);
2091
2092 /* Current value of the `slice', `space-width', and 'height' properties. */
2093 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2094 it->space_width = Qnil;
2095 it->font_height = Qnil;
2096 it->override_ascent = -1;
2097
2098 /* Are control characters displayed as `^C'? */
2099 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2100
2101 /* -1 means everything between a CR and the following line end
2102 is invisible. >0 means lines indented more than this value are
2103 invisible. */
2104 it->selective = (INTEGERP (current_buffer->selective_display)
2105 ? XFASTINT (current_buffer->selective_display)
2106 : (!NILP (current_buffer->selective_display)
2107 ? -1 : 0));
2108 it->selective_display_ellipsis_p
2109 = !NILP (current_buffer->selective_display_ellipses);
2110
2111 /* Display table to use. */
2112 it->dp = window_display_table (w);
2113
2114 /* Are multibyte characters enabled in current_buffer? */
2115 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2116
2117 /* Non-zero if we should highlight the region. */
2118 highlight_region_p
2119 = (!NILP (Vtransient_mark_mode)
2120 && !NILP (current_buffer->mark_active)
2121 && XMARKER (current_buffer->mark)->buffer != 0);
2122
2123 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2124 start and end of a visible region in window IT->w. Set both to
2125 -1 to indicate no region. */
2126 if (highlight_region_p
2127 /* Maybe highlight only in selected window. */
2128 && (/* Either show region everywhere. */
2129 highlight_nonselected_windows
2130 /* Or show region in the selected window. */
2131 || w == XWINDOW (selected_window)
2132 /* Or show the region if we are in the mini-buffer and W is
2133 the window the mini-buffer refers to. */
2134 || (MINI_WINDOW_P (XWINDOW (selected_window))
2135 && WINDOWP (minibuf_selected_window)
2136 && w == XWINDOW (minibuf_selected_window))))
2137 {
2138 int charpos = marker_position (current_buffer->mark);
2139 it->region_beg_charpos = min (PT, charpos);
2140 it->region_end_charpos = max (PT, charpos);
2141 }
2142 else
2143 it->region_beg_charpos = it->region_end_charpos = -1;
2144
2145 /* Get the position at which the redisplay_end_trigger hook should
2146 be run, if it is to be run at all. */
2147 if (MARKERP (w->redisplay_end_trigger)
2148 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2149 it->redisplay_end_trigger_charpos
2150 = marker_position (w->redisplay_end_trigger);
2151 else if (INTEGERP (w->redisplay_end_trigger))
2152 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2153
2154 /* Correct bogus values of tab_width. */
2155 it->tab_width = XINT (current_buffer->tab_width);
2156 if (it->tab_width <= 0 || it->tab_width > 1000)
2157 it->tab_width = 8;
2158
2159 /* Are lines in the display truncated? */
2160 it->truncate_lines_p
2161 = (base_face_id != DEFAULT_FACE_ID
2162 || XINT (it->w->hscroll)
2163 || (truncate_partial_width_windows
2164 && !WINDOW_FULL_WIDTH_P (it->w))
2165 || !NILP (current_buffer->truncate_lines));
2166
2167 /* Get dimensions of truncation and continuation glyphs. These are
2168 displayed as fringe bitmaps under X, so we don't need them for such
2169 frames. */
2170 if (!FRAME_WINDOW_P (it->f))
2171 {
2172 if (it->truncate_lines_p)
2173 {
2174 /* We will need the truncation glyph. */
2175 xassert (it->glyph_row == NULL);
2176 produce_special_glyphs (it, IT_TRUNCATION);
2177 it->truncation_pixel_width = it->pixel_width;
2178 }
2179 else
2180 {
2181 /* We will need the continuation glyph. */
2182 xassert (it->glyph_row == NULL);
2183 produce_special_glyphs (it, IT_CONTINUATION);
2184 it->continuation_pixel_width = it->pixel_width;
2185 }
2186
2187 /* Reset these values to zero because the produce_special_glyphs
2188 above has changed them. */
2189 it->pixel_width = it->ascent = it->descent = 0;
2190 it->phys_ascent = it->phys_descent = 0;
2191 }
2192
2193 /* Set this after getting the dimensions of truncation and
2194 continuation glyphs, so that we don't produce glyphs when calling
2195 produce_special_glyphs, above. */
2196 it->glyph_row = row;
2197 it->area = TEXT_AREA;
2198
2199 /* Get the dimensions of the display area. The display area
2200 consists of the visible window area plus a horizontally scrolled
2201 part to the left of the window. All x-values are relative to the
2202 start of this total display area. */
2203 if (base_face_id != DEFAULT_FACE_ID)
2204 {
2205 /* Mode lines, menu bar in terminal frames. */
2206 it->first_visible_x = 0;
2207 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2208 }
2209 else
2210 {
2211 it->first_visible_x
2212 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2213 it->last_visible_x = (it->first_visible_x
2214 + window_box_width (w, TEXT_AREA));
2215
2216 /* If we truncate lines, leave room for the truncator glyph(s) at
2217 the right margin. Otherwise, leave room for the continuation
2218 glyph(s). Truncation and continuation glyphs are not inserted
2219 for window-based redisplay. */
2220 if (!FRAME_WINDOW_P (it->f))
2221 {
2222 if (it->truncate_lines_p)
2223 it->last_visible_x -= it->truncation_pixel_width;
2224 else
2225 it->last_visible_x -= it->continuation_pixel_width;
2226 }
2227
2228 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2229 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2230 }
2231
2232 /* Leave room for a border glyph. */
2233 if (!FRAME_WINDOW_P (it->f)
2234 && !WINDOW_RIGHTMOST_P (it->w))
2235 it->last_visible_x -= 1;
2236
2237 it->last_visible_y = window_text_bottom_y (w);
2238
2239 /* For mode lines and alike, arrange for the first glyph having a
2240 left box line if the face specifies a box. */
2241 if (base_face_id != DEFAULT_FACE_ID)
2242 {
2243 struct face *face;
2244
2245 it->face_id = base_face_id;
2246
2247 /* If we have a boxed mode line, make the first character appear
2248 with a left box line. */
2249 face = FACE_FROM_ID (it->f, base_face_id);
2250 if (face->box != FACE_NO_BOX)
2251 it->start_of_box_run_p = 1;
2252 }
2253
2254 /* If a buffer position was specified, set the iterator there,
2255 getting overlays and face properties from that position. */
2256 if (charpos >= BUF_BEG (current_buffer))
2257 {
2258 it->end_charpos = ZV;
2259 it->face_id = -1;
2260 IT_CHARPOS (*it) = charpos;
2261
2262 /* Compute byte position if not specified. */
2263 if (bytepos < charpos)
2264 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2265 else
2266 IT_BYTEPOS (*it) = bytepos;
2267
2268 it->start = it->current;
2269
2270 /* Compute faces etc. */
2271 reseat (it, it->current.pos, 1);
2272 }
2273
2274 CHECK_IT (it);
2275 }
2276
2277
2278 /* Initialize IT for the display of window W with window start POS. */
2279
2280 void
2281 start_display (it, w, pos)
2282 struct it *it;
2283 struct window *w;
2284 struct text_pos pos;
2285 {
2286 struct glyph_row *row;
2287 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2288
2289 row = w->desired_matrix->rows + first_vpos;
2290 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2291 it->first_vpos = first_vpos;
2292
2293 if (!it->truncate_lines_p)
2294 {
2295 int start_at_line_beg_p;
2296 int first_y = it->current_y;
2297
2298 /* If window start is not at a line start, skip forward to POS to
2299 get the correct continuation lines width. */
2300 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2301 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2302 if (!start_at_line_beg_p)
2303 {
2304 int new_x;
2305
2306 reseat_at_previous_visible_line_start (it);
2307 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2308
2309 new_x = it->current_x + it->pixel_width;
2310
2311 /* If lines are continued, this line may end in the middle
2312 of a multi-glyph character (e.g. a control character
2313 displayed as \003, or in the middle of an overlay
2314 string). In this case move_it_to above will not have
2315 taken us to the start of the continuation line but to the
2316 end of the continued line. */
2317 if (it->current_x > 0
2318 && !it->truncate_lines_p /* Lines are continued. */
2319 && (/* And glyph doesn't fit on the line. */
2320 new_x > it->last_visible_x
2321 /* Or it fits exactly and we're on a window
2322 system frame. */
2323 || (new_x == it->last_visible_x
2324 && FRAME_WINDOW_P (it->f))))
2325 {
2326 if (it->current.dpvec_index >= 0
2327 || it->current.overlay_string_index >= 0)
2328 {
2329 set_iterator_to_next (it, 1);
2330 move_it_in_display_line_to (it, -1, -1, 0);
2331 }
2332
2333 it->continuation_lines_width += it->current_x;
2334 }
2335
2336 /* We're starting a new display line, not affected by the
2337 height of the continued line, so clear the appropriate
2338 fields in the iterator structure. */
2339 it->max_ascent = it->max_descent = 0;
2340 it->max_phys_ascent = it->max_phys_descent = 0;
2341
2342 it->current_y = first_y;
2343 it->vpos = 0;
2344 it->current_x = it->hpos = 0;
2345 }
2346 }
2347
2348 #if 0 /* Don't assert the following because start_display is sometimes
2349 called intentionally with a window start that is not at a
2350 line start. Please leave this code in as a comment. */
2351
2352 /* Window start should be on a line start, now. */
2353 xassert (it->continuation_lines_width
2354 || IT_CHARPOS (it) == BEGV
2355 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2356 #endif /* 0 */
2357 }
2358
2359
2360 /* Return 1 if POS is a position in ellipses displayed for invisible
2361 text. W is the window we display, for text property lookup. */
2362
2363 static int
2364 in_ellipses_for_invisible_text_p (pos, w)
2365 struct display_pos *pos;
2366 struct window *w;
2367 {
2368 Lisp_Object prop, window;
2369 int ellipses_p = 0;
2370 int charpos = CHARPOS (pos->pos);
2371
2372 /* If POS specifies a position in a display vector, this might
2373 be for an ellipsis displayed for invisible text. We won't
2374 get the iterator set up for delivering that ellipsis unless
2375 we make sure that it gets aware of the invisible text. */
2376 if (pos->dpvec_index >= 0
2377 && pos->overlay_string_index < 0
2378 && CHARPOS (pos->string_pos) < 0
2379 && charpos > BEGV
2380 && (XSETWINDOW (window, w),
2381 prop = Fget_char_property (make_number (charpos),
2382 Qinvisible, window),
2383 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2384 {
2385 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2386 window);
2387 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2388 }
2389
2390 return ellipses_p;
2391 }
2392
2393
2394 /* Initialize IT for stepping through current_buffer in window W,
2395 starting at position POS that includes overlay string and display
2396 vector/ control character translation position information. Value
2397 is zero if there are overlay strings with newlines at POS. */
2398
2399 static int
2400 init_from_display_pos (it, w, pos)
2401 struct it *it;
2402 struct window *w;
2403 struct display_pos *pos;
2404 {
2405 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2406 int i, overlay_strings_with_newlines = 0;
2407
2408 /* If POS specifies a position in a display vector, this might
2409 be for an ellipsis displayed for invisible text. We won't
2410 get the iterator set up for delivering that ellipsis unless
2411 we make sure that it gets aware of the invisible text. */
2412 if (in_ellipses_for_invisible_text_p (pos, w))
2413 {
2414 --charpos;
2415 bytepos = 0;
2416 }
2417
2418 /* Keep in mind: the call to reseat in init_iterator skips invisible
2419 text, so we might end up at a position different from POS. This
2420 is only a problem when POS is a row start after a newline and an
2421 overlay starts there with an after-string, and the overlay has an
2422 invisible property. Since we don't skip invisible text in
2423 display_line and elsewhere immediately after consuming the
2424 newline before the row start, such a POS will not be in a string,
2425 but the call to init_iterator below will move us to the
2426 after-string. */
2427 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2428
2429 for (i = 0; i < it->n_overlay_strings; ++i)
2430 {
2431 const char *s = SDATA (it->overlay_strings[i]);
2432 const char *e = s + SBYTES (it->overlay_strings[i]);
2433
2434 while (s < e && *s != '\n')
2435 ++s;
2436
2437 if (s < e)
2438 {
2439 overlay_strings_with_newlines = 1;
2440 break;
2441 }
2442 }
2443
2444 /* If position is within an overlay string, set up IT to the right
2445 overlay string. */
2446 if (pos->overlay_string_index >= 0)
2447 {
2448 int relative_index;
2449
2450 /* If the first overlay string happens to have a `display'
2451 property for an image, the iterator will be set up for that
2452 image, and we have to undo that setup first before we can
2453 correct the overlay string index. */
2454 if (it->method == next_element_from_image)
2455 pop_it (it);
2456
2457 /* We already have the first chunk of overlay strings in
2458 IT->overlay_strings. Load more until the one for
2459 pos->overlay_string_index is in IT->overlay_strings. */
2460 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2461 {
2462 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2463 it->current.overlay_string_index = 0;
2464 while (n--)
2465 {
2466 load_overlay_strings (it, 0);
2467 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2468 }
2469 }
2470
2471 it->current.overlay_string_index = pos->overlay_string_index;
2472 relative_index = (it->current.overlay_string_index
2473 % OVERLAY_STRING_CHUNK_SIZE);
2474 it->string = it->overlay_strings[relative_index];
2475 xassert (STRINGP (it->string));
2476 it->current.string_pos = pos->string_pos;
2477 it->method = next_element_from_string;
2478 }
2479
2480 #if 0 /* This is bogus because POS not having an overlay string
2481 position does not mean it's after the string. Example: A
2482 line starting with a before-string and initialization of IT
2483 to the previous row's end position. */
2484 else if (it->current.overlay_string_index >= 0)
2485 {
2486 /* If POS says we're already after an overlay string ending at
2487 POS, make sure to pop the iterator because it will be in
2488 front of that overlay string. When POS is ZV, we've thereby
2489 also ``processed'' overlay strings at ZV. */
2490 while (it->sp)
2491 pop_it (it);
2492 it->current.overlay_string_index = -1;
2493 it->method = next_element_from_buffer;
2494 if (CHARPOS (pos->pos) == ZV)
2495 it->overlay_strings_at_end_processed_p = 1;
2496 }
2497 #endif /* 0 */
2498
2499 if (CHARPOS (pos->string_pos) >= 0)
2500 {
2501 /* Recorded position is not in an overlay string, but in another
2502 string. This can only be a string from a `display' property.
2503 IT should already be filled with that string. */
2504 it->current.string_pos = pos->string_pos;
2505 xassert (STRINGP (it->string));
2506 }
2507
2508 /* Restore position in display vector translations, control
2509 character translations or ellipses. */
2510 if (pos->dpvec_index >= 0)
2511 {
2512 if (it->dpvec == NULL)
2513 get_next_display_element (it);
2514 xassert (it->dpvec && it->current.dpvec_index == 0);
2515 it->current.dpvec_index = pos->dpvec_index;
2516 }
2517
2518 CHECK_IT (it);
2519 return !overlay_strings_with_newlines;
2520 }
2521
2522
2523 /* Initialize IT for stepping through current_buffer in window W
2524 starting at ROW->start. */
2525
2526 static void
2527 init_to_row_start (it, w, row)
2528 struct it *it;
2529 struct window *w;
2530 struct glyph_row *row;
2531 {
2532 init_from_display_pos (it, w, &row->start);
2533 it->start = row->start;
2534 it->continuation_lines_width = row->continuation_lines_width;
2535 CHECK_IT (it);
2536 }
2537
2538
2539 /* Initialize IT for stepping through current_buffer in window W
2540 starting in the line following ROW, i.e. starting at ROW->end.
2541 Value is zero if there are overlay strings with newlines at ROW's
2542 end position. */
2543
2544 static int
2545 init_to_row_end (it, w, row)
2546 struct it *it;
2547 struct window *w;
2548 struct glyph_row *row;
2549 {
2550 int success = 0;
2551
2552 if (init_from_display_pos (it, w, &row->end))
2553 {
2554 if (row->continued_p)
2555 it->continuation_lines_width
2556 = row->continuation_lines_width + row->pixel_width;
2557 CHECK_IT (it);
2558 success = 1;
2559 }
2560
2561 return success;
2562 }
2563
2564
2565
2566 \f
2567 /***********************************************************************
2568 Text properties
2569 ***********************************************************************/
2570
2571 /* Called when IT reaches IT->stop_charpos. Handle text property and
2572 overlay changes. Set IT->stop_charpos to the next position where
2573 to stop. */
2574
2575 static void
2576 handle_stop (it)
2577 struct it *it;
2578 {
2579 enum prop_handled handled;
2580 int handle_overlay_change_p = 1;
2581 struct props *p;
2582
2583 it->dpvec = NULL;
2584 it->current.dpvec_index = -1;
2585
2586 do
2587 {
2588 handled = HANDLED_NORMALLY;
2589
2590 /* Call text property handlers. */
2591 for (p = it_props; p->handler; ++p)
2592 {
2593 handled = p->handler (it);
2594
2595 if (handled == HANDLED_RECOMPUTE_PROPS)
2596 break;
2597 else if (handled == HANDLED_RETURN)
2598 return;
2599 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2600 handle_overlay_change_p = 0;
2601 }
2602
2603 if (handled != HANDLED_RECOMPUTE_PROPS)
2604 {
2605 /* Don't check for overlay strings below when set to deliver
2606 characters from a display vector. */
2607 if (it->method == next_element_from_display_vector)
2608 handle_overlay_change_p = 0;
2609
2610 /* Handle overlay changes. */
2611 if (handle_overlay_change_p)
2612 handled = handle_overlay_change (it);
2613
2614 /* Determine where to stop next. */
2615 if (handled == HANDLED_NORMALLY)
2616 compute_stop_pos (it);
2617 }
2618 }
2619 while (handled == HANDLED_RECOMPUTE_PROPS);
2620 }
2621
2622
2623 /* Compute IT->stop_charpos from text property and overlay change
2624 information for IT's current position. */
2625
2626 static void
2627 compute_stop_pos (it)
2628 struct it *it;
2629 {
2630 register INTERVAL iv, next_iv;
2631 Lisp_Object object, limit, position;
2632
2633 /* If nowhere else, stop at the end. */
2634 it->stop_charpos = it->end_charpos;
2635
2636 if (STRINGP (it->string))
2637 {
2638 /* Strings are usually short, so don't limit the search for
2639 properties. */
2640 object = it->string;
2641 limit = Qnil;
2642 position = make_number (IT_STRING_CHARPOS (*it));
2643 }
2644 else
2645 {
2646 int charpos;
2647
2648 /* If next overlay change is in front of the current stop pos
2649 (which is IT->end_charpos), stop there. Note: value of
2650 next_overlay_change is point-max if no overlay change
2651 follows. */
2652 charpos = next_overlay_change (IT_CHARPOS (*it));
2653 if (charpos < it->stop_charpos)
2654 it->stop_charpos = charpos;
2655
2656 /* If showing the region, we have to stop at the region
2657 start or end because the face might change there. */
2658 if (it->region_beg_charpos > 0)
2659 {
2660 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2661 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2662 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2663 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2664 }
2665
2666 /* Set up variables for computing the stop position from text
2667 property changes. */
2668 XSETBUFFER (object, current_buffer);
2669 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2670 position = make_number (IT_CHARPOS (*it));
2671
2672 }
2673
2674 /* Get the interval containing IT's position. Value is a null
2675 interval if there isn't such an interval. */
2676 iv = validate_interval_range (object, &position, &position, 0);
2677 if (!NULL_INTERVAL_P (iv))
2678 {
2679 Lisp_Object values_here[LAST_PROP_IDX];
2680 struct props *p;
2681
2682 /* Get properties here. */
2683 for (p = it_props; p->handler; ++p)
2684 values_here[p->idx] = textget (iv->plist, *p->name);
2685
2686 /* Look for an interval following iv that has different
2687 properties. */
2688 for (next_iv = next_interval (iv);
2689 (!NULL_INTERVAL_P (next_iv)
2690 && (NILP (limit)
2691 || XFASTINT (limit) > next_iv->position));
2692 next_iv = next_interval (next_iv))
2693 {
2694 for (p = it_props; p->handler; ++p)
2695 {
2696 Lisp_Object new_value;
2697
2698 new_value = textget (next_iv->plist, *p->name);
2699 if (!EQ (values_here[p->idx], new_value))
2700 break;
2701 }
2702
2703 if (p->handler)
2704 break;
2705 }
2706
2707 if (!NULL_INTERVAL_P (next_iv))
2708 {
2709 if (INTEGERP (limit)
2710 && next_iv->position >= XFASTINT (limit))
2711 /* No text property change up to limit. */
2712 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2713 else
2714 /* Text properties change in next_iv. */
2715 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2716 }
2717 }
2718
2719 xassert (STRINGP (it->string)
2720 || (it->stop_charpos >= BEGV
2721 && it->stop_charpos >= IT_CHARPOS (*it)));
2722 }
2723
2724
2725 /* Return the position of the next overlay change after POS in
2726 current_buffer. Value is point-max if no overlay change
2727 follows. This is like `next-overlay-change' but doesn't use
2728 xmalloc. */
2729
2730 static int
2731 next_overlay_change (pos)
2732 int pos;
2733 {
2734 int noverlays;
2735 int endpos;
2736 Lisp_Object *overlays;
2737 int i;
2738
2739 /* Get all overlays at the given position. */
2740 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2741
2742 /* If any of these overlays ends before endpos,
2743 use its ending point instead. */
2744 for (i = 0; i < noverlays; ++i)
2745 {
2746 Lisp_Object oend;
2747 int oendpos;
2748
2749 oend = OVERLAY_END (overlays[i]);
2750 oendpos = OVERLAY_POSITION (oend);
2751 endpos = min (endpos, oendpos);
2752 }
2753
2754 return endpos;
2755 }
2756
2757
2758 \f
2759 /***********************************************************************
2760 Fontification
2761 ***********************************************************************/
2762
2763 /* Handle changes in the `fontified' property of the current buffer by
2764 calling hook functions from Qfontification_functions to fontify
2765 regions of text. */
2766
2767 static enum prop_handled
2768 handle_fontified_prop (it)
2769 struct it *it;
2770 {
2771 Lisp_Object prop, pos;
2772 enum prop_handled handled = HANDLED_NORMALLY;
2773
2774 /* Get the value of the `fontified' property at IT's current buffer
2775 position. (The `fontified' property doesn't have a special
2776 meaning in strings.) If the value is nil, call functions from
2777 Qfontification_functions. */
2778 if (!STRINGP (it->string)
2779 && it->s == NULL
2780 && !NILP (Vfontification_functions)
2781 && !NILP (Vrun_hooks)
2782 && (pos = make_number (IT_CHARPOS (*it)),
2783 prop = Fget_char_property (pos, Qfontified, Qnil),
2784 NILP (prop)))
2785 {
2786 int count = SPECPDL_INDEX ();
2787 Lisp_Object val;
2788
2789 val = Vfontification_functions;
2790 specbind (Qfontification_functions, Qnil);
2791
2792 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2793 safe_call1 (val, pos);
2794 else
2795 {
2796 Lisp_Object globals, fn;
2797 struct gcpro gcpro1, gcpro2;
2798
2799 globals = Qnil;
2800 GCPRO2 (val, globals);
2801
2802 for (; CONSP (val); val = XCDR (val))
2803 {
2804 fn = XCAR (val);
2805
2806 if (EQ (fn, Qt))
2807 {
2808 /* A value of t indicates this hook has a local
2809 binding; it means to run the global binding too.
2810 In a global value, t should not occur. If it
2811 does, we must ignore it to avoid an endless
2812 loop. */
2813 for (globals = Fdefault_value (Qfontification_functions);
2814 CONSP (globals);
2815 globals = XCDR (globals))
2816 {
2817 fn = XCAR (globals);
2818 if (!EQ (fn, Qt))
2819 safe_call1 (fn, pos);
2820 }
2821 }
2822 else
2823 safe_call1 (fn, pos);
2824 }
2825
2826 UNGCPRO;
2827 }
2828
2829 unbind_to (count, Qnil);
2830
2831 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2832 something. This avoids an endless loop if they failed to
2833 fontify the text for which reason ever. */
2834 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2835 handled = HANDLED_RECOMPUTE_PROPS;
2836 }
2837
2838 return handled;
2839 }
2840
2841
2842 \f
2843 /***********************************************************************
2844 Faces
2845 ***********************************************************************/
2846
2847 /* Set up iterator IT from face properties at its current position.
2848 Called from handle_stop. */
2849
2850 static enum prop_handled
2851 handle_face_prop (it)
2852 struct it *it;
2853 {
2854 int new_face_id, next_stop;
2855
2856 if (!STRINGP (it->string))
2857 {
2858 new_face_id
2859 = face_at_buffer_position (it->w,
2860 IT_CHARPOS (*it),
2861 it->region_beg_charpos,
2862 it->region_end_charpos,
2863 &next_stop,
2864 (IT_CHARPOS (*it)
2865 + TEXT_PROP_DISTANCE_LIMIT),
2866 0);
2867
2868 /* Is this a start of a run of characters with box face?
2869 Caveat: this can be called for a freshly initialized
2870 iterator; face_id is -1 in this case. We know that the new
2871 face will not change until limit, i.e. if the new face has a
2872 box, all characters up to limit will have one. But, as
2873 usual, we don't know whether limit is really the end. */
2874 if (new_face_id != it->face_id)
2875 {
2876 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2877
2878 /* If new face has a box but old face has not, this is
2879 the start of a run of characters with box, i.e. it has
2880 a shadow on the left side. The value of face_id of the
2881 iterator will be -1 if this is the initial call that gets
2882 the face. In this case, we have to look in front of IT's
2883 position and see whether there is a face != new_face_id. */
2884 it->start_of_box_run_p
2885 = (new_face->box != FACE_NO_BOX
2886 && (it->face_id >= 0
2887 || IT_CHARPOS (*it) == BEG
2888 || new_face_id != face_before_it_pos (it)));
2889 it->face_box_p = new_face->box != FACE_NO_BOX;
2890 }
2891 }
2892 else
2893 {
2894 int base_face_id, bufpos;
2895
2896 if (it->current.overlay_string_index >= 0)
2897 bufpos = IT_CHARPOS (*it);
2898 else
2899 bufpos = 0;
2900
2901 /* For strings from a buffer, i.e. overlay strings or strings
2902 from a `display' property, use the face at IT's current
2903 buffer position as the base face to merge with, so that
2904 overlay strings appear in the same face as surrounding
2905 text, unless they specify their own faces. */
2906 base_face_id = underlying_face_id (it);
2907
2908 new_face_id = face_at_string_position (it->w,
2909 it->string,
2910 IT_STRING_CHARPOS (*it),
2911 bufpos,
2912 it->region_beg_charpos,
2913 it->region_end_charpos,
2914 &next_stop,
2915 base_face_id, 0);
2916
2917 #if 0 /* This shouldn't be neccessary. Let's check it. */
2918 /* If IT is used to display a mode line we would really like to
2919 use the mode line face instead of the frame's default face. */
2920 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2921 && new_face_id == DEFAULT_FACE_ID)
2922 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2923 #endif
2924
2925 /* Is this a start of a run of characters with box? Caveat:
2926 this can be called for a freshly allocated iterator; face_id
2927 is -1 is this case. We know that the new face will not
2928 change until the next check pos, i.e. if the new face has a
2929 box, all characters up to that position will have a
2930 box. But, as usual, we don't know whether that position
2931 is really the end. */
2932 if (new_face_id != it->face_id)
2933 {
2934 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2935 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2936
2937 /* If new face has a box but old face hasn't, this is the
2938 start of a run of characters with box, i.e. it has a
2939 shadow on the left side. */
2940 it->start_of_box_run_p
2941 = new_face->box && (old_face == NULL || !old_face->box);
2942 it->face_box_p = new_face->box != FACE_NO_BOX;
2943 }
2944 }
2945
2946 it->face_id = new_face_id;
2947 return HANDLED_NORMALLY;
2948 }
2949
2950
2951 /* Return the ID of the face ``underlying'' IT's current position,
2952 which is in a string. If the iterator is associated with a
2953 buffer, return the face at IT's current buffer position.
2954 Otherwise, use the iterator's base_face_id. */
2955
2956 static int
2957 underlying_face_id (it)
2958 struct it *it;
2959 {
2960 int face_id = it->base_face_id, i;
2961
2962 xassert (STRINGP (it->string));
2963
2964 for (i = it->sp - 1; i >= 0; --i)
2965 if (NILP (it->stack[i].string))
2966 face_id = it->stack[i].face_id;
2967
2968 return face_id;
2969 }
2970
2971
2972 /* Compute the face one character before or after the current position
2973 of IT. BEFORE_P non-zero means get the face in front of IT's
2974 position. Value is the id of the face. */
2975
2976 static int
2977 face_before_or_after_it_pos (it, before_p)
2978 struct it *it;
2979 int before_p;
2980 {
2981 int face_id, limit;
2982 int next_check_charpos;
2983 struct text_pos pos;
2984
2985 xassert (it->s == NULL);
2986
2987 if (STRINGP (it->string))
2988 {
2989 int bufpos, base_face_id;
2990
2991 /* No face change past the end of the string (for the case
2992 we are padding with spaces). No face change before the
2993 string start. */
2994 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2995 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2996 return it->face_id;
2997
2998 /* Set pos to the position before or after IT's current position. */
2999 if (before_p)
3000 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3001 else
3002 /* For composition, we must check the character after the
3003 composition. */
3004 pos = (it->what == IT_COMPOSITION
3005 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3006 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3007
3008 if (it->current.overlay_string_index >= 0)
3009 bufpos = IT_CHARPOS (*it);
3010 else
3011 bufpos = 0;
3012
3013 base_face_id = underlying_face_id (it);
3014
3015 /* Get the face for ASCII, or unibyte. */
3016 face_id = face_at_string_position (it->w,
3017 it->string,
3018 CHARPOS (pos),
3019 bufpos,
3020 it->region_beg_charpos,
3021 it->region_end_charpos,
3022 &next_check_charpos,
3023 base_face_id, 0);
3024
3025 /* Correct the face for charsets different from ASCII. Do it
3026 for the multibyte case only. The face returned above is
3027 suitable for unibyte text if IT->string is unibyte. */
3028 if (STRING_MULTIBYTE (it->string))
3029 {
3030 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3031 int rest = SBYTES (it->string) - BYTEPOS (pos);
3032 int c, len;
3033 struct face *face = FACE_FROM_ID (it->f, face_id);
3034
3035 c = string_char_and_length (p, rest, &len);
3036 face_id = FACE_FOR_CHAR (it->f, face, c);
3037 }
3038 }
3039 else
3040 {
3041 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3042 || (IT_CHARPOS (*it) <= BEGV && before_p))
3043 return it->face_id;
3044
3045 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3046 pos = it->current.pos;
3047
3048 if (before_p)
3049 DEC_TEXT_POS (pos, it->multibyte_p);
3050 else
3051 {
3052 if (it->what == IT_COMPOSITION)
3053 /* For composition, we must check the position after the
3054 composition. */
3055 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3056 else
3057 INC_TEXT_POS (pos, it->multibyte_p);
3058 }
3059
3060 /* Determine face for CHARSET_ASCII, or unibyte. */
3061 face_id = face_at_buffer_position (it->w,
3062 CHARPOS (pos),
3063 it->region_beg_charpos,
3064 it->region_end_charpos,
3065 &next_check_charpos,
3066 limit, 0);
3067
3068 /* Correct the face for charsets different from ASCII. Do it
3069 for the multibyte case only. The face returned above is
3070 suitable for unibyte text if current_buffer is unibyte. */
3071 if (it->multibyte_p)
3072 {
3073 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3074 struct face *face = FACE_FROM_ID (it->f, face_id);
3075 face_id = FACE_FOR_CHAR (it->f, face, c);
3076 }
3077 }
3078
3079 return face_id;
3080 }
3081
3082
3083 \f
3084 /***********************************************************************
3085 Invisible text
3086 ***********************************************************************/
3087
3088 /* Set up iterator IT from invisible properties at its current
3089 position. Called from handle_stop. */
3090
3091 static enum prop_handled
3092 handle_invisible_prop (it)
3093 struct it *it;
3094 {
3095 enum prop_handled handled = HANDLED_NORMALLY;
3096
3097 if (STRINGP (it->string))
3098 {
3099 extern Lisp_Object Qinvisible;
3100 Lisp_Object prop, end_charpos, limit, charpos;
3101
3102 /* Get the value of the invisible text property at the
3103 current position. Value will be nil if there is no such
3104 property. */
3105 charpos = make_number (IT_STRING_CHARPOS (*it));
3106 prop = Fget_text_property (charpos, Qinvisible, it->string);
3107
3108 if (!NILP (prop)
3109 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3110 {
3111 handled = HANDLED_RECOMPUTE_PROPS;
3112
3113 /* Get the position at which the next change of the
3114 invisible text property can be found in IT->string.
3115 Value will be nil if the property value is the same for
3116 all the rest of IT->string. */
3117 XSETINT (limit, SCHARS (it->string));
3118 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3119 it->string, limit);
3120
3121 /* Text at current position is invisible. The next
3122 change in the property is at position end_charpos.
3123 Move IT's current position to that position. */
3124 if (INTEGERP (end_charpos)
3125 && XFASTINT (end_charpos) < XFASTINT (limit))
3126 {
3127 struct text_pos old;
3128 old = it->current.string_pos;
3129 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3130 compute_string_pos (&it->current.string_pos, old, it->string);
3131 }
3132 else
3133 {
3134 /* The rest of the string is invisible. If this is an
3135 overlay string, proceed with the next overlay string
3136 or whatever comes and return a character from there. */
3137 if (it->current.overlay_string_index >= 0)
3138 {
3139 next_overlay_string (it);
3140 /* Don't check for overlay strings when we just
3141 finished processing them. */
3142 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3143 }
3144 else
3145 {
3146 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3147 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3148 }
3149 }
3150 }
3151 }
3152 else
3153 {
3154 int invis_p, newpos, next_stop, start_charpos;
3155 Lisp_Object pos, prop, overlay;
3156
3157 /* First of all, is there invisible text at this position? */
3158 start_charpos = IT_CHARPOS (*it);
3159 pos = make_number (IT_CHARPOS (*it));
3160 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3161 &overlay);
3162 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3163
3164 /* If we are on invisible text, skip over it. */
3165 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3166 {
3167 /* Record whether we have to display an ellipsis for the
3168 invisible text. */
3169 int display_ellipsis_p = invis_p == 2;
3170
3171 handled = HANDLED_RECOMPUTE_PROPS;
3172
3173 /* Loop skipping over invisible text. The loop is left at
3174 ZV or with IT on the first char being visible again. */
3175 do
3176 {
3177 /* Try to skip some invisible text. Return value is the
3178 position reached which can be equal to IT's position
3179 if there is nothing invisible here. This skips both
3180 over invisible text properties and overlays with
3181 invisible property. */
3182 newpos = skip_invisible (IT_CHARPOS (*it),
3183 &next_stop, ZV, it->window);
3184
3185 /* If we skipped nothing at all we weren't at invisible
3186 text in the first place. If everything to the end of
3187 the buffer was skipped, end the loop. */
3188 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3189 invis_p = 0;
3190 else
3191 {
3192 /* We skipped some characters but not necessarily
3193 all there are. Check if we ended up on visible
3194 text. Fget_char_property returns the property of
3195 the char before the given position, i.e. if we
3196 get invis_p = 0, this means that the char at
3197 newpos is visible. */
3198 pos = make_number (newpos);
3199 prop = Fget_char_property (pos, Qinvisible, it->window);
3200 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3201 }
3202
3203 /* If we ended up on invisible text, proceed to
3204 skip starting with next_stop. */
3205 if (invis_p)
3206 IT_CHARPOS (*it) = next_stop;
3207 }
3208 while (invis_p);
3209
3210 /* The position newpos is now either ZV or on visible text. */
3211 IT_CHARPOS (*it) = newpos;
3212 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3213
3214 /* If there are before-strings at the start of invisible
3215 text, and the text is invisible because of a text
3216 property, arrange to show before-strings because 20.x did
3217 it that way. (If the text is invisible because of an
3218 overlay property instead of a text property, this is
3219 already handled in the overlay code.) */
3220 if (NILP (overlay)
3221 && get_overlay_strings (it, start_charpos))
3222 {
3223 handled = HANDLED_RECOMPUTE_PROPS;
3224 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3225 }
3226 else if (display_ellipsis_p)
3227 setup_for_ellipsis (it);
3228 }
3229 }
3230
3231 return handled;
3232 }
3233
3234
3235 /* Make iterator IT return `...' next. */
3236
3237 static void
3238 setup_for_ellipsis (it)
3239 struct it *it;
3240 {
3241 if (it->dp
3242 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3243 {
3244 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3245 it->dpvec = v->contents;
3246 it->dpend = v->contents + v->size;
3247 }
3248 else
3249 {
3250 /* Default `...'. */
3251 it->dpvec = default_invis_vector;
3252 it->dpend = default_invis_vector + 3;
3253 }
3254
3255 /* The ellipsis display does not replace the display of the
3256 character at the new position. Indicate this by setting
3257 IT->dpvec_char_len to zero. */
3258 it->dpvec_char_len = 0;
3259
3260 it->current.dpvec_index = 0;
3261 it->method = next_element_from_display_vector;
3262 }
3263
3264
3265 \f
3266 /***********************************************************************
3267 'display' property
3268 ***********************************************************************/
3269
3270 /* Set up iterator IT from `display' property at its current position.
3271 Called from handle_stop. */
3272
3273 static enum prop_handled
3274 handle_display_prop (it)
3275 struct it *it;
3276 {
3277 Lisp_Object prop, object;
3278 struct text_pos *position;
3279 int display_replaced_p = 0;
3280
3281 if (STRINGP (it->string))
3282 {
3283 object = it->string;
3284 position = &it->current.string_pos;
3285 }
3286 else
3287 {
3288 object = it->w->buffer;
3289 position = &it->current.pos;
3290 }
3291
3292 /* Reset those iterator values set from display property values. */
3293 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3294 it->space_width = Qnil;
3295 it->font_height = Qnil;
3296 it->voffset = 0;
3297
3298 /* We don't support recursive `display' properties, i.e. string
3299 values that have a string `display' property, that have a string
3300 `display' property etc. */
3301 if (!it->string_from_display_prop_p)
3302 it->area = TEXT_AREA;
3303
3304 prop = Fget_char_property (make_number (position->charpos),
3305 Qdisplay, object);
3306 if (NILP (prop))
3307 return HANDLED_NORMALLY;
3308
3309 if (CONSP (prop)
3310 /* Simple properties. */
3311 && !EQ (XCAR (prop), Qimage)
3312 && !EQ (XCAR (prop), Qspace)
3313 && !EQ (XCAR (prop), Qwhen)
3314 && !EQ (XCAR (prop), Qslice)
3315 && !EQ (XCAR (prop), Qspace_width)
3316 && !EQ (XCAR (prop), Qheight)
3317 && !EQ (XCAR (prop), Qraise)
3318 /* Marginal area specifications. */
3319 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3320 && !EQ (XCAR (prop), Qleft_fringe)
3321 && !EQ (XCAR (prop), Qright_fringe)
3322 && !NILP (XCAR (prop)))
3323 {
3324 for (; CONSP (prop); prop = XCDR (prop))
3325 {
3326 if (handle_single_display_prop (it, XCAR (prop), object,
3327 position, display_replaced_p))
3328 display_replaced_p = 1;
3329 }
3330 }
3331 else if (VECTORP (prop))
3332 {
3333 int i;
3334 for (i = 0; i < ASIZE (prop); ++i)
3335 if (handle_single_display_prop (it, AREF (prop, i), object,
3336 position, display_replaced_p))
3337 display_replaced_p = 1;
3338 }
3339 else
3340 {
3341 if (handle_single_display_prop (it, prop, object, position, 0))
3342 display_replaced_p = 1;
3343 }
3344
3345 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3346 }
3347
3348
3349 /* Value is the position of the end of the `display' property starting
3350 at START_POS in OBJECT. */
3351
3352 static struct text_pos
3353 display_prop_end (it, object, start_pos)
3354 struct it *it;
3355 Lisp_Object object;
3356 struct text_pos start_pos;
3357 {
3358 Lisp_Object end;
3359 struct text_pos end_pos;
3360
3361 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3362 Qdisplay, object, Qnil);
3363 CHARPOS (end_pos) = XFASTINT (end);
3364 if (STRINGP (object))
3365 compute_string_pos (&end_pos, start_pos, it->string);
3366 else
3367 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3368
3369 return end_pos;
3370 }
3371
3372
3373 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3374 is the object in which the `display' property was found. *POSITION
3375 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3376 means that we previously saw a display sub-property which already
3377 replaced text display with something else, for example an image;
3378 ignore such properties after the first one has been processed.
3379
3380 If PROP is a `space' or `image' sub-property, set *POSITION to the
3381 end position of the `display' property.
3382
3383 Value is non-zero if something was found which replaces the display
3384 of buffer or string text. */
3385
3386 static int
3387 handle_single_display_prop (it, prop, object, position,
3388 display_replaced_before_p)
3389 struct it *it;
3390 Lisp_Object prop;
3391 Lisp_Object object;
3392 struct text_pos *position;
3393 int display_replaced_before_p;
3394 {
3395 Lisp_Object value;
3396 int replaces_text_display_p = 0;
3397 Lisp_Object form;
3398
3399 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3400 evaluated. If the result is nil, VALUE is ignored. */
3401 form = Qt;
3402 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3403 {
3404 prop = XCDR (prop);
3405 if (!CONSP (prop))
3406 return 0;
3407 form = XCAR (prop);
3408 prop = XCDR (prop);
3409 }
3410
3411 if (!NILP (form) && !EQ (form, Qt))
3412 {
3413 int count = SPECPDL_INDEX ();
3414 struct gcpro gcpro1;
3415
3416 /* Bind `object' to the object having the `display' property, a
3417 buffer or string. Bind `position' to the position in the
3418 object where the property was found, and `buffer-position'
3419 to the current position in the buffer. */
3420 specbind (Qobject, object);
3421 specbind (Qposition, make_number (CHARPOS (*position)));
3422 specbind (Qbuffer_position,
3423 make_number (STRINGP (object)
3424 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3425 GCPRO1 (form);
3426 form = safe_eval (form);
3427 UNGCPRO;
3428 unbind_to (count, Qnil);
3429 }
3430
3431 if (NILP (form))
3432 return 0;
3433
3434 if (CONSP (prop)
3435 && EQ (XCAR (prop), Qheight)
3436 && CONSP (XCDR (prop)))
3437 {
3438 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3439 return 0;
3440
3441 /* `(height HEIGHT)'. */
3442 it->font_height = XCAR (XCDR (prop));
3443 if (!NILP (it->font_height))
3444 {
3445 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3446 int new_height = -1;
3447
3448 if (CONSP (it->font_height)
3449 && (EQ (XCAR (it->font_height), Qplus)
3450 || EQ (XCAR (it->font_height), Qminus))
3451 && CONSP (XCDR (it->font_height))
3452 && INTEGERP (XCAR (XCDR (it->font_height))))
3453 {
3454 /* `(+ N)' or `(- N)' where N is an integer. */
3455 int steps = XINT (XCAR (XCDR (it->font_height)));
3456 if (EQ (XCAR (it->font_height), Qplus))
3457 steps = - steps;
3458 it->face_id = smaller_face (it->f, it->face_id, steps);
3459 }
3460 else if (FUNCTIONP (it->font_height))
3461 {
3462 /* Call function with current height as argument.
3463 Value is the new height. */
3464 Lisp_Object height;
3465 height = safe_call1 (it->font_height,
3466 face->lface[LFACE_HEIGHT_INDEX]);
3467 if (NUMBERP (height))
3468 new_height = XFLOATINT (height);
3469 }
3470 else if (NUMBERP (it->font_height))
3471 {
3472 /* Value is a multiple of the canonical char height. */
3473 struct face *face;
3474
3475 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3476 new_height = (XFLOATINT (it->font_height)
3477 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3478 }
3479 else
3480 {
3481 /* Evaluate IT->font_height with `height' bound to the
3482 current specified height to get the new height. */
3483 Lisp_Object value;
3484 int count = SPECPDL_INDEX ();
3485
3486 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3487 value = safe_eval (it->font_height);
3488 unbind_to (count, Qnil);
3489
3490 if (NUMBERP (value))
3491 new_height = XFLOATINT (value);
3492 }
3493
3494 if (new_height > 0)
3495 it->face_id = face_with_height (it->f, it->face_id, new_height);
3496 }
3497 }
3498 else if (CONSP (prop)
3499 && EQ (XCAR (prop), Qspace_width)
3500 && CONSP (XCDR (prop)))
3501 {
3502 /* `(space_width WIDTH)'. */
3503 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3504 return 0;
3505
3506 value = XCAR (XCDR (prop));
3507 if (NUMBERP (value) && XFLOATINT (value) > 0)
3508 it->space_width = value;
3509 }
3510 else if (CONSP (prop)
3511 && EQ (XCAR (prop), Qslice))
3512 {
3513 /* `(slice X Y WIDTH HEIGHT)'. */
3514 Lisp_Object tem;
3515
3516 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3517 return 0;
3518
3519 if (tem = XCDR (prop), CONSP (tem))
3520 {
3521 it->slice.x = XCAR (tem);
3522 if (tem = XCDR (tem), CONSP (tem))
3523 {
3524 it->slice.y = XCAR (tem);
3525 if (tem = XCDR (tem), CONSP (tem))
3526 {
3527 it->slice.width = XCAR (tem);
3528 if (tem = XCDR (tem), CONSP (tem))
3529 it->slice.height = XCAR (tem);
3530 }
3531 }
3532 }
3533 }
3534 else if (CONSP (prop)
3535 && EQ (XCAR (prop), Qraise)
3536 && CONSP (XCDR (prop)))
3537 {
3538 /* `(raise FACTOR)'. */
3539 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3540 return 0;
3541
3542 #ifdef HAVE_WINDOW_SYSTEM
3543 value = XCAR (XCDR (prop));
3544 if (NUMBERP (value))
3545 {
3546 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3547 it->voffset = - (XFLOATINT (value)
3548 * (FONT_HEIGHT (face->font)));
3549 }
3550 #endif /* HAVE_WINDOW_SYSTEM */
3551 }
3552 else if (!it->string_from_display_prop_p)
3553 {
3554 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3555 VALUE) or `((margin nil) VALUE)' or VALUE. */
3556 Lisp_Object location, value;
3557 struct text_pos start_pos;
3558 int valid_p;
3559
3560 /* Characters having this form of property are not displayed, so
3561 we have to find the end of the property. */
3562 start_pos = *position;
3563 *position = display_prop_end (it, object, start_pos);
3564 value = Qnil;
3565
3566 /* Let's stop at the new position and assume that all
3567 text properties change there. */
3568 it->stop_charpos = position->charpos;
3569
3570 if (CONSP (prop)
3571 && (EQ (XCAR (prop), Qleft_fringe)
3572 || EQ (XCAR (prop), Qright_fringe))
3573 && CONSP (XCDR (prop)))
3574 {
3575 unsigned face_id = DEFAULT_FACE_ID;
3576
3577 /* Save current settings of IT so that we can restore them
3578 when we are finished with the glyph property value. */
3579
3580 /* `(left-fringe BITMAP FACE)'. */
3581 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3582 return 0;
3583
3584 #ifdef HAVE_WINDOW_SYSTEM
3585 value = XCAR (XCDR (prop));
3586 if (!NUMBERP (value)
3587 || !valid_fringe_bitmap_id_p (XINT (value)))
3588 return 0;
3589
3590 if (CONSP (XCDR (XCDR (prop))))
3591 {
3592 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3593
3594 face_id = lookup_named_face (it->f, face_name, 'A');
3595 if (face_id < 0)
3596 return 0;
3597 }
3598
3599 push_it (it);
3600
3601 it->area = TEXT_AREA;
3602 it->what = IT_IMAGE;
3603 it->image_id = -1; /* no image */
3604 it->position = start_pos;
3605 it->object = NILP (object) ? it->w->buffer : object;
3606 it->method = next_element_from_image;
3607 it->face_id = face_id;
3608
3609 /* Say that we haven't consumed the characters with
3610 `display' property yet. The call to pop_it in
3611 set_iterator_to_next will clean this up. */
3612 *position = start_pos;
3613
3614 if (EQ (XCAR (prop), Qleft_fringe))
3615 {
3616 it->left_user_fringe_bitmap = XINT (value);
3617 it->left_user_fringe_face_id = face_id;
3618 }
3619 else
3620 {
3621 it->right_user_fringe_bitmap = XINT (value);
3622 it->right_user_fringe_face_id = face_id;
3623 }
3624 #endif /* HAVE_WINDOW_SYSTEM */
3625 return 1;
3626 }
3627
3628 location = Qunbound;
3629 if (CONSP (prop) && CONSP (XCAR (prop)))
3630 {
3631 Lisp_Object tem;
3632
3633 value = XCDR (prop);
3634 if (CONSP (value))
3635 value = XCAR (value);
3636
3637 tem = XCAR (prop);
3638 if (EQ (XCAR (tem), Qmargin)
3639 && (tem = XCDR (tem),
3640 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3641 (NILP (tem)
3642 || EQ (tem, Qleft_margin)
3643 || EQ (tem, Qright_margin))))
3644 location = tem;
3645 }
3646
3647 if (EQ (location, Qunbound))
3648 {
3649 location = Qnil;
3650 value = prop;
3651 }
3652
3653 valid_p = (STRINGP (value)
3654 #ifdef HAVE_WINDOW_SYSTEM
3655 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3656 #endif /* not HAVE_WINDOW_SYSTEM */
3657 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3658
3659 if ((EQ (location, Qleft_margin)
3660 || EQ (location, Qright_margin)
3661 || NILP (location))
3662 && valid_p
3663 && !display_replaced_before_p)
3664 {
3665 replaces_text_display_p = 1;
3666
3667 /* Save current settings of IT so that we can restore them
3668 when we are finished with the glyph property value. */
3669 push_it (it);
3670
3671 if (NILP (location))
3672 it->area = TEXT_AREA;
3673 else if (EQ (location, Qleft_margin))
3674 it->area = LEFT_MARGIN_AREA;
3675 else
3676 it->area = RIGHT_MARGIN_AREA;
3677
3678 if (STRINGP (value))
3679 {
3680 it->string = value;
3681 it->multibyte_p = STRING_MULTIBYTE (it->string);
3682 it->current.overlay_string_index = -1;
3683 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3684 it->end_charpos = it->string_nchars = SCHARS (it->string);
3685 it->method = next_element_from_string;
3686 it->stop_charpos = 0;
3687 it->string_from_display_prop_p = 1;
3688 /* Say that we haven't consumed the characters with
3689 `display' property yet. The call to pop_it in
3690 set_iterator_to_next will clean this up. */
3691 *position = start_pos;
3692 }
3693 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3694 {
3695 it->method = next_element_from_stretch;
3696 it->object = value;
3697 it->current.pos = it->position = start_pos;
3698 }
3699 #ifdef HAVE_WINDOW_SYSTEM
3700 else
3701 {
3702 it->what = IT_IMAGE;
3703 it->image_id = lookup_image (it->f, value);
3704 it->position = start_pos;
3705 it->object = NILP (object) ? it->w->buffer : object;
3706 it->method = next_element_from_image;
3707
3708 /* Say that we haven't consumed the characters with
3709 `display' property yet. The call to pop_it in
3710 set_iterator_to_next will clean this up. */
3711 *position = start_pos;
3712 }
3713 #endif /* HAVE_WINDOW_SYSTEM */
3714 }
3715 else
3716 /* Invalid property or property not supported. Restore
3717 the position to what it was before. */
3718 *position = start_pos;
3719 }
3720
3721 return replaces_text_display_p;
3722 }
3723
3724
3725 /* Check if PROP is a display sub-property value whose text should be
3726 treated as intangible. */
3727
3728 static int
3729 single_display_prop_intangible_p (prop)
3730 Lisp_Object prop;
3731 {
3732 /* Skip over `when FORM'. */
3733 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3734 {
3735 prop = XCDR (prop);
3736 if (!CONSP (prop))
3737 return 0;
3738 prop = XCDR (prop);
3739 }
3740
3741 if (STRINGP (prop))
3742 return 1;
3743
3744 if (!CONSP (prop))
3745 return 0;
3746
3747 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3748 we don't need to treat text as intangible. */
3749 if (EQ (XCAR (prop), Qmargin))
3750 {
3751 prop = XCDR (prop);
3752 if (!CONSP (prop))
3753 return 0;
3754
3755 prop = XCDR (prop);
3756 if (!CONSP (prop)
3757 || EQ (XCAR (prop), Qleft_margin)
3758 || EQ (XCAR (prop), Qright_margin))
3759 return 0;
3760 }
3761
3762 return (CONSP (prop)
3763 && (EQ (XCAR (prop), Qimage)
3764 || EQ (XCAR (prop), Qspace)));
3765 }
3766
3767
3768 /* Check if PROP is a display property value whose text should be
3769 treated as intangible. */
3770
3771 int
3772 display_prop_intangible_p (prop)
3773 Lisp_Object prop;
3774 {
3775 if (CONSP (prop)
3776 && CONSP (XCAR (prop))
3777 && !EQ (Qmargin, XCAR (XCAR (prop))))
3778 {
3779 /* A list of sub-properties. */
3780 while (CONSP (prop))
3781 {
3782 if (single_display_prop_intangible_p (XCAR (prop)))
3783 return 1;
3784 prop = XCDR (prop);
3785 }
3786 }
3787 else if (VECTORP (prop))
3788 {
3789 /* A vector of sub-properties. */
3790 int i;
3791 for (i = 0; i < ASIZE (prop); ++i)
3792 if (single_display_prop_intangible_p (AREF (prop, i)))
3793 return 1;
3794 }
3795 else
3796 return single_display_prop_intangible_p (prop);
3797
3798 return 0;
3799 }
3800
3801
3802 /* Return 1 if PROP is a display sub-property value containing STRING. */
3803
3804 static int
3805 single_display_prop_string_p (prop, string)
3806 Lisp_Object prop, string;
3807 {
3808 if (EQ (string, prop))
3809 return 1;
3810
3811 /* Skip over `when FORM'. */
3812 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3813 {
3814 prop = XCDR (prop);
3815 if (!CONSP (prop))
3816 return 0;
3817 prop = XCDR (prop);
3818 }
3819
3820 if (CONSP (prop))
3821 /* Skip over `margin LOCATION'. */
3822 if (EQ (XCAR (prop), Qmargin))
3823 {
3824 prop = XCDR (prop);
3825 if (!CONSP (prop))
3826 return 0;
3827
3828 prop = XCDR (prop);
3829 if (!CONSP (prop))
3830 return 0;
3831 }
3832
3833 return CONSP (prop) && EQ (XCAR (prop), string);
3834 }
3835
3836
3837 /* Return 1 if STRING appears in the `display' property PROP. */
3838
3839 static int
3840 display_prop_string_p (prop, string)
3841 Lisp_Object prop, string;
3842 {
3843 if (CONSP (prop)
3844 && CONSP (XCAR (prop))
3845 && !EQ (Qmargin, XCAR (XCAR (prop))))
3846 {
3847 /* A list of sub-properties. */
3848 while (CONSP (prop))
3849 {
3850 if (single_display_prop_string_p (XCAR (prop), string))
3851 return 1;
3852 prop = XCDR (prop);
3853 }
3854 }
3855 else if (VECTORP (prop))
3856 {
3857 /* A vector of sub-properties. */
3858 int i;
3859 for (i = 0; i < ASIZE (prop); ++i)
3860 if (single_display_prop_string_p (AREF (prop, i), string))
3861 return 1;
3862 }
3863 else
3864 return single_display_prop_string_p (prop, string);
3865
3866 return 0;
3867 }
3868
3869
3870 /* Determine from which buffer position in W's buffer STRING comes
3871 from. AROUND_CHARPOS is an approximate position where it could
3872 be from. Value is the buffer position or 0 if it couldn't be
3873 determined.
3874
3875 W's buffer must be current.
3876
3877 This function is necessary because we don't record buffer positions
3878 in glyphs generated from strings (to keep struct glyph small).
3879 This function may only use code that doesn't eval because it is
3880 called asynchronously from note_mouse_highlight. */
3881
3882 int
3883 string_buffer_position (w, string, around_charpos)
3884 struct window *w;
3885 Lisp_Object string;
3886 int around_charpos;
3887 {
3888 Lisp_Object limit, prop, pos;
3889 const int MAX_DISTANCE = 1000;
3890 int found = 0;
3891
3892 pos = make_number (around_charpos);
3893 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3894 while (!found && !EQ (pos, limit))
3895 {
3896 prop = Fget_char_property (pos, Qdisplay, Qnil);
3897 if (!NILP (prop) && display_prop_string_p (prop, string))
3898 found = 1;
3899 else
3900 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3901 }
3902
3903 if (!found)
3904 {
3905 pos = make_number (around_charpos);
3906 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3907 while (!found && !EQ (pos, limit))
3908 {
3909 prop = Fget_char_property (pos, Qdisplay, Qnil);
3910 if (!NILP (prop) && display_prop_string_p (prop, string))
3911 found = 1;
3912 else
3913 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3914 limit);
3915 }
3916 }
3917
3918 return found ? XINT (pos) : 0;
3919 }
3920
3921
3922 \f
3923 /***********************************************************************
3924 `composition' property
3925 ***********************************************************************/
3926
3927 /* Set up iterator IT from `composition' property at its current
3928 position. Called from handle_stop. */
3929
3930 static enum prop_handled
3931 handle_composition_prop (it)
3932 struct it *it;
3933 {
3934 Lisp_Object prop, string;
3935 int pos, pos_byte, end;
3936 enum prop_handled handled = HANDLED_NORMALLY;
3937
3938 if (STRINGP (it->string))
3939 {
3940 pos = IT_STRING_CHARPOS (*it);
3941 pos_byte = IT_STRING_BYTEPOS (*it);
3942 string = it->string;
3943 }
3944 else
3945 {
3946 pos = IT_CHARPOS (*it);
3947 pos_byte = IT_BYTEPOS (*it);
3948 string = Qnil;
3949 }
3950
3951 /* If there's a valid composition and point is not inside of the
3952 composition (in the case that the composition is from the current
3953 buffer), draw a glyph composed from the composition components. */
3954 if (find_composition (pos, -1, &pos, &end, &prop, string)
3955 && COMPOSITION_VALID_P (pos, end, prop)
3956 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3957 {
3958 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3959
3960 if (id >= 0)
3961 {
3962 it->method = next_element_from_composition;
3963 it->cmp_id = id;
3964 it->cmp_len = COMPOSITION_LENGTH (prop);
3965 /* For a terminal, draw only the first character of the
3966 components. */
3967 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3968 it->len = (STRINGP (it->string)
3969 ? string_char_to_byte (it->string, end)
3970 : CHAR_TO_BYTE (end)) - pos_byte;
3971 it->stop_charpos = end;
3972 handled = HANDLED_RETURN;
3973 }
3974 }
3975
3976 return handled;
3977 }
3978
3979
3980 \f
3981 /***********************************************************************
3982 Overlay strings
3983 ***********************************************************************/
3984
3985 /* The following structure is used to record overlay strings for
3986 later sorting in load_overlay_strings. */
3987
3988 struct overlay_entry
3989 {
3990 Lisp_Object overlay;
3991 Lisp_Object string;
3992 int priority;
3993 int after_string_p;
3994 };
3995
3996
3997 /* Set up iterator IT from overlay strings at its current position.
3998 Called from handle_stop. */
3999
4000 static enum prop_handled
4001 handle_overlay_change (it)
4002 struct it *it;
4003 {
4004 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4005 return HANDLED_RECOMPUTE_PROPS;
4006 else
4007 return HANDLED_NORMALLY;
4008 }
4009
4010
4011 /* Set up the next overlay string for delivery by IT, if there is an
4012 overlay string to deliver. Called by set_iterator_to_next when the
4013 end of the current overlay string is reached. If there are more
4014 overlay strings to display, IT->string and
4015 IT->current.overlay_string_index are set appropriately here.
4016 Otherwise IT->string is set to nil. */
4017
4018 static void
4019 next_overlay_string (it)
4020 struct it *it;
4021 {
4022 ++it->current.overlay_string_index;
4023 if (it->current.overlay_string_index == it->n_overlay_strings)
4024 {
4025 /* No more overlay strings. Restore IT's settings to what
4026 they were before overlay strings were processed, and
4027 continue to deliver from current_buffer. */
4028 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4029
4030 pop_it (it);
4031 xassert (it->stop_charpos >= BEGV
4032 && it->stop_charpos <= it->end_charpos);
4033 it->string = Qnil;
4034 it->current.overlay_string_index = -1;
4035 SET_TEXT_POS (it->current.string_pos, -1, -1);
4036 it->n_overlay_strings = 0;
4037 it->method = next_element_from_buffer;
4038
4039 /* If we're at the end of the buffer, record that we have
4040 processed the overlay strings there already, so that
4041 next_element_from_buffer doesn't try it again. */
4042 if (IT_CHARPOS (*it) >= it->end_charpos)
4043 it->overlay_strings_at_end_processed_p = 1;
4044
4045 /* If we have to display `...' for invisible text, set
4046 the iterator up for that. */
4047 if (display_ellipsis_p)
4048 setup_for_ellipsis (it);
4049 }
4050 else
4051 {
4052 /* There are more overlay strings to process. If
4053 IT->current.overlay_string_index has advanced to a position
4054 where we must load IT->overlay_strings with more strings, do
4055 it. */
4056 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4057
4058 if (it->current.overlay_string_index && i == 0)
4059 load_overlay_strings (it, 0);
4060
4061 /* Initialize IT to deliver display elements from the overlay
4062 string. */
4063 it->string = it->overlay_strings[i];
4064 it->multibyte_p = STRING_MULTIBYTE (it->string);
4065 SET_TEXT_POS (it->current.string_pos, 0, 0);
4066 it->method = next_element_from_string;
4067 it->stop_charpos = 0;
4068 }
4069
4070 CHECK_IT (it);
4071 }
4072
4073
4074 /* Compare two overlay_entry structures E1 and E2. Used as a
4075 comparison function for qsort in load_overlay_strings. Overlay
4076 strings for the same position are sorted so that
4077
4078 1. All after-strings come in front of before-strings, except
4079 when they come from the same overlay.
4080
4081 2. Within after-strings, strings are sorted so that overlay strings
4082 from overlays with higher priorities come first.
4083
4084 2. Within before-strings, strings are sorted so that overlay
4085 strings from overlays with higher priorities come last.
4086
4087 Value is analogous to strcmp. */
4088
4089
4090 static int
4091 compare_overlay_entries (e1, e2)
4092 void *e1, *e2;
4093 {
4094 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4095 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4096 int result;
4097
4098 if (entry1->after_string_p != entry2->after_string_p)
4099 {
4100 /* Let after-strings appear in front of before-strings if
4101 they come from different overlays. */
4102 if (EQ (entry1->overlay, entry2->overlay))
4103 result = entry1->after_string_p ? 1 : -1;
4104 else
4105 result = entry1->after_string_p ? -1 : 1;
4106 }
4107 else if (entry1->after_string_p)
4108 /* After-strings sorted in order of decreasing priority. */
4109 result = entry2->priority - entry1->priority;
4110 else
4111 /* Before-strings sorted in order of increasing priority. */
4112 result = entry1->priority - entry2->priority;
4113
4114 return result;
4115 }
4116
4117
4118 /* Load the vector IT->overlay_strings with overlay strings from IT's
4119 current buffer position, or from CHARPOS if that is > 0. Set
4120 IT->n_overlays to the total number of overlay strings found.
4121
4122 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4123 a time. On entry into load_overlay_strings,
4124 IT->current.overlay_string_index gives the number of overlay
4125 strings that have already been loaded by previous calls to this
4126 function.
4127
4128 IT->add_overlay_start contains an additional overlay start
4129 position to consider for taking overlay strings from, if non-zero.
4130 This position comes into play when the overlay has an `invisible'
4131 property, and both before and after-strings. When we've skipped to
4132 the end of the overlay, because of its `invisible' property, we
4133 nevertheless want its before-string to appear.
4134 IT->add_overlay_start will contain the overlay start position
4135 in this case.
4136
4137 Overlay strings are sorted so that after-string strings come in
4138 front of before-string strings. Within before and after-strings,
4139 strings are sorted by overlay priority. See also function
4140 compare_overlay_entries. */
4141
4142 static void
4143 load_overlay_strings (it, charpos)
4144 struct it *it;
4145 int charpos;
4146 {
4147 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4148 Lisp_Object overlay, window, str, invisible;
4149 struct Lisp_Overlay *ov;
4150 int start, end;
4151 int size = 20;
4152 int n = 0, i, j, invis_p;
4153 struct overlay_entry *entries
4154 = (struct overlay_entry *) alloca (size * sizeof *entries);
4155
4156 if (charpos <= 0)
4157 charpos = IT_CHARPOS (*it);
4158
4159 /* Append the overlay string STRING of overlay OVERLAY to vector
4160 `entries' which has size `size' and currently contains `n'
4161 elements. AFTER_P non-zero means STRING is an after-string of
4162 OVERLAY. */
4163 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4164 do \
4165 { \
4166 Lisp_Object priority; \
4167 \
4168 if (n == size) \
4169 { \
4170 int new_size = 2 * size; \
4171 struct overlay_entry *old = entries; \
4172 entries = \
4173 (struct overlay_entry *) alloca (new_size \
4174 * sizeof *entries); \
4175 bcopy (old, entries, size * sizeof *entries); \
4176 size = new_size; \
4177 } \
4178 \
4179 entries[n].string = (STRING); \
4180 entries[n].overlay = (OVERLAY); \
4181 priority = Foverlay_get ((OVERLAY), Qpriority); \
4182 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4183 entries[n].after_string_p = (AFTER_P); \
4184 ++n; \
4185 } \
4186 while (0)
4187
4188 /* Process overlay before the overlay center. */
4189 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4190 {
4191 XSETMISC (overlay, ov);
4192 xassert (OVERLAYP (overlay));
4193 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4194 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4195
4196 if (end < charpos)
4197 break;
4198
4199 /* Skip this overlay if it doesn't start or end at IT's current
4200 position. */
4201 if (end != charpos && start != charpos)
4202 continue;
4203
4204 /* Skip this overlay if it doesn't apply to IT->w. */
4205 window = Foverlay_get (overlay, Qwindow);
4206 if (WINDOWP (window) && XWINDOW (window) != it->w)
4207 continue;
4208
4209 /* If the text ``under'' the overlay is invisible, both before-
4210 and after-strings from this overlay are visible; start and
4211 end position are indistinguishable. */
4212 invisible = Foverlay_get (overlay, Qinvisible);
4213 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4214
4215 /* If overlay has a non-empty before-string, record it. */
4216 if ((start == charpos || (end == charpos && invis_p))
4217 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4218 && SCHARS (str))
4219 RECORD_OVERLAY_STRING (overlay, str, 0);
4220
4221 /* If overlay has a non-empty after-string, record it. */
4222 if ((end == charpos || (start == charpos && invis_p))
4223 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4224 && SCHARS (str))
4225 RECORD_OVERLAY_STRING (overlay, str, 1);
4226 }
4227
4228 /* Process overlays after the overlay center. */
4229 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4230 {
4231 XSETMISC (overlay, ov);
4232 xassert (OVERLAYP (overlay));
4233 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4234 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4235
4236 if (start > charpos)
4237 break;
4238
4239 /* Skip this overlay if it doesn't start or end at IT's current
4240 position. */
4241 if (end != charpos && start != charpos)
4242 continue;
4243
4244 /* Skip this overlay if it doesn't apply to IT->w. */
4245 window = Foverlay_get (overlay, Qwindow);
4246 if (WINDOWP (window) && XWINDOW (window) != it->w)
4247 continue;
4248
4249 /* If the text ``under'' the overlay is invisible, it has a zero
4250 dimension, and both before- and after-strings apply. */
4251 invisible = Foverlay_get (overlay, Qinvisible);
4252 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4253
4254 /* If overlay has a non-empty before-string, record it. */
4255 if ((start == charpos || (end == charpos && invis_p))
4256 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4257 && SCHARS (str))
4258 RECORD_OVERLAY_STRING (overlay, str, 0);
4259
4260 /* If overlay has a non-empty after-string, record it. */
4261 if ((end == charpos || (start == charpos && invis_p))
4262 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4263 && SCHARS (str))
4264 RECORD_OVERLAY_STRING (overlay, str, 1);
4265 }
4266
4267 #undef RECORD_OVERLAY_STRING
4268
4269 /* Sort entries. */
4270 if (n > 1)
4271 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4272
4273 /* Record the total number of strings to process. */
4274 it->n_overlay_strings = n;
4275
4276 /* IT->current.overlay_string_index is the number of overlay strings
4277 that have already been consumed by IT. Copy some of the
4278 remaining overlay strings to IT->overlay_strings. */
4279 i = 0;
4280 j = it->current.overlay_string_index;
4281 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4282 it->overlay_strings[i++] = entries[j++].string;
4283
4284 CHECK_IT (it);
4285 }
4286
4287
4288 /* Get the first chunk of overlay strings at IT's current buffer
4289 position, or at CHARPOS if that is > 0. Value is non-zero if at
4290 least one overlay string was found. */
4291
4292 static int
4293 get_overlay_strings (it, charpos)
4294 struct it *it;
4295 int charpos;
4296 {
4297 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4298 process. This fills IT->overlay_strings with strings, and sets
4299 IT->n_overlay_strings to the total number of strings to process.
4300 IT->pos.overlay_string_index has to be set temporarily to zero
4301 because load_overlay_strings needs this; it must be set to -1
4302 when no overlay strings are found because a zero value would
4303 indicate a position in the first overlay string. */
4304 it->current.overlay_string_index = 0;
4305 load_overlay_strings (it, charpos);
4306
4307 /* If we found overlay strings, set up IT to deliver display
4308 elements from the first one. Otherwise set up IT to deliver
4309 from current_buffer. */
4310 if (it->n_overlay_strings)
4311 {
4312 /* Make sure we know settings in current_buffer, so that we can
4313 restore meaningful values when we're done with the overlay
4314 strings. */
4315 compute_stop_pos (it);
4316 xassert (it->face_id >= 0);
4317
4318 /* Save IT's settings. They are restored after all overlay
4319 strings have been processed. */
4320 xassert (it->sp == 0);
4321 push_it (it);
4322
4323 /* Set up IT to deliver display elements from the first overlay
4324 string. */
4325 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4326 it->string = it->overlay_strings[0];
4327 it->stop_charpos = 0;
4328 xassert (STRINGP (it->string));
4329 it->end_charpos = SCHARS (it->string);
4330 it->multibyte_p = STRING_MULTIBYTE (it->string);
4331 it->method = next_element_from_string;
4332 }
4333 else
4334 {
4335 it->string = Qnil;
4336 it->current.overlay_string_index = -1;
4337 it->method = next_element_from_buffer;
4338 }
4339
4340 CHECK_IT (it);
4341
4342 /* Value is non-zero if we found at least one overlay string. */
4343 return STRINGP (it->string);
4344 }
4345
4346
4347 \f
4348 /***********************************************************************
4349 Saving and restoring state
4350 ***********************************************************************/
4351
4352 /* Save current settings of IT on IT->stack. Called, for example,
4353 before setting up IT for an overlay string, to be able to restore
4354 IT's settings to what they were after the overlay string has been
4355 processed. */
4356
4357 static void
4358 push_it (it)
4359 struct it *it;
4360 {
4361 struct iterator_stack_entry *p;
4362
4363 xassert (it->sp < 2);
4364 p = it->stack + it->sp;
4365
4366 p->stop_charpos = it->stop_charpos;
4367 xassert (it->face_id >= 0);
4368 p->face_id = it->face_id;
4369 p->string = it->string;
4370 p->pos = it->current;
4371 p->end_charpos = it->end_charpos;
4372 p->string_nchars = it->string_nchars;
4373 p->area = it->area;
4374 p->multibyte_p = it->multibyte_p;
4375 p->slice = it->slice;
4376 p->space_width = it->space_width;
4377 p->font_height = it->font_height;
4378 p->voffset = it->voffset;
4379 p->string_from_display_prop_p = it->string_from_display_prop_p;
4380 p->display_ellipsis_p = 0;
4381 ++it->sp;
4382 }
4383
4384
4385 /* Restore IT's settings from IT->stack. Called, for example, when no
4386 more overlay strings must be processed, and we return to delivering
4387 display elements from a buffer, or when the end of a string from a
4388 `display' property is reached and we return to delivering display
4389 elements from an overlay string, or from a buffer. */
4390
4391 static void
4392 pop_it (it)
4393 struct it *it;
4394 {
4395 struct iterator_stack_entry *p;
4396
4397 xassert (it->sp > 0);
4398 --it->sp;
4399 p = it->stack + it->sp;
4400 it->stop_charpos = p->stop_charpos;
4401 it->face_id = p->face_id;
4402 it->string = p->string;
4403 it->current = p->pos;
4404 it->end_charpos = p->end_charpos;
4405 it->string_nchars = p->string_nchars;
4406 it->area = p->area;
4407 it->multibyte_p = p->multibyte_p;
4408 it->slice = p->slice;
4409 it->space_width = p->space_width;
4410 it->font_height = p->font_height;
4411 it->voffset = p->voffset;
4412 it->string_from_display_prop_p = p->string_from_display_prop_p;
4413 }
4414
4415
4416 \f
4417 /***********************************************************************
4418 Moving over lines
4419 ***********************************************************************/
4420
4421 /* Set IT's current position to the previous line start. */
4422
4423 static void
4424 back_to_previous_line_start (it)
4425 struct it *it;
4426 {
4427 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4428 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4429 }
4430
4431
4432 /* Move IT to the next line start.
4433
4434 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4435 we skipped over part of the text (as opposed to moving the iterator
4436 continuously over the text). Otherwise, don't change the value
4437 of *SKIPPED_P.
4438
4439 Newlines may come from buffer text, overlay strings, or strings
4440 displayed via the `display' property. That's the reason we can't
4441 simply use find_next_newline_no_quit.
4442
4443 Note that this function may not skip over invisible text that is so
4444 because of text properties and immediately follows a newline. If
4445 it would, function reseat_at_next_visible_line_start, when called
4446 from set_iterator_to_next, would effectively make invisible
4447 characters following a newline part of the wrong glyph row, which
4448 leads to wrong cursor motion. */
4449
4450 static int
4451 forward_to_next_line_start (it, skipped_p)
4452 struct it *it;
4453 int *skipped_p;
4454 {
4455 int old_selective, newline_found_p, n;
4456 const int MAX_NEWLINE_DISTANCE = 500;
4457
4458 /* If already on a newline, just consume it to avoid unintended
4459 skipping over invisible text below. */
4460 if (it->what == IT_CHARACTER
4461 && it->c == '\n'
4462 && CHARPOS (it->position) == IT_CHARPOS (*it))
4463 {
4464 set_iterator_to_next (it, 0);
4465 it->c = 0;
4466 return 1;
4467 }
4468
4469 /* Don't handle selective display in the following. It's (a)
4470 unnecessary because it's done by the caller, and (b) leads to an
4471 infinite recursion because next_element_from_ellipsis indirectly
4472 calls this function. */
4473 old_selective = it->selective;
4474 it->selective = 0;
4475
4476 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4477 from buffer text. */
4478 for (n = newline_found_p = 0;
4479 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4480 n += STRINGP (it->string) ? 0 : 1)
4481 {
4482 if (!get_next_display_element (it))
4483 return 0;
4484 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4485 set_iterator_to_next (it, 0);
4486 }
4487
4488 /* If we didn't find a newline near enough, see if we can use a
4489 short-cut. */
4490 if (!newline_found_p)
4491 {
4492 int start = IT_CHARPOS (*it);
4493 int limit = find_next_newline_no_quit (start, 1);
4494 Lisp_Object pos;
4495
4496 xassert (!STRINGP (it->string));
4497
4498 /* If there isn't any `display' property in sight, and no
4499 overlays, we can just use the position of the newline in
4500 buffer text. */
4501 if (it->stop_charpos >= limit
4502 || ((pos = Fnext_single_property_change (make_number (start),
4503 Qdisplay,
4504 Qnil, make_number (limit)),
4505 NILP (pos))
4506 && next_overlay_change (start) == ZV))
4507 {
4508 IT_CHARPOS (*it) = limit;
4509 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4510 *skipped_p = newline_found_p = 1;
4511 }
4512 else
4513 {
4514 while (get_next_display_element (it)
4515 && !newline_found_p)
4516 {
4517 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4518 set_iterator_to_next (it, 0);
4519 }
4520 }
4521 }
4522
4523 it->selective = old_selective;
4524 return newline_found_p;
4525 }
4526
4527
4528 /* Set IT's current position to the previous visible line start. Skip
4529 invisible text that is so either due to text properties or due to
4530 selective display. Caution: this does not change IT->current_x and
4531 IT->hpos. */
4532
4533 static void
4534 back_to_previous_visible_line_start (it)
4535 struct it *it;
4536 {
4537 int visible_p = 0;
4538
4539 /* Go back one newline if not on BEGV already. */
4540 if (IT_CHARPOS (*it) > BEGV)
4541 back_to_previous_line_start (it);
4542
4543 /* Move over lines that are invisible because of selective display
4544 or text properties. */
4545 while (IT_CHARPOS (*it) > BEGV
4546 && !visible_p)
4547 {
4548 visible_p = 1;
4549
4550 /* If selective > 0, then lines indented more than that values
4551 are invisible. */
4552 if (it->selective > 0
4553 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4554 (double) it->selective)) /* iftc */
4555 visible_p = 0;
4556 else
4557 {
4558 Lisp_Object prop;
4559
4560 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4561 Qinvisible, it->window);
4562 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4563 visible_p = 0;
4564 }
4565
4566 /* Back one more newline if the current one is invisible. */
4567 if (!visible_p)
4568 back_to_previous_line_start (it);
4569 }
4570
4571 xassert (IT_CHARPOS (*it) >= BEGV);
4572 xassert (IT_CHARPOS (*it) == BEGV
4573 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4574 CHECK_IT (it);
4575 }
4576
4577
4578 /* Reseat iterator IT at the previous visible line start. Skip
4579 invisible text that is so either due to text properties or due to
4580 selective display. At the end, update IT's overlay information,
4581 face information etc. */
4582
4583 static void
4584 reseat_at_previous_visible_line_start (it)
4585 struct it *it;
4586 {
4587 back_to_previous_visible_line_start (it);
4588 reseat (it, it->current.pos, 1);
4589 CHECK_IT (it);
4590 }
4591
4592
4593 /* Reseat iterator IT on the next visible line start in the current
4594 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4595 preceding the line start. Skip over invisible text that is so
4596 because of selective display. Compute faces, overlays etc at the
4597 new position. Note that this function does not skip over text that
4598 is invisible because of text properties. */
4599
4600 static void
4601 reseat_at_next_visible_line_start (it, on_newline_p)
4602 struct it *it;
4603 int on_newline_p;
4604 {
4605 int newline_found_p, skipped_p = 0;
4606
4607 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4608
4609 /* Skip over lines that are invisible because they are indented
4610 more than the value of IT->selective. */
4611 if (it->selective > 0)
4612 while (IT_CHARPOS (*it) < ZV
4613 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4614 (double) it->selective)) /* iftc */
4615 {
4616 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4617 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4618 }
4619
4620 /* Position on the newline if that's what's requested. */
4621 if (on_newline_p && newline_found_p)
4622 {
4623 if (STRINGP (it->string))
4624 {
4625 if (IT_STRING_CHARPOS (*it) > 0)
4626 {
4627 --IT_STRING_CHARPOS (*it);
4628 --IT_STRING_BYTEPOS (*it);
4629 }
4630 }
4631 else if (IT_CHARPOS (*it) > BEGV)
4632 {
4633 --IT_CHARPOS (*it);
4634 --IT_BYTEPOS (*it);
4635 reseat (it, it->current.pos, 0);
4636 }
4637 }
4638 else if (skipped_p)
4639 reseat (it, it->current.pos, 0);
4640
4641 CHECK_IT (it);
4642 }
4643
4644
4645 \f
4646 /***********************************************************************
4647 Changing an iterator's position
4648 ***********************************************************************/
4649
4650 /* Change IT's current position to POS in current_buffer. If FORCE_P
4651 is non-zero, always check for text properties at the new position.
4652 Otherwise, text properties are only looked up if POS >=
4653 IT->check_charpos of a property. */
4654
4655 static void
4656 reseat (it, pos, force_p)
4657 struct it *it;
4658 struct text_pos pos;
4659 int force_p;
4660 {
4661 int original_pos = IT_CHARPOS (*it);
4662
4663 reseat_1 (it, pos, 0);
4664
4665 /* Determine where to check text properties. Avoid doing it
4666 where possible because text property lookup is very expensive. */
4667 if (force_p
4668 || CHARPOS (pos) > it->stop_charpos
4669 || CHARPOS (pos) < original_pos)
4670 handle_stop (it);
4671
4672 CHECK_IT (it);
4673 }
4674
4675
4676 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4677 IT->stop_pos to POS, also. */
4678
4679 static void
4680 reseat_1 (it, pos, set_stop_p)
4681 struct it *it;
4682 struct text_pos pos;
4683 int set_stop_p;
4684 {
4685 /* Don't call this function when scanning a C string. */
4686 xassert (it->s == NULL);
4687
4688 /* POS must be a reasonable value. */
4689 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4690
4691 it->current.pos = it->position = pos;
4692 XSETBUFFER (it->object, current_buffer);
4693 it->end_charpos = ZV;
4694 it->dpvec = NULL;
4695 it->current.dpvec_index = -1;
4696 it->current.overlay_string_index = -1;
4697 IT_STRING_CHARPOS (*it) = -1;
4698 IT_STRING_BYTEPOS (*it) = -1;
4699 it->string = Qnil;
4700 it->method = next_element_from_buffer;
4701 /* RMS: I added this to fix a bug in move_it_vertically_backward
4702 where it->area continued to relate to the starting point
4703 for the backward motion. Bug report from
4704 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4705 However, I am not sure whether reseat still does the right thing
4706 in general after this change. */
4707 it->area = TEXT_AREA;
4708 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4709 it->sp = 0;
4710 it->face_before_selective_p = 0;
4711
4712 if (set_stop_p)
4713 it->stop_charpos = CHARPOS (pos);
4714 }
4715
4716
4717 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4718 If S is non-null, it is a C string to iterate over. Otherwise,
4719 STRING gives a Lisp string to iterate over.
4720
4721 If PRECISION > 0, don't return more then PRECISION number of
4722 characters from the string.
4723
4724 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4725 characters have been returned. FIELD_WIDTH < 0 means an infinite
4726 field width.
4727
4728 MULTIBYTE = 0 means disable processing of multibyte characters,
4729 MULTIBYTE > 0 means enable it,
4730 MULTIBYTE < 0 means use IT->multibyte_p.
4731
4732 IT must be initialized via a prior call to init_iterator before
4733 calling this function. */
4734
4735 static void
4736 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4737 struct it *it;
4738 unsigned char *s;
4739 Lisp_Object string;
4740 int charpos;
4741 int precision, field_width, multibyte;
4742 {
4743 /* No region in strings. */
4744 it->region_beg_charpos = it->region_end_charpos = -1;
4745
4746 /* No text property checks performed by default, but see below. */
4747 it->stop_charpos = -1;
4748
4749 /* Set iterator position and end position. */
4750 bzero (&it->current, sizeof it->current);
4751 it->current.overlay_string_index = -1;
4752 it->current.dpvec_index = -1;
4753 xassert (charpos >= 0);
4754
4755 /* If STRING is specified, use its multibyteness, otherwise use the
4756 setting of MULTIBYTE, if specified. */
4757 if (multibyte >= 0)
4758 it->multibyte_p = multibyte > 0;
4759
4760 if (s == NULL)
4761 {
4762 xassert (STRINGP (string));
4763 it->string = string;
4764 it->s = NULL;
4765 it->end_charpos = it->string_nchars = SCHARS (string);
4766 it->method = next_element_from_string;
4767 it->current.string_pos = string_pos (charpos, string);
4768 }
4769 else
4770 {
4771 it->s = s;
4772 it->string = Qnil;
4773
4774 /* Note that we use IT->current.pos, not it->current.string_pos,
4775 for displaying C strings. */
4776 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4777 if (it->multibyte_p)
4778 {
4779 it->current.pos = c_string_pos (charpos, s, 1);
4780 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4781 }
4782 else
4783 {
4784 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4785 it->end_charpos = it->string_nchars = strlen (s);
4786 }
4787
4788 it->method = next_element_from_c_string;
4789 }
4790
4791 /* PRECISION > 0 means don't return more than PRECISION characters
4792 from the string. */
4793 if (precision > 0 && it->end_charpos - charpos > precision)
4794 it->end_charpos = it->string_nchars = charpos + precision;
4795
4796 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4797 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4798 FIELD_WIDTH < 0 means infinite field width. This is useful for
4799 padding with `-' at the end of a mode line. */
4800 if (field_width < 0)
4801 field_width = INFINITY;
4802 if (field_width > it->end_charpos - charpos)
4803 it->end_charpos = charpos + field_width;
4804
4805 /* Use the standard display table for displaying strings. */
4806 if (DISP_TABLE_P (Vstandard_display_table))
4807 it->dp = XCHAR_TABLE (Vstandard_display_table);
4808
4809 it->stop_charpos = charpos;
4810 CHECK_IT (it);
4811 }
4812
4813
4814 \f
4815 /***********************************************************************
4816 Iteration
4817 ***********************************************************************/
4818
4819 /* Load IT's display element fields with information about the next
4820 display element from the current position of IT. Value is zero if
4821 end of buffer (or C string) is reached. */
4822
4823 int
4824 get_next_display_element (it)
4825 struct it *it;
4826 {
4827 /* Non-zero means that we found a display element. Zero means that
4828 we hit the end of what we iterate over. Performance note: the
4829 function pointer `method' used here turns out to be faster than
4830 using a sequence of if-statements. */
4831 int success_p = (*it->method) (it);
4832
4833 if (it->what == IT_CHARACTER)
4834 {
4835 /* Map via display table or translate control characters.
4836 IT->c, IT->len etc. have been set to the next character by
4837 the function call above. If we have a display table, and it
4838 contains an entry for IT->c, translate it. Don't do this if
4839 IT->c itself comes from a display table, otherwise we could
4840 end up in an infinite recursion. (An alternative could be to
4841 count the recursion depth of this function and signal an
4842 error when a certain maximum depth is reached.) Is it worth
4843 it? */
4844 if (success_p && it->dpvec == NULL)
4845 {
4846 Lisp_Object dv;
4847
4848 if (it->dp
4849 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4850 VECTORP (dv)))
4851 {
4852 struct Lisp_Vector *v = XVECTOR (dv);
4853
4854 /* Return the first character from the display table
4855 entry, if not empty. If empty, don't display the
4856 current character. */
4857 if (v->size)
4858 {
4859 it->dpvec_char_len = it->len;
4860 it->dpvec = v->contents;
4861 it->dpend = v->contents + v->size;
4862 it->current.dpvec_index = 0;
4863 it->method = next_element_from_display_vector;
4864 success_p = get_next_display_element (it);
4865 }
4866 else
4867 {
4868 set_iterator_to_next (it, 0);
4869 success_p = get_next_display_element (it);
4870 }
4871 }
4872
4873 /* Translate control characters into `\003' or `^C' form.
4874 Control characters coming from a display table entry are
4875 currently not translated because we use IT->dpvec to hold
4876 the translation. This could easily be changed but I
4877 don't believe that it is worth doing.
4878
4879 If it->multibyte_p is nonzero, eight-bit characters and
4880 non-printable multibyte characters are also translated to
4881 octal form.
4882
4883 If it->multibyte_p is zero, eight-bit characters that
4884 don't have corresponding multibyte char code are also
4885 translated to octal form. */
4886 else if ((it->c < ' '
4887 && (it->area != TEXT_AREA
4888 || (it->c != '\n' && it->c != '\t')))
4889 || (it->multibyte_p
4890 ? ((it->c >= 127
4891 && it->len == 1)
4892 || !CHAR_PRINTABLE_P (it->c))
4893 : (it->c >= 127
4894 && it->c == unibyte_char_to_multibyte (it->c))))
4895 {
4896 /* IT->c is a control character which must be displayed
4897 either as '\003' or as `^C' where the '\\' and '^'
4898 can be defined in the display table. Fill
4899 IT->ctl_chars with glyphs for what we have to
4900 display. Then, set IT->dpvec to these glyphs. */
4901 GLYPH g;
4902
4903 if (it->c < 128 && it->ctl_arrow_p)
4904 {
4905 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4906 if (it->dp
4907 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4908 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4909 g = XINT (DISP_CTRL_GLYPH (it->dp));
4910 else
4911 g = FAST_MAKE_GLYPH ('^', 0);
4912 XSETINT (it->ctl_chars[0], g);
4913
4914 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4915 XSETINT (it->ctl_chars[1], g);
4916
4917 /* Set up IT->dpvec and return first character from it. */
4918 it->dpvec_char_len = it->len;
4919 it->dpvec = it->ctl_chars;
4920 it->dpend = it->dpvec + 2;
4921 it->current.dpvec_index = 0;
4922 it->method = next_element_from_display_vector;
4923 get_next_display_element (it);
4924 }
4925 else
4926 {
4927 unsigned char str[MAX_MULTIBYTE_LENGTH];
4928 int len;
4929 int i;
4930 GLYPH escape_glyph;
4931
4932 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4933 if (it->dp
4934 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4935 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4936 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4937 else
4938 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4939
4940 if (SINGLE_BYTE_CHAR_P (it->c))
4941 str[0] = it->c, len = 1;
4942 else
4943 {
4944 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4945 if (len < 0)
4946 {
4947 /* It's an invalid character, which
4948 shouldn't happen actually, but due to
4949 bugs it may happen. Let's print the char
4950 as is, there's not much meaningful we can
4951 do with it. */
4952 str[0] = it->c;
4953 str[1] = it->c >> 8;
4954 str[2] = it->c >> 16;
4955 str[3] = it->c >> 24;
4956 len = 4;
4957 }
4958 }
4959
4960 for (i = 0; i < len; i++)
4961 {
4962 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4963 /* Insert three more glyphs into IT->ctl_chars for
4964 the octal display of the character. */
4965 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4966 XSETINT (it->ctl_chars[i * 4 + 1], g);
4967 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4968 XSETINT (it->ctl_chars[i * 4 + 2], g);
4969 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4970 XSETINT (it->ctl_chars[i * 4 + 3], g);
4971 }
4972
4973 /* Set up IT->dpvec and return the first character
4974 from it. */
4975 it->dpvec_char_len = it->len;
4976 it->dpvec = it->ctl_chars;
4977 it->dpend = it->dpvec + len * 4;
4978 it->current.dpvec_index = 0;
4979 it->method = next_element_from_display_vector;
4980 get_next_display_element (it);
4981 }
4982 }
4983 }
4984
4985 /* Adjust face id for a multibyte character. There are no
4986 multibyte character in unibyte text. */
4987 if (it->multibyte_p
4988 && success_p
4989 && FRAME_WINDOW_P (it->f))
4990 {
4991 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4992 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4993 }
4994 }
4995
4996 /* Is this character the last one of a run of characters with
4997 box? If yes, set IT->end_of_box_run_p to 1. */
4998 if (it->face_box_p
4999 && it->s == NULL)
5000 {
5001 int face_id;
5002 struct face *face;
5003
5004 it->end_of_box_run_p
5005 = ((face_id = face_after_it_pos (it),
5006 face_id != it->face_id)
5007 && (face = FACE_FROM_ID (it->f, face_id),
5008 face->box == FACE_NO_BOX));
5009 }
5010
5011 /* Value is 0 if end of buffer or string reached. */
5012 return success_p;
5013 }
5014
5015
5016 /* Move IT to the next display element.
5017
5018 RESEAT_P non-zero means if called on a newline in buffer text,
5019 skip to the next visible line start.
5020
5021 Functions get_next_display_element and set_iterator_to_next are
5022 separate because I find this arrangement easier to handle than a
5023 get_next_display_element function that also increments IT's
5024 position. The way it is we can first look at an iterator's current
5025 display element, decide whether it fits on a line, and if it does,
5026 increment the iterator position. The other way around we probably
5027 would either need a flag indicating whether the iterator has to be
5028 incremented the next time, or we would have to implement a
5029 decrement position function which would not be easy to write. */
5030
5031 void
5032 set_iterator_to_next (it, reseat_p)
5033 struct it *it;
5034 int reseat_p;
5035 {
5036 /* Reset flags indicating start and end of a sequence of characters
5037 with box. Reset them at the start of this function because
5038 moving the iterator to a new position might set them. */
5039 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5040
5041 if (it->method == next_element_from_buffer)
5042 {
5043 /* The current display element of IT is a character from
5044 current_buffer. Advance in the buffer, and maybe skip over
5045 invisible lines that are so because of selective display. */
5046 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5047 reseat_at_next_visible_line_start (it, 0);
5048 else
5049 {
5050 xassert (it->len != 0);
5051 IT_BYTEPOS (*it) += it->len;
5052 IT_CHARPOS (*it) += 1;
5053 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5054 }
5055 }
5056 else if (it->method == next_element_from_composition)
5057 {
5058 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5059 if (STRINGP (it->string))
5060 {
5061 IT_STRING_BYTEPOS (*it) += it->len;
5062 IT_STRING_CHARPOS (*it) += it->cmp_len;
5063 it->method = next_element_from_string;
5064 goto consider_string_end;
5065 }
5066 else
5067 {
5068 IT_BYTEPOS (*it) += it->len;
5069 IT_CHARPOS (*it) += it->cmp_len;
5070 it->method = next_element_from_buffer;
5071 }
5072 }
5073 else if (it->method == next_element_from_c_string)
5074 {
5075 /* Current display element of IT is from a C string. */
5076 IT_BYTEPOS (*it) += it->len;
5077 IT_CHARPOS (*it) += 1;
5078 }
5079 else if (it->method == next_element_from_display_vector)
5080 {
5081 /* Current display element of IT is from a display table entry.
5082 Advance in the display table definition. Reset it to null if
5083 end reached, and continue with characters from buffers/
5084 strings. */
5085 ++it->current.dpvec_index;
5086
5087 /* Restore face of the iterator to what they were before the
5088 display vector entry (these entries may contain faces). */
5089 it->face_id = it->saved_face_id;
5090
5091 if (it->dpvec + it->current.dpvec_index == it->dpend)
5092 {
5093 if (it->s)
5094 it->method = next_element_from_c_string;
5095 else if (STRINGP (it->string))
5096 it->method = next_element_from_string;
5097 else
5098 it->method = next_element_from_buffer;
5099
5100 it->dpvec = NULL;
5101 it->current.dpvec_index = -1;
5102
5103 /* Skip over characters which were displayed via IT->dpvec. */
5104 if (it->dpvec_char_len < 0)
5105 reseat_at_next_visible_line_start (it, 1);
5106 else if (it->dpvec_char_len > 0)
5107 {
5108 it->len = it->dpvec_char_len;
5109 set_iterator_to_next (it, reseat_p);
5110 }
5111 }
5112 }
5113 else if (it->method == next_element_from_string)
5114 {
5115 /* Current display element is a character from a Lisp string. */
5116 xassert (it->s == NULL && STRINGP (it->string));
5117 IT_STRING_BYTEPOS (*it) += it->len;
5118 IT_STRING_CHARPOS (*it) += 1;
5119
5120 consider_string_end:
5121
5122 if (it->current.overlay_string_index >= 0)
5123 {
5124 /* IT->string is an overlay string. Advance to the
5125 next, if there is one. */
5126 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5127 next_overlay_string (it);
5128 }
5129 else
5130 {
5131 /* IT->string is not an overlay string. If we reached
5132 its end, and there is something on IT->stack, proceed
5133 with what is on the stack. This can be either another
5134 string, this time an overlay string, or a buffer. */
5135 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5136 && it->sp > 0)
5137 {
5138 pop_it (it);
5139 if (!STRINGP (it->string))
5140 it->method = next_element_from_buffer;
5141 else
5142 goto consider_string_end;
5143 }
5144 }
5145 }
5146 else if (it->method == next_element_from_image
5147 || it->method == next_element_from_stretch)
5148 {
5149 /* The position etc with which we have to proceed are on
5150 the stack. The position may be at the end of a string,
5151 if the `display' property takes up the whole string. */
5152 pop_it (it);
5153 it->image_id = 0;
5154 if (STRINGP (it->string))
5155 {
5156 it->method = next_element_from_string;
5157 goto consider_string_end;
5158 }
5159 else
5160 it->method = next_element_from_buffer;
5161 }
5162 else
5163 /* There are no other methods defined, so this should be a bug. */
5164 abort ();
5165
5166 xassert (it->method != next_element_from_string
5167 || (STRINGP (it->string)
5168 && IT_STRING_CHARPOS (*it) >= 0));
5169 }
5170
5171
5172 /* Load IT's display element fields with information about the next
5173 display element which comes from a display table entry or from the
5174 result of translating a control character to one of the forms `^C'
5175 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5176
5177 static int
5178 next_element_from_display_vector (it)
5179 struct it *it;
5180 {
5181 /* Precondition. */
5182 xassert (it->dpvec && it->current.dpvec_index >= 0);
5183
5184 /* Remember the current face id in case glyphs specify faces.
5185 IT's face is restored in set_iterator_to_next. */
5186 it->saved_face_id = it->face_id;
5187
5188 if (INTEGERP (*it->dpvec)
5189 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5190 {
5191 int lface_id;
5192 GLYPH g;
5193
5194 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5195 it->c = FAST_GLYPH_CHAR (g);
5196 it->len = CHAR_BYTES (it->c);
5197
5198 /* The entry may contain a face id to use. Such a face id is
5199 the id of a Lisp face, not a realized face. A face id of
5200 zero means no face is specified. */
5201 lface_id = FAST_GLYPH_FACE (g);
5202 if (lface_id)
5203 {
5204 /* The function returns -1 if lface_id is invalid. */
5205 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5206 if (face_id >= 0)
5207 it->face_id = face_id;
5208 }
5209 }
5210 else
5211 /* Display table entry is invalid. Return a space. */
5212 it->c = ' ', it->len = 1;
5213
5214 /* Don't change position and object of the iterator here. They are
5215 still the values of the character that had this display table
5216 entry or was translated, and that's what we want. */
5217 it->what = IT_CHARACTER;
5218 return 1;
5219 }
5220
5221
5222 /* Load IT with the next display element from Lisp string IT->string.
5223 IT->current.string_pos is the current position within the string.
5224 If IT->current.overlay_string_index >= 0, the Lisp string is an
5225 overlay string. */
5226
5227 static int
5228 next_element_from_string (it)
5229 struct it *it;
5230 {
5231 struct text_pos position;
5232
5233 xassert (STRINGP (it->string));
5234 xassert (IT_STRING_CHARPOS (*it) >= 0);
5235 position = it->current.string_pos;
5236
5237 /* Time to check for invisible text? */
5238 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5239 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5240 {
5241 handle_stop (it);
5242
5243 /* Since a handler may have changed IT->method, we must
5244 recurse here. */
5245 return get_next_display_element (it);
5246 }
5247
5248 if (it->current.overlay_string_index >= 0)
5249 {
5250 /* Get the next character from an overlay string. In overlay
5251 strings, There is no field width or padding with spaces to
5252 do. */
5253 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5254 {
5255 it->what = IT_EOB;
5256 return 0;
5257 }
5258 else if (STRING_MULTIBYTE (it->string))
5259 {
5260 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5261 const unsigned char *s = (SDATA (it->string)
5262 + IT_STRING_BYTEPOS (*it));
5263 it->c = string_char_and_length (s, remaining, &it->len);
5264 }
5265 else
5266 {
5267 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5268 it->len = 1;
5269 }
5270 }
5271 else
5272 {
5273 /* Get the next character from a Lisp string that is not an
5274 overlay string. Such strings come from the mode line, for
5275 example. We may have to pad with spaces, or truncate the
5276 string. See also next_element_from_c_string. */
5277 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5278 {
5279 it->what = IT_EOB;
5280 return 0;
5281 }
5282 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5283 {
5284 /* Pad with spaces. */
5285 it->c = ' ', it->len = 1;
5286 CHARPOS (position) = BYTEPOS (position) = -1;
5287 }
5288 else if (STRING_MULTIBYTE (it->string))
5289 {
5290 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5291 const unsigned char *s = (SDATA (it->string)
5292 + IT_STRING_BYTEPOS (*it));
5293 it->c = string_char_and_length (s, maxlen, &it->len);
5294 }
5295 else
5296 {
5297 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5298 it->len = 1;
5299 }
5300 }
5301
5302 /* Record what we have and where it came from. Note that we store a
5303 buffer position in IT->position although it could arguably be a
5304 string position. */
5305 it->what = IT_CHARACTER;
5306 it->object = it->string;
5307 it->position = position;
5308 return 1;
5309 }
5310
5311
5312 /* Load IT with next display element from C string IT->s.
5313 IT->string_nchars is the maximum number of characters to return
5314 from the string. IT->end_charpos may be greater than
5315 IT->string_nchars when this function is called, in which case we
5316 may have to return padding spaces. Value is zero if end of string
5317 reached, including padding spaces. */
5318
5319 static int
5320 next_element_from_c_string (it)
5321 struct it *it;
5322 {
5323 int success_p = 1;
5324
5325 xassert (it->s);
5326 it->what = IT_CHARACTER;
5327 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5328 it->object = Qnil;
5329
5330 /* IT's position can be greater IT->string_nchars in case a field
5331 width or precision has been specified when the iterator was
5332 initialized. */
5333 if (IT_CHARPOS (*it) >= it->end_charpos)
5334 {
5335 /* End of the game. */
5336 it->what = IT_EOB;
5337 success_p = 0;
5338 }
5339 else if (IT_CHARPOS (*it) >= it->string_nchars)
5340 {
5341 /* Pad with spaces. */
5342 it->c = ' ', it->len = 1;
5343 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5344 }
5345 else if (it->multibyte_p)
5346 {
5347 /* Implementation note: The calls to strlen apparently aren't a
5348 performance problem because there is no noticeable performance
5349 difference between Emacs running in unibyte or multibyte mode. */
5350 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5351 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5352 maxlen, &it->len);
5353 }
5354 else
5355 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5356
5357 return success_p;
5358 }
5359
5360
5361 /* Set up IT to return characters from an ellipsis, if appropriate.
5362 The definition of the ellipsis glyphs may come from a display table
5363 entry. This function Fills IT with the first glyph from the
5364 ellipsis if an ellipsis is to be displayed. */
5365
5366 static int
5367 next_element_from_ellipsis (it)
5368 struct it *it;
5369 {
5370 if (it->selective_display_ellipsis_p)
5371 {
5372 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5373 {
5374 /* Use the display table definition for `...'. Invalid glyphs
5375 will be handled by the method returning elements from dpvec. */
5376 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5377 it->dpvec_char_len = it->len;
5378 it->dpvec = v->contents;
5379 it->dpend = v->contents + v->size;
5380 it->current.dpvec_index = 0;
5381 it->method = next_element_from_display_vector;
5382 }
5383 else
5384 {
5385 /* Use default `...' which is stored in default_invis_vector. */
5386 it->dpvec_char_len = it->len;
5387 it->dpvec = default_invis_vector;
5388 it->dpend = default_invis_vector + 3;
5389 it->current.dpvec_index = 0;
5390 it->method = next_element_from_display_vector;
5391 }
5392 }
5393 else
5394 {
5395 /* The face at the current position may be different from the
5396 face we find after the invisible text. Remember what it
5397 was in IT->saved_face_id, and signal that it's there by
5398 setting face_before_selective_p. */
5399 it->saved_face_id = it->face_id;
5400 it->method = next_element_from_buffer;
5401 reseat_at_next_visible_line_start (it, 1);
5402 it->face_before_selective_p = 1;
5403 }
5404
5405 return get_next_display_element (it);
5406 }
5407
5408
5409 /* Deliver an image display element. The iterator IT is already
5410 filled with image information (done in handle_display_prop). Value
5411 is always 1. */
5412
5413
5414 static int
5415 next_element_from_image (it)
5416 struct it *it;
5417 {
5418 it->what = IT_IMAGE;
5419 return 1;
5420 }
5421
5422
5423 /* Fill iterator IT with next display element from a stretch glyph
5424 property. IT->object is the value of the text property. Value is
5425 always 1. */
5426
5427 static int
5428 next_element_from_stretch (it)
5429 struct it *it;
5430 {
5431 it->what = IT_STRETCH;
5432 return 1;
5433 }
5434
5435
5436 /* Load IT with the next display element from current_buffer. Value
5437 is zero if end of buffer reached. IT->stop_charpos is the next
5438 position at which to stop and check for text properties or buffer
5439 end. */
5440
5441 static int
5442 next_element_from_buffer (it)
5443 struct it *it;
5444 {
5445 int success_p = 1;
5446
5447 /* Check this assumption, otherwise, we would never enter the
5448 if-statement, below. */
5449 xassert (IT_CHARPOS (*it) >= BEGV
5450 && IT_CHARPOS (*it) <= it->stop_charpos);
5451
5452 if (IT_CHARPOS (*it) >= it->stop_charpos)
5453 {
5454 if (IT_CHARPOS (*it) >= it->end_charpos)
5455 {
5456 int overlay_strings_follow_p;
5457
5458 /* End of the game, except when overlay strings follow that
5459 haven't been returned yet. */
5460 if (it->overlay_strings_at_end_processed_p)
5461 overlay_strings_follow_p = 0;
5462 else
5463 {
5464 it->overlay_strings_at_end_processed_p = 1;
5465 overlay_strings_follow_p = get_overlay_strings (it, 0);
5466 }
5467
5468 if (overlay_strings_follow_p)
5469 success_p = get_next_display_element (it);
5470 else
5471 {
5472 it->what = IT_EOB;
5473 it->position = it->current.pos;
5474 success_p = 0;
5475 }
5476 }
5477 else
5478 {
5479 handle_stop (it);
5480 return get_next_display_element (it);
5481 }
5482 }
5483 else
5484 {
5485 /* No face changes, overlays etc. in sight, so just return a
5486 character from current_buffer. */
5487 unsigned char *p;
5488
5489 /* Maybe run the redisplay end trigger hook. Performance note:
5490 This doesn't seem to cost measurable time. */
5491 if (it->redisplay_end_trigger_charpos
5492 && it->glyph_row
5493 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5494 run_redisplay_end_trigger_hook (it);
5495
5496 /* Get the next character, maybe multibyte. */
5497 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5498 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5499 {
5500 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5501 - IT_BYTEPOS (*it));
5502 it->c = string_char_and_length (p, maxlen, &it->len);
5503 }
5504 else
5505 it->c = *p, it->len = 1;
5506
5507 /* Record what we have and where it came from. */
5508 it->what = IT_CHARACTER;;
5509 it->object = it->w->buffer;
5510 it->position = it->current.pos;
5511
5512 /* Normally we return the character found above, except when we
5513 really want to return an ellipsis for selective display. */
5514 if (it->selective)
5515 {
5516 if (it->c == '\n')
5517 {
5518 /* A value of selective > 0 means hide lines indented more
5519 than that number of columns. */
5520 if (it->selective > 0
5521 && IT_CHARPOS (*it) + 1 < ZV
5522 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5523 IT_BYTEPOS (*it) + 1,
5524 (double) it->selective)) /* iftc */
5525 {
5526 success_p = next_element_from_ellipsis (it);
5527 it->dpvec_char_len = -1;
5528 }
5529 }
5530 else if (it->c == '\r' && it->selective == -1)
5531 {
5532 /* A value of selective == -1 means that everything from the
5533 CR to the end of the line is invisible, with maybe an
5534 ellipsis displayed for it. */
5535 success_p = next_element_from_ellipsis (it);
5536 it->dpvec_char_len = -1;
5537 }
5538 }
5539 }
5540
5541 /* Value is zero if end of buffer reached. */
5542 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5543 return success_p;
5544 }
5545
5546
5547 /* Run the redisplay end trigger hook for IT. */
5548
5549 static void
5550 run_redisplay_end_trigger_hook (it)
5551 struct it *it;
5552 {
5553 Lisp_Object args[3];
5554
5555 /* IT->glyph_row should be non-null, i.e. we should be actually
5556 displaying something, or otherwise we should not run the hook. */
5557 xassert (it->glyph_row);
5558
5559 /* Set up hook arguments. */
5560 args[0] = Qredisplay_end_trigger_functions;
5561 args[1] = it->window;
5562 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5563 it->redisplay_end_trigger_charpos = 0;
5564
5565 /* Since we are *trying* to run these functions, don't try to run
5566 them again, even if they get an error. */
5567 it->w->redisplay_end_trigger = Qnil;
5568 Frun_hook_with_args (3, args);
5569
5570 /* Notice if it changed the face of the character we are on. */
5571 handle_face_prop (it);
5572 }
5573
5574
5575 /* Deliver a composition display element. The iterator IT is already
5576 filled with composition information (done in
5577 handle_composition_prop). Value is always 1. */
5578
5579 static int
5580 next_element_from_composition (it)
5581 struct it *it;
5582 {
5583 it->what = IT_COMPOSITION;
5584 it->position = (STRINGP (it->string)
5585 ? it->current.string_pos
5586 : it->current.pos);
5587 return 1;
5588 }
5589
5590
5591 \f
5592 /***********************************************************************
5593 Moving an iterator without producing glyphs
5594 ***********************************************************************/
5595
5596 /* Move iterator IT to a specified buffer or X position within one
5597 line on the display without producing glyphs.
5598
5599 OP should be a bit mask including some or all of these bits:
5600 MOVE_TO_X: Stop on reaching x-position TO_X.
5601 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5602 Regardless of OP's value, stop in reaching the end of the display line.
5603
5604 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5605 This means, in particular, that TO_X includes window's horizontal
5606 scroll amount.
5607
5608 The return value has several possible values that
5609 say what condition caused the scan to stop:
5610
5611 MOVE_POS_MATCH_OR_ZV
5612 - when TO_POS or ZV was reached.
5613
5614 MOVE_X_REACHED
5615 -when TO_X was reached before TO_POS or ZV were reached.
5616
5617 MOVE_LINE_CONTINUED
5618 - when we reached the end of the display area and the line must
5619 be continued.
5620
5621 MOVE_LINE_TRUNCATED
5622 - when we reached the end of the display area and the line is
5623 truncated.
5624
5625 MOVE_NEWLINE_OR_CR
5626 - when we stopped at a line end, i.e. a newline or a CR and selective
5627 display is on. */
5628
5629 static enum move_it_result
5630 move_it_in_display_line_to (it, to_charpos, to_x, op)
5631 struct it *it;
5632 int to_charpos, to_x, op;
5633 {
5634 enum move_it_result result = MOVE_UNDEFINED;
5635 struct glyph_row *saved_glyph_row;
5636
5637 /* Don't produce glyphs in produce_glyphs. */
5638 saved_glyph_row = it->glyph_row;
5639 it->glyph_row = NULL;
5640
5641 #define BUFFER_POS_REACHED_P() \
5642 ((op & MOVE_TO_POS) != 0 \
5643 && BUFFERP (it->object) \
5644 && IT_CHARPOS (*it) >= to_charpos)
5645
5646 while (1)
5647 {
5648 int x, i, ascent = 0, descent = 0;
5649
5650 /* Stop when ZV or TO_CHARPOS reached. */
5651 if (!get_next_display_element (it)
5652 || BUFFER_POS_REACHED_P ())
5653 {
5654 result = MOVE_POS_MATCH_OR_ZV;
5655 break;
5656 }
5657
5658 /* The call to produce_glyphs will get the metrics of the
5659 display element IT is loaded with. We record in x the
5660 x-position before this display element in case it does not
5661 fit on the line. */
5662 x = it->current_x;
5663
5664 /* Remember the line height so far in case the next element doesn't
5665 fit on the line. */
5666 if (!it->truncate_lines_p)
5667 {
5668 ascent = it->max_ascent;
5669 descent = it->max_descent;
5670 }
5671
5672 PRODUCE_GLYPHS (it);
5673
5674 if (it->area != TEXT_AREA)
5675 {
5676 set_iterator_to_next (it, 1);
5677 continue;
5678 }
5679
5680 /* The number of glyphs we get back in IT->nglyphs will normally
5681 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5682 character on a terminal frame, or (iii) a line end. For the
5683 second case, IT->nglyphs - 1 padding glyphs will be present
5684 (on X frames, there is only one glyph produced for a
5685 composite character.
5686
5687 The behavior implemented below means, for continuation lines,
5688 that as many spaces of a TAB as fit on the current line are
5689 displayed there. For terminal frames, as many glyphs of a
5690 multi-glyph character are displayed in the current line, too.
5691 This is what the old redisplay code did, and we keep it that
5692 way. Under X, the whole shape of a complex character must
5693 fit on the line or it will be completely displayed in the
5694 next line.
5695
5696 Note that both for tabs and padding glyphs, all glyphs have
5697 the same width. */
5698 if (it->nglyphs)
5699 {
5700 /* More than one glyph or glyph doesn't fit on line. All
5701 glyphs have the same width. */
5702 int single_glyph_width = it->pixel_width / it->nglyphs;
5703 int new_x;
5704
5705 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5706 {
5707 new_x = x + single_glyph_width;
5708
5709 /* We want to leave anything reaching TO_X to the caller. */
5710 if ((op & MOVE_TO_X) && new_x > to_x)
5711 {
5712 it->current_x = x;
5713 result = MOVE_X_REACHED;
5714 break;
5715 }
5716 else if (/* Lines are continued. */
5717 !it->truncate_lines_p
5718 && (/* And glyph doesn't fit on the line. */
5719 new_x > it->last_visible_x
5720 /* Or it fits exactly and we're on a window
5721 system frame. */
5722 || (new_x == it->last_visible_x
5723 && FRAME_WINDOW_P (it->f))))
5724 {
5725 if (/* IT->hpos == 0 means the very first glyph
5726 doesn't fit on the line, e.g. a wide image. */
5727 it->hpos == 0
5728 || (new_x == it->last_visible_x
5729 && FRAME_WINDOW_P (it->f)))
5730 {
5731 ++it->hpos;
5732 it->current_x = new_x;
5733 if (i == it->nglyphs - 1)
5734 {
5735 set_iterator_to_next (it, 1);
5736 #ifdef HAVE_WINDOW_SYSTEM
5737 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5738 {
5739 if (!get_next_display_element (it)
5740 || BUFFER_POS_REACHED_P ())
5741 {
5742 result = MOVE_POS_MATCH_OR_ZV;
5743 break;
5744 }
5745 if (ITERATOR_AT_END_OF_LINE_P (it))
5746 {
5747 result = MOVE_NEWLINE_OR_CR;
5748 break;
5749 }
5750 }
5751 #endif /* HAVE_WINDOW_SYSTEM */
5752 }
5753 }
5754 else
5755 {
5756 it->current_x = x;
5757 it->max_ascent = ascent;
5758 it->max_descent = descent;
5759 }
5760
5761 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5762 IT_CHARPOS (*it)));
5763 result = MOVE_LINE_CONTINUED;
5764 break;
5765 }
5766 else if (new_x > it->first_visible_x)
5767 {
5768 /* Glyph is visible. Increment number of glyphs that
5769 would be displayed. */
5770 ++it->hpos;
5771 }
5772 else
5773 {
5774 /* Glyph is completely off the left margin of the display
5775 area. Nothing to do. */
5776 }
5777 }
5778
5779 if (result != MOVE_UNDEFINED)
5780 break;
5781 }
5782 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5783 {
5784 /* Stop when TO_X specified and reached. This check is
5785 necessary here because of lines consisting of a line end,
5786 only. The line end will not produce any glyphs and we
5787 would never get MOVE_X_REACHED. */
5788 xassert (it->nglyphs == 0);
5789 result = MOVE_X_REACHED;
5790 break;
5791 }
5792
5793 /* Is this a line end? If yes, we're done. */
5794 if (ITERATOR_AT_END_OF_LINE_P (it))
5795 {
5796 result = MOVE_NEWLINE_OR_CR;
5797 break;
5798 }
5799
5800 /* The current display element has been consumed. Advance
5801 to the next. */
5802 set_iterator_to_next (it, 1);
5803
5804 /* Stop if lines are truncated and IT's current x-position is
5805 past the right edge of the window now. */
5806 if (it->truncate_lines_p
5807 && it->current_x >= it->last_visible_x)
5808 {
5809 #ifdef HAVE_WINDOW_SYSTEM
5810 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5811 {
5812 if (!get_next_display_element (it)
5813 || BUFFER_POS_REACHED_P ())
5814 {
5815 result = MOVE_POS_MATCH_OR_ZV;
5816 break;
5817 }
5818 if (ITERATOR_AT_END_OF_LINE_P (it))
5819 {
5820 result = MOVE_NEWLINE_OR_CR;
5821 break;
5822 }
5823 }
5824 #endif /* HAVE_WINDOW_SYSTEM */
5825 result = MOVE_LINE_TRUNCATED;
5826 break;
5827 }
5828 }
5829
5830 #undef BUFFER_POS_REACHED_P
5831
5832 /* Restore the iterator settings altered at the beginning of this
5833 function. */
5834 it->glyph_row = saved_glyph_row;
5835 return result;
5836 }
5837
5838
5839 /* Move IT forward until it satisfies one or more of the criteria in
5840 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5841
5842 OP is a bit-mask that specifies where to stop, and in particular,
5843 which of those four position arguments makes a difference. See the
5844 description of enum move_operation_enum.
5845
5846 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5847 screen line, this function will set IT to the next position >
5848 TO_CHARPOS. */
5849
5850 void
5851 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5852 struct it *it;
5853 int to_charpos, to_x, to_y, to_vpos;
5854 int op;
5855 {
5856 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5857 int line_height;
5858 int reached = 0;
5859
5860 for (;;)
5861 {
5862 if (op & MOVE_TO_VPOS)
5863 {
5864 /* If no TO_CHARPOS and no TO_X specified, stop at the
5865 start of the line TO_VPOS. */
5866 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5867 {
5868 if (it->vpos == to_vpos)
5869 {
5870 reached = 1;
5871 break;
5872 }
5873 else
5874 skip = move_it_in_display_line_to (it, -1, -1, 0);
5875 }
5876 else
5877 {
5878 /* TO_VPOS >= 0 means stop at TO_X in the line at
5879 TO_VPOS, or at TO_POS, whichever comes first. */
5880 if (it->vpos == to_vpos)
5881 {
5882 reached = 2;
5883 break;
5884 }
5885
5886 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5887
5888 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5889 {
5890 reached = 3;
5891 break;
5892 }
5893 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5894 {
5895 /* We have reached TO_X but not in the line we want. */
5896 skip = move_it_in_display_line_to (it, to_charpos,
5897 -1, MOVE_TO_POS);
5898 if (skip == MOVE_POS_MATCH_OR_ZV)
5899 {
5900 reached = 4;
5901 break;
5902 }
5903 }
5904 }
5905 }
5906 else if (op & MOVE_TO_Y)
5907 {
5908 struct it it_backup;
5909
5910 /* TO_Y specified means stop at TO_X in the line containing
5911 TO_Y---or at TO_CHARPOS if this is reached first. The
5912 problem is that we can't really tell whether the line
5913 contains TO_Y before we have completely scanned it, and
5914 this may skip past TO_X. What we do is to first scan to
5915 TO_X.
5916
5917 If TO_X is not specified, use a TO_X of zero. The reason
5918 is to make the outcome of this function more predictable.
5919 If we didn't use TO_X == 0, we would stop at the end of
5920 the line which is probably not what a caller would expect
5921 to happen. */
5922 skip = move_it_in_display_line_to (it, to_charpos,
5923 ((op & MOVE_TO_X)
5924 ? to_x : 0),
5925 (MOVE_TO_X
5926 | (op & MOVE_TO_POS)));
5927
5928 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5929 if (skip == MOVE_POS_MATCH_OR_ZV)
5930 {
5931 reached = 5;
5932 break;
5933 }
5934
5935 /* If TO_X was reached, we would like to know whether TO_Y
5936 is in the line. This can only be said if we know the
5937 total line height which requires us to scan the rest of
5938 the line. */
5939 if (skip == MOVE_X_REACHED)
5940 {
5941 it_backup = *it;
5942 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5943 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5944 op & MOVE_TO_POS);
5945 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5946 }
5947
5948 /* Now, decide whether TO_Y is in this line. */
5949 line_height = it->max_ascent + it->max_descent;
5950 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5951
5952 if (to_y >= it->current_y
5953 && to_y < it->current_y + line_height)
5954 {
5955 if (skip == MOVE_X_REACHED)
5956 /* If TO_Y is in this line and TO_X was reached above,
5957 we scanned too far. We have to restore IT's settings
5958 to the ones before skipping. */
5959 *it = it_backup;
5960 reached = 6;
5961 }
5962 else if (skip == MOVE_X_REACHED)
5963 {
5964 skip = skip2;
5965 if (skip == MOVE_POS_MATCH_OR_ZV)
5966 reached = 7;
5967 }
5968
5969 if (reached)
5970 break;
5971 }
5972 else
5973 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5974
5975 switch (skip)
5976 {
5977 case MOVE_POS_MATCH_OR_ZV:
5978 reached = 8;
5979 goto out;
5980
5981 case MOVE_NEWLINE_OR_CR:
5982 set_iterator_to_next (it, 1);
5983 it->continuation_lines_width = 0;
5984 break;
5985
5986 case MOVE_LINE_TRUNCATED:
5987 it->continuation_lines_width = 0;
5988 reseat_at_next_visible_line_start (it, 0);
5989 if ((op & MOVE_TO_POS) != 0
5990 && IT_CHARPOS (*it) > to_charpos)
5991 {
5992 reached = 9;
5993 goto out;
5994 }
5995 break;
5996
5997 case MOVE_LINE_CONTINUED:
5998 it->continuation_lines_width += it->current_x;
5999 break;
6000
6001 default:
6002 abort ();
6003 }
6004
6005 /* Reset/increment for the next run. */
6006 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6007 it->current_x = it->hpos = 0;
6008 it->current_y += it->max_ascent + it->max_descent;
6009 ++it->vpos;
6010 last_height = it->max_ascent + it->max_descent;
6011 last_max_ascent = it->max_ascent;
6012 it->max_ascent = it->max_descent = 0;
6013 }
6014
6015 out:
6016
6017 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6018 }
6019
6020
6021 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6022
6023 If DY > 0, move IT backward at least that many pixels. DY = 0
6024 means move IT backward to the preceding line start or BEGV. This
6025 function may move over more than DY pixels if IT->current_y - DY
6026 ends up in the middle of a line; in this case IT->current_y will be
6027 set to the top of the line moved to. */
6028
6029 void
6030 move_it_vertically_backward (it, dy)
6031 struct it *it;
6032 int dy;
6033 {
6034 int nlines, h;
6035 struct it it2, it3;
6036 int start_pos = IT_CHARPOS (*it);
6037
6038 xassert (dy >= 0);
6039
6040 /* Estimate how many newlines we must move back. */
6041 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6042
6043 /* Set the iterator's position that many lines back. */
6044 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6045 back_to_previous_visible_line_start (it);
6046
6047 /* Reseat the iterator here. When moving backward, we don't want
6048 reseat to skip forward over invisible text, set up the iterator
6049 to deliver from overlay strings at the new position etc. So,
6050 use reseat_1 here. */
6051 reseat_1 (it, it->current.pos, 1);
6052
6053 /* We are now surely at a line start. */
6054 it->current_x = it->hpos = 0;
6055 it->continuation_lines_width = 0;
6056
6057 /* Move forward and see what y-distance we moved. First move to the
6058 start of the next line so that we get its height. We need this
6059 height to be able to tell whether we reached the specified
6060 y-distance. */
6061 it2 = *it;
6062 it2.max_ascent = it2.max_descent = 0;
6063 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6064 MOVE_TO_POS | MOVE_TO_VPOS);
6065 xassert (IT_CHARPOS (*it) >= BEGV);
6066 it3 = it2;
6067
6068 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6069 xassert (IT_CHARPOS (*it) >= BEGV);
6070 /* H is the actual vertical distance from the position in *IT
6071 and the starting position. */
6072 h = it2.current_y - it->current_y;
6073 /* NLINES is the distance in number of lines. */
6074 nlines = it2.vpos - it->vpos;
6075
6076 /* Correct IT's y and vpos position
6077 so that they are relative to the starting point. */
6078 it->vpos -= nlines;
6079 it->current_y -= h;
6080
6081 if (dy == 0)
6082 {
6083 /* DY == 0 means move to the start of the screen line. The
6084 value of nlines is > 0 if continuation lines were involved. */
6085 if (nlines > 0)
6086 move_it_by_lines (it, nlines, 1);
6087 xassert (IT_CHARPOS (*it) <= start_pos);
6088 }
6089 else
6090 {
6091 /* The y-position we try to reach, relative to *IT.
6092 Note that H has been subtracted in front of the if-statement. */
6093 int target_y = it->current_y + h - dy;
6094 int y0 = it3.current_y;
6095 int y1 = line_bottom_y (&it3);
6096 int line_height = y1 - y0;
6097
6098 /* If we did not reach target_y, try to move further backward if
6099 we can. If we moved too far backward, try to move forward. */
6100 if (target_y < it->current_y
6101 /* This is heuristic. In a window that's 3 lines high, with
6102 a line height of 13 pixels each, recentering with point
6103 on the bottom line will try to move -39/2 = 19 pixels
6104 backward. Try to avoid moving into the first line. */
6105 && it->current_y - target_y > line_height / 3 * 2
6106 && IT_CHARPOS (*it) > BEGV)
6107 {
6108 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6109 target_y - it->current_y));
6110 move_it_vertically (it, target_y - it->current_y);
6111 xassert (IT_CHARPOS (*it) >= BEGV);
6112 }
6113 else if (target_y >= it->current_y + line_height
6114 && IT_CHARPOS (*it) < ZV)
6115 {
6116 /* Should move forward by at least one line, maybe more.
6117
6118 Note: Calling move_it_by_lines can be expensive on
6119 terminal frames, where compute_motion is used (via
6120 vmotion) to do the job, when there are very long lines
6121 and truncate-lines is nil. That's the reason for
6122 treating terminal frames specially here. */
6123
6124 if (!FRAME_WINDOW_P (it->f))
6125 move_it_vertically (it, target_y - (it->current_y + line_height));
6126 else
6127 {
6128 do
6129 {
6130 move_it_by_lines (it, 1, 1);
6131 }
6132 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6133 }
6134
6135 xassert (IT_CHARPOS (*it) >= BEGV);
6136 }
6137 }
6138 }
6139
6140
6141 /* Move IT by a specified amount of pixel lines DY. DY negative means
6142 move backwards. DY = 0 means move to start of screen line. At the
6143 end, IT will be on the start of a screen line. */
6144
6145 void
6146 move_it_vertically (it, dy)
6147 struct it *it;
6148 int dy;
6149 {
6150 if (dy <= 0)
6151 move_it_vertically_backward (it, -dy);
6152 else if (dy > 0)
6153 {
6154 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6155 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6156 MOVE_TO_POS | MOVE_TO_Y);
6157 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6158
6159 /* If buffer ends in ZV without a newline, move to the start of
6160 the line to satisfy the post-condition. */
6161 if (IT_CHARPOS (*it) == ZV
6162 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6163 move_it_by_lines (it, 0, 0);
6164 }
6165 }
6166
6167
6168 /* Move iterator IT past the end of the text line it is in. */
6169
6170 void
6171 move_it_past_eol (it)
6172 struct it *it;
6173 {
6174 enum move_it_result rc;
6175
6176 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6177 if (rc == MOVE_NEWLINE_OR_CR)
6178 set_iterator_to_next (it, 0);
6179 }
6180
6181
6182 #if 0 /* Currently not used. */
6183
6184 /* Return non-zero if some text between buffer positions START_CHARPOS
6185 and END_CHARPOS is invisible. IT->window is the window for text
6186 property lookup. */
6187
6188 static int
6189 invisible_text_between_p (it, start_charpos, end_charpos)
6190 struct it *it;
6191 int start_charpos, end_charpos;
6192 {
6193 Lisp_Object prop, limit;
6194 int invisible_found_p;
6195
6196 xassert (it != NULL && start_charpos <= end_charpos);
6197
6198 /* Is text at START invisible? */
6199 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6200 it->window);
6201 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6202 invisible_found_p = 1;
6203 else
6204 {
6205 limit = Fnext_single_char_property_change (make_number (start_charpos),
6206 Qinvisible, Qnil,
6207 make_number (end_charpos));
6208 invisible_found_p = XFASTINT (limit) < end_charpos;
6209 }
6210
6211 return invisible_found_p;
6212 }
6213
6214 #endif /* 0 */
6215
6216
6217 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6218 negative means move up. DVPOS == 0 means move to the start of the
6219 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6220 NEED_Y_P is zero, IT->current_y will be left unchanged.
6221
6222 Further optimization ideas: If we would know that IT->f doesn't use
6223 a face with proportional font, we could be faster for
6224 truncate-lines nil. */
6225
6226 void
6227 move_it_by_lines (it, dvpos, need_y_p)
6228 struct it *it;
6229 int dvpos, need_y_p;
6230 {
6231 struct position pos;
6232
6233 if (!FRAME_WINDOW_P (it->f))
6234 {
6235 struct text_pos textpos;
6236
6237 /* We can use vmotion on frames without proportional fonts. */
6238 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6239 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6240 reseat (it, textpos, 1);
6241 it->vpos += pos.vpos;
6242 it->current_y += pos.vpos;
6243 }
6244 else if (dvpos == 0)
6245 {
6246 /* DVPOS == 0 means move to the start of the screen line. */
6247 move_it_vertically_backward (it, 0);
6248 xassert (it->current_x == 0 && it->hpos == 0);
6249 }
6250 else if (dvpos > 0)
6251 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6252 else
6253 {
6254 struct it it2;
6255 int start_charpos, i;
6256
6257 /* Start at the beginning of the screen line containing IT's
6258 position. */
6259 move_it_vertically_backward (it, 0);
6260
6261 /* Go back -DVPOS visible lines and reseat the iterator there. */
6262 start_charpos = IT_CHARPOS (*it);
6263 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6264 back_to_previous_visible_line_start (it);
6265 reseat (it, it->current.pos, 1);
6266 it->current_x = it->hpos = 0;
6267
6268 /* Above call may have moved too far if continuation lines
6269 are involved. Scan forward and see if it did. */
6270 it2 = *it;
6271 it2.vpos = it2.current_y = 0;
6272 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6273 it->vpos -= it2.vpos;
6274 it->current_y -= it2.current_y;
6275 it->current_x = it->hpos = 0;
6276
6277 /* If we moved too far, move IT some lines forward. */
6278 if (it2.vpos > -dvpos)
6279 {
6280 int delta = it2.vpos + dvpos;
6281 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6282 }
6283 }
6284 }
6285
6286 /* Return 1 if IT points into the middle of a display vector. */
6287
6288 int
6289 in_display_vector_p (it)
6290 struct it *it;
6291 {
6292 return (it->method == next_element_from_display_vector
6293 && it->current.dpvec_index > 0
6294 && it->dpvec + it->current.dpvec_index != it->dpend);
6295 }
6296
6297 \f
6298 /***********************************************************************
6299 Messages
6300 ***********************************************************************/
6301
6302
6303 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6304 to *Messages*. */
6305
6306 void
6307 add_to_log (format, arg1, arg2)
6308 char *format;
6309 Lisp_Object arg1, arg2;
6310 {
6311 Lisp_Object args[3];
6312 Lisp_Object msg, fmt;
6313 char *buffer;
6314 int len;
6315 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6316
6317 /* Do nothing if called asynchronously. Inserting text into
6318 a buffer may call after-change-functions and alike and
6319 that would means running Lisp asynchronously. */
6320 if (handling_signal)
6321 return;
6322
6323 fmt = msg = Qnil;
6324 GCPRO4 (fmt, msg, arg1, arg2);
6325
6326 args[0] = fmt = build_string (format);
6327 args[1] = arg1;
6328 args[2] = arg2;
6329 msg = Fformat (3, args);
6330
6331 len = SBYTES (msg) + 1;
6332 buffer = (char *) alloca (len);
6333 bcopy (SDATA (msg), buffer, len);
6334
6335 message_dolog (buffer, len - 1, 1, 0);
6336 UNGCPRO;
6337 }
6338
6339
6340 /* Output a newline in the *Messages* buffer if "needs" one. */
6341
6342 void
6343 message_log_maybe_newline ()
6344 {
6345 if (message_log_need_newline)
6346 message_dolog ("", 0, 1, 0);
6347 }
6348
6349
6350 /* Add a string M of length NBYTES to the message log, optionally
6351 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6352 nonzero, means interpret the contents of M as multibyte. This
6353 function calls low-level routines in order to bypass text property
6354 hooks, etc. which might not be safe to run. */
6355
6356 void
6357 message_dolog (m, nbytes, nlflag, multibyte)
6358 const char *m;
6359 int nbytes, nlflag, multibyte;
6360 {
6361 if (!NILP (Vmemory_full))
6362 return;
6363
6364 if (!NILP (Vmessage_log_max))
6365 {
6366 struct buffer *oldbuf;
6367 Lisp_Object oldpoint, oldbegv, oldzv;
6368 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6369 int point_at_end = 0;
6370 int zv_at_end = 0;
6371 Lisp_Object old_deactivate_mark, tem;
6372 struct gcpro gcpro1;
6373
6374 old_deactivate_mark = Vdeactivate_mark;
6375 oldbuf = current_buffer;
6376 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6377 current_buffer->undo_list = Qt;
6378
6379 oldpoint = message_dolog_marker1;
6380 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6381 oldbegv = message_dolog_marker2;
6382 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6383 oldzv = message_dolog_marker3;
6384 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6385 GCPRO1 (old_deactivate_mark);
6386
6387 if (PT == Z)
6388 point_at_end = 1;
6389 if (ZV == Z)
6390 zv_at_end = 1;
6391
6392 BEGV = BEG;
6393 BEGV_BYTE = BEG_BYTE;
6394 ZV = Z;
6395 ZV_BYTE = Z_BYTE;
6396 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6397
6398 /* Insert the string--maybe converting multibyte to single byte
6399 or vice versa, so that all the text fits the buffer. */
6400 if (multibyte
6401 && NILP (current_buffer->enable_multibyte_characters))
6402 {
6403 int i, c, char_bytes;
6404 unsigned char work[1];
6405
6406 /* Convert a multibyte string to single-byte
6407 for the *Message* buffer. */
6408 for (i = 0; i < nbytes; i += char_bytes)
6409 {
6410 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6411 work[0] = (SINGLE_BYTE_CHAR_P (c)
6412 ? c
6413 : multibyte_char_to_unibyte (c, Qnil));
6414 insert_1_both (work, 1, 1, 1, 0, 0);
6415 }
6416 }
6417 else if (! multibyte
6418 && ! NILP (current_buffer->enable_multibyte_characters))
6419 {
6420 int i, c, char_bytes;
6421 unsigned char *msg = (unsigned char *) m;
6422 unsigned char str[MAX_MULTIBYTE_LENGTH];
6423 /* Convert a single-byte string to multibyte
6424 for the *Message* buffer. */
6425 for (i = 0; i < nbytes; i++)
6426 {
6427 c = unibyte_char_to_multibyte (msg[i]);
6428 char_bytes = CHAR_STRING (c, str);
6429 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6430 }
6431 }
6432 else if (nbytes)
6433 insert_1 (m, nbytes, 1, 0, 0);
6434
6435 if (nlflag)
6436 {
6437 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6438 insert_1 ("\n", 1, 1, 0, 0);
6439
6440 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6441 this_bol = PT;
6442 this_bol_byte = PT_BYTE;
6443
6444 /* See if this line duplicates the previous one.
6445 If so, combine duplicates. */
6446 if (this_bol > BEG)
6447 {
6448 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6449 prev_bol = PT;
6450 prev_bol_byte = PT_BYTE;
6451
6452 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6453 this_bol, this_bol_byte);
6454 if (dup)
6455 {
6456 del_range_both (prev_bol, prev_bol_byte,
6457 this_bol, this_bol_byte, 0);
6458 if (dup > 1)
6459 {
6460 char dupstr[40];
6461 int duplen;
6462
6463 /* If you change this format, don't forget to also
6464 change message_log_check_duplicate. */
6465 sprintf (dupstr, " [%d times]", dup);
6466 duplen = strlen (dupstr);
6467 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6468 insert_1 (dupstr, duplen, 1, 0, 1);
6469 }
6470 }
6471 }
6472
6473 /* If we have more than the desired maximum number of lines
6474 in the *Messages* buffer now, delete the oldest ones.
6475 This is safe because we don't have undo in this buffer. */
6476
6477 if (NATNUMP (Vmessage_log_max))
6478 {
6479 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6480 -XFASTINT (Vmessage_log_max) - 1, 0);
6481 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6482 }
6483 }
6484 BEGV = XMARKER (oldbegv)->charpos;
6485 BEGV_BYTE = marker_byte_position (oldbegv);
6486
6487 if (zv_at_end)
6488 {
6489 ZV = Z;
6490 ZV_BYTE = Z_BYTE;
6491 }
6492 else
6493 {
6494 ZV = XMARKER (oldzv)->charpos;
6495 ZV_BYTE = marker_byte_position (oldzv);
6496 }
6497
6498 if (point_at_end)
6499 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6500 else
6501 /* We can't do Fgoto_char (oldpoint) because it will run some
6502 Lisp code. */
6503 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6504 XMARKER (oldpoint)->bytepos);
6505
6506 UNGCPRO;
6507 unchain_marker (XMARKER (oldpoint));
6508 unchain_marker (XMARKER (oldbegv));
6509 unchain_marker (XMARKER (oldzv));
6510
6511 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6512 set_buffer_internal (oldbuf);
6513 if (NILP (tem))
6514 windows_or_buffers_changed = old_windows_or_buffers_changed;
6515 message_log_need_newline = !nlflag;
6516 Vdeactivate_mark = old_deactivate_mark;
6517 }
6518 }
6519
6520
6521 /* We are at the end of the buffer after just having inserted a newline.
6522 (Note: We depend on the fact we won't be crossing the gap.)
6523 Check to see if the most recent message looks a lot like the previous one.
6524 Return 0 if different, 1 if the new one should just replace it, or a
6525 value N > 1 if we should also append " [N times]". */
6526
6527 static int
6528 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6529 int prev_bol, this_bol;
6530 int prev_bol_byte, this_bol_byte;
6531 {
6532 int i;
6533 int len = Z_BYTE - 1 - this_bol_byte;
6534 int seen_dots = 0;
6535 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6536 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6537
6538 for (i = 0; i < len; i++)
6539 {
6540 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6541 seen_dots = 1;
6542 if (p1[i] != p2[i])
6543 return seen_dots;
6544 }
6545 p1 += len;
6546 if (*p1 == '\n')
6547 return 2;
6548 if (*p1++ == ' ' && *p1++ == '[')
6549 {
6550 int n = 0;
6551 while (*p1 >= '0' && *p1 <= '9')
6552 n = n * 10 + *p1++ - '0';
6553 if (strncmp (p1, " times]\n", 8) == 0)
6554 return n+1;
6555 }
6556 return 0;
6557 }
6558
6559
6560 /* Display an echo area message M with a specified length of NBYTES
6561 bytes. The string may include null characters. If M is 0, clear
6562 out any existing message, and let the mini-buffer text show
6563 through.
6564
6565 The buffer M must continue to exist until after the echo area gets
6566 cleared or some other message gets displayed there. This means do
6567 not pass text that is stored in a Lisp string; do not pass text in
6568 a buffer that was alloca'd. */
6569
6570 void
6571 message2 (m, nbytes, multibyte)
6572 const char *m;
6573 int nbytes;
6574 int multibyte;
6575 {
6576 /* First flush out any partial line written with print. */
6577 message_log_maybe_newline ();
6578 if (m)
6579 message_dolog (m, nbytes, 1, multibyte);
6580 message2_nolog (m, nbytes, multibyte);
6581 }
6582
6583
6584 /* The non-logging counterpart of message2. */
6585
6586 void
6587 message2_nolog (m, nbytes, multibyte)
6588 const char *m;
6589 int nbytes, multibyte;
6590 {
6591 struct frame *sf = SELECTED_FRAME ();
6592 message_enable_multibyte = multibyte;
6593
6594 if (noninteractive)
6595 {
6596 if (noninteractive_need_newline)
6597 putc ('\n', stderr);
6598 noninteractive_need_newline = 0;
6599 if (m)
6600 fwrite (m, nbytes, 1, stderr);
6601 if (cursor_in_echo_area == 0)
6602 fprintf (stderr, "\n");
6603 fflush (stderr);
6604 }
6605 /* A null message buffer means that the frame hasn't really been
6606 initialized yet. Error messages get reported properly by
6607 cmd_error, so this must be just an informative message; toss it. */
6608 else if (INTERACTIVE
6609 && sf->glyphs_initialized_p
6610 && FRAME_MESSAGE_BUF (sf))
6611 {
6612 Lisp_Object mini_window;
6613 struct frame *f;
6614
6615 /* Get the frame containing the mini-buffer
6616 that the selected frame is using. */
6617 mini_window = FRAME_MINIBUF_WINDOW (sf);
6618 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6619
6620 FRAME_SAMPLE_VISIBILITY (f);
6621 if (FRAME_VISIBLE_P (sf)
6622 && ! FRAME_VISIBLE_P (f))
6623 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6624
6625 if (m)
6626 {
6627 set_message (m, Qnil, nbytes, multibyte);
6628 if (minibuffer_auto_raise)
6629 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6630 }
6631 else
6632 clear_message (1, 1);
6633
6634 do_pending_window_change (0);
6635 echo_area_display (1);
6636 do_pending_window_change (0);
6637 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6638 (*frame_up_to_date_hook) (f);
6639 }
6640 }
6641
6642
6643 /* Display an echo area message M with a specified length of NBYTES
6644 bytes. The string may include null characters. If M is not a
6645 string, clear out any existing message, and let the mini-buffer
6646 text show through. */
6647
6648 void
6649 message3 (m, nbytes, multibyte)
6650 Lisp_Object m;
6651 int nbytes;
6652 int multibyte;
6653 {
6654 struct gcpro gcpro1;
6655
6656 GCPRO1 (m);
6657
6658 /* First flush out any partial line written with print. */
6659 message_log_maybe_newline ();
6660 if (STRINGP (m))
6661 message_dolog (SDATA (m), nbytes, 1, multibyte);
6662 message3_nolog (m, nbytes, multibyte);
6663
6664 UNGCPRO;
6665 }
6666
6667
6668 /* The non-logging version of message3. */
6669
6670 void
6671 message3_nolog (m, nbytes, multibyte)
6672 Lisp_Object m;
6673 int nbytes, multibyte;
6674 {
6675 struct frame *sf = SELECTED_FRAME ();
6676 message_enable_multibyte = multibyte;
6677
6678 if (noninteractive)
6679 {
6680 if (noninteractive_need_newline)
6681 putc ('\n', stderr);
6682 noninteractive_need_newline = 0;
6683 if (STRINGP (m))
6684 fwrite (SDATA (m), nbytes, 1, stderr);
6685 if (cursor_in_echo_area == 0)
6686 fprintf (stderr, "\n");
6687 fflush (stderr);
6688 }
6689 /* A null message buffer means that the frame hasn't really been
6690 initialized yet. Error messages get reported properly by
6691 cmd_error, so this must be just an informative message; toss it. */
6692 else if (INTERACTIVE
6693 && sf->glyphs_initialized_p
6694 && FRAME_MESSAGE_BUF (sf))
6695 {
6696 Lisp_Object mini_window;
6697 Lisp_Object frame;
6698 struct frame *f;
6699
6700 /* Get the frame containing the mini-buffer
6701 that the selected frame is using. */
6702 mini_window = FRAME_MINIBUF_WINDOW (sf);
6703 frame = XWINDOW (mini_window)->frame;
6704 f = XFRAME (frame);
6705
6706 FRAME_SAMPLE_VISIBILITY (f);
6707 if (FRAME_VISIBLE_P (sf)
6708 && !FRAME_VISIBLE_P (f))
6709 Fmake_frame_visible (frame);
6710
6711 if (STRINGP (m) && SCHARS (m) > 0)
6712 {
6713 set_message (NULL, m, nbytes, multibyte);
6714 if (minibuffer_auto_raise)
6715 Fraise_frame (frame);
6716 }
6717 else
6718 clear_message (1, 1);
6719
6720 do_pending_window_change (0);
6721 echo_area_display (1);
6722 do_pending_window_change (0);
6723 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6724 (*frame_up_to_date_hook) (f);
6725 }
6726 }
6727
6728
6729 /* Display a null-terminated echo area message M. If M is 0, clear
6730 out any existing message, and let the mini-buffer text show through.
6731
6732 The buffer M must continue to exist until after the echo area gets
6733 cleared or some other message gets displayed there. Do not pass
6734 text that is stored in a Lisp string. Do not pass text in a buffer
6735 that was alloca'd. */
6736
6737 void
6738 message1 (m)
6739 char *m;
6740 {
6741 message2 (m, (m ? strlen (m) : 0), 0);
6742 }
6743
6744
6745 /* The non-logging counterpart of message1. */
6746
6747 void
6748 message1_nolog (m)
6749 char *m;
6750 {
6751 message2_nolog (m, (m ? strlen (m) : 0), 0);
6752 }
6753
6754 /* Display a message M which contains a single %s
6755 which gets replaced with STRING. */
6756
6757 void
6758 message_with_string (m, string, log)
6759 char *m;
6760 Lisp_Object string;
6761 int log;
6762 {
6763 CHECK_STRING (string);
6764
6765 if (noninteractive)
6766 {
6767 if (m)
6768 {
6769 if (noninteractive_need_newline)
6770 putc ('\n', stderr);
6771 noninteractive_need_newline = 0;
6772 fprintf (stderr, m, SDATA (string));
6773 if (cursor_in_echo_area == 0)
6774 fprintf (stderr, "\n");
6775 fflush (stderr);
6776 }
6777 }
6778 else if (INTERACTIVE)
6779 {
6780 /* The frame whose minibuffer we're going to display the message on.
6781 It may be larger than the selected frame, so we need
6782 to use its buffer, not the selected frame's buffer. */
6783 Lisp_Object mini_window;
6784 struct frame *f, *sf = SELECTED_FRAME ();
6785
6786 /* Get the frame containing the minibuffer
6787 that the selected frame is using. */
6788 mini_window = FRAME_MINIBUF_WINDOW (sf);
6789 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6790
6791 /* A null message buffer means that the frame hasn't really been
6792 initialized yet. Error messages get reported properly by
6793 cmd_error, so this must be just an informative message; toss it. */
6794 if (FRAME_MESSAGE_BUF (f))
6795 {
6796 Lisp_Object args[2], message;
6797 struct gcpro gcpro1, gcpro2;
6798
6799 args[0] = build_string (m);
6800 args[1] = message = string;
6801 GCPRO2 (args[0], message);
6802 gcpro1.nvars = 2;
6803
6804 message = Fformat (2, args);
6805
6806 if (log)
6807 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6808 else
6809 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6810
6811 UNGCPRO;
6812
6813 /* Print should start at the beginning of the message
6814 buffer next time. */
6815 message_buf_print = 0;
6816 }
6817 }
6818 }
6819
6820
6821 /* Dump an informative message to the minibuf. If M is 0, clear out
6822 any existing message, and let the mini-buffer text show through. */
6823
6824 /* VARARGS 1 */
6825 void
6826 message (m, a1, a2, a3)
6827 char *m;
6828 EMACS_INT a1, a2, a3;
6829 {
6830 if (noninteractive)
6831 {
6832 if (m)
6833 {
6834 if (noninteractive_need_newline)
6835 putc ('\n', stderr);
6836 noninteractive_need_newline = 0;
6837 fprintf (stderr, m, a1, a2, a3);
6838 if (cursor_in_echo_area == 0)
6839 fprintf (stderr, "\n");
6840 fflush (stderr);
6841 }
6842 }
6843 else if (INTERACTIVE)
6844 {
6845 /* The frame whose mini-buffer we're going to display the message
6846 on. It may be larger than the selected frame, so we need to
6847 use its buffer, not the selected frame's buffer. */
6848 Lisp_Object mini_window;
6849 struct frame *f, *sf = SELECTED_FRAME ();
6850
6851 /* Get the frame containing the mini-buffer
6852 that the selected frame is using. */
6853 mini_window = FRAME_MINIBUF_WINDOW (sf);
6854 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6855
6856 /* A null message buffer means that the frame hasn't really been
6857 initialized yet. Error messages get reported properly by
6858 cmd_error, so this must be just an informative message; toss
6859 it. */
6860 if (FRAME_MESSAGE_BUF (f))
6861 {
6862 if (m)
6863 {
6864 int len;
6865 #ifdef NO_ARG_ARRAY
6866 char *a[3];
6867 a[0] = (char *) a1;
6868 a[1] = (char *) a2;
6869 a[2] = (char *) a3;
6870
6871 len = doprnt (FRAME_MESSAGE_BUF (f),
6872 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6873 #else
6874 len = doprnt (FRAME_MESSAGE_BUF (f),
6875 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6876 (char **) &a1);
6877 #endif /* NO_ARG_ARRAY */
6878
6879 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6880 }
6881 else
6882 message1 (0);
6883
6884 /* Print should start at the beginning of the message
6885 buffer next time. */
6886 message_buf_print = 0;
6887 }
6888 }
6889 }
6890
6891
6892 /* The non-logging version of message. */
6893
6894 void
6895 message_nolog (m, a1, a2, a3)
6896 char *m;
6897 EMACS_INT a1, a2, a3;
6898 {
6899 Lisp_Object old_log_max;
6900 old_log_max = Vmessage_log_max;
6901 Vmessage_log_max = Qnil;
6902 message (m, a1, a2, a3);
6903 Vmessage_log_max = old_log_max;
6904 }
6905
6906
6907 /* Display the current message in the current mini-buffer. This is
6908 only called from error handlers in process.c, and is not time
6909 critical. */
6910
6911 void
6912 update_echo_area ()
6913 {
6914 if (!NILP (echo_area_buffer[0]))
6915 {
6916 Lisp_Object string;
6917 string = Fcurrent_message ();
6918 message3 (string, SBYTES (string),
6919 !NILP (current_buffer->enable_multibyte_characters));
6920 }
6921 }
6922
6923
6924 /* Make sure echo area buffers in `echo_buffers' are live.
6925 If they aren't, make new ones. */
6926
6927 static void
6928 ensure_echo_area_buffers ()
6929 {
6930 int i;
6931
6932 for (i = 0; i < 2; ++i)
6933 if (!BUFFERP (echo_buffer[i])
6934 || NILP (XBUFFER (echo_buffer[i])->name))
6935 {
6936 char name[30];
6937 Lisp_Object old_buffer;
6938 int j;
6939
6940 old_buffer = echo_buffer[i];
6941 sprintf (name, " *Echo Area %d*", i);
6942 echo_buffer[i] = Fget_buffer_create (build_string (name));
6943 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6944
6945 for (j = 0; j < 2; ++j)
6946 if (EQ (old_buffer, echo_area_buffer[j]))
6947 echo_area_buffer[j] = echo_buffer[i];
6948 }
6949 }
6950
6951
6952 /* Call FN with args A1..A4 with either the current or last displayed
6953 echo_area_buffer as current buffer.
6954
6955 WHICH zero means use the current message buffer
6956 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6957 from echo_buffer[] and clear it.
6958
6959 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6960 suitable buffer from echo_buffer[] and clear it.
6961
6962 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6963 that the current message becomes the last displayed one, make
6964 choose a suitable buffer for echo_area_buffer[0], and clear it.
6965
6966 Value is what FN returns. */
6967
6968 static int
6969 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6970 struct window *w;
6971 int which;
6972 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6973 EMACS_INT a1;
6974 Lisp_Object a2;
6975 EMACS_INT a3, a4;
6976 {
6977 Lisp_Object buffer;
6978 int this_one, the_other, clear_buffer_p, rc;
6979 int count = SPECPDL_INDEX ();
6980
6981 /* If buffers aren't live, make new ones. */
6982 ensure_echo_area_buffers ();
6983
6984 clear_buffer_p = 0;
6985
6986 if (which == 0)
6987 this_one = 0, the_other = 1;
6988 else if (which > 0)
6989 this_one = 1, the_other = 0;
6990 else
6991 {
6992 this_one = 0, the_other = 1;
6993 clear_buffer_p = 1;
6994
6995 /* We need a fresh one in case the current echo buffer equals
6996 the one containing the last displayed echo area message. */
6997 if (!NILP (echo_area_buffer[this_one])
6998 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6999 echo_area_buffer[this_one] = Qnil;
7000 }
7001
7002 /* Choose a suitable buffer from echo_buffer[] is we don't
7003 have one. */
7004 if (NILP (echo_area_buffer[this_one]))
7005 {
7006 echo_area_buffer[this_one]
7007 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7008 ? echo_buffer[the_other]
7009 : echo_buffer[this_one]);
7010 clear_buffer_p = 1;
7011 }
7012
7013 buffer = echo_area_buffer[this_one];
7014
7015 /* Don't get confused by reusing the buffer used for echoing
7016 for a different purpose. */
7017 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7018 cancel_echoing ();
7019
7020 record_unwind_protect (unwind_with_echo_area_buffer,
7021 with_echo_area_buffer_unwind_data (w));
7022
7023 /* Make the echo area buffer current. Note that for display
7024 purposes, it is not necessary that the displayed window's buffer
7025 == current_buffer, except for text property lookup. So, let's
7026 only set that buffer temporarily here without doing a full
7027 Fset_window_buffer. We must also change w->pointm, though,
7028 because otherwise an assertions in unshow_buffer fails, and Emacs
7029 aborts. */
7030 set_buffer_internal_1 (XBUFFER (buffer));
7031 if (w)
7032 {
7033 w->buffer = buffer;
7034 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7035 }
7036
7037 current_buffer->undo_list = Qt;
7038 current_buffer->read_only = Qnil;
7039 specbind (Qinhibit_read_only, Qt);
7040 specbind (Qinhibit_modification_hooks, Qt);
7041
7042 if (clear_buffer_p && Z > BEG)
7043 del_range (BEG, Z);
7044
7045 xassert (BEGV >= BEG);
7046 xassert (ZV <= Z && ZV >= BEGV);
7047
7048 rc = fn (a1, a2, a3, a4);
7049
7050 xassert (BEGV >= BEG);
7051 xassert (ZV <= Z && ZV >= BEGV);
7052
7053 unbind_to (count, Qnil);
7054 return rc;
7055 }
7056
7057
7058 /* Save state that should be preserved around the call to the function
7059 FN called in with_echo_area_buffer. */
7060
7061 static Lisp_Object
7062 with_echo_area_buffer_unwind_data (w)
7063 struct window *w;
7064 {
7065 int i = 0;
7066 Lisp_Object vector;
7067
7068 /* Reduce consing by keeping one vector in
7069 Vwith_echo_area_save_vector. */
7070 vector = Vwith_echo_area_save_vector;
7071 Vwith_echo_area_save_vector = Qnil;
7072
7073 if (NILP (vector))
7074 vector = Fmake_vector (make_number (7), Qnil);
7075
7076 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7077 AREF (vector, i) = Vdeactivate_mark, ++i;
7078 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7079
7080 if (w)
7081 {
7082 XSETWINDOW (AREF (vector, i), w); ++i;
7083 AREF (vector, i) = w->buffer; ++i;
7084 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7085 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7086 }
7087 else
7088 {
7089 int end = i + 4;
7090 for (; i < end; ++i)
7091 AREF (vector, i) = Qnil;
7092 }
7093
7094 xassert (i == ASIZE (vector));
7095 return vector;
7096 }
7097
7098
7099 /* Restore global state from VECTOR which was created by
7100 with_echo_area_buffer_unwind_data. */
7101
7102 static Lisp_Object
7103 unwind_with_echo_area_buffer (vector)
7104 Lisp_Object vector;
7105 {
7106 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7107 Vdeactivate_mark = AREF (vector, 1);
7108 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7109
7110 if (WINDOWP (AREF (vector, 3)))
7111 {
7112 struct window *w;
7113 Lisp_Object buffer, charpos, bytepos;
7114
7115 w = XWINDOW (AREF (vector, 3));
7116 buffer = AREF (vector, 4);
7117 charpos = AREF (vector, 5);
7118 bytepos = AREF (vector, 6);
7119
7120 w->buffer = buffer;
7121 set_marker_both (w->pointm, buffer,
7122 XFASTINT (charpos), XFASTINT (bytepos));
7123 }
7124
7125 Vwith_echo_area_save_vector = vector;
7126 return Qnil;
7127 }
7128
7129
7130 /* Set up the echo area for use by print functions. MULTIBYTE_P
7131 non-zero means we will print multibyte. */
7132
7133 void
7134 setup_echo_area_for_printing (multibyte_p)
7135 int multibyte_p;
7136 {
7137 /* If we can't find an echo area any more, exit. */
7138 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7139 Fkill_emacs (Qnil);
7140
7141 ensure_echo_area_buffers ();
7142
7143 if (!message_buf_print)
7144 {
7145 /* A message has been output since the last time we printed.
7146 Choose a fresh echo area buffer. */
7147 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7148 echo_area_buffer[0] = echo_buffer[1];
7149 else
7150 echo_area_buffer[0] = echo_buffer[0];
7151
7152 /* Switch to that buffer and clear it. */
7153 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7154 current_buffer->truncate_lines = Qnil;
7155
7156 if (Z > BEG)
7157 {
7158 int count = SPECPDL_INDEX ();
7159 specbind (Qinhibit_read_only, Qt);
7160 /* Note that undo recording is always disabled. */
7161 del_range (BEG, Z);
7162 unbind_to (count, Qnil);
7163 }
7164 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7165
7166 /* Set up the buffer for the multibyteness we need. */
7167 if (multibyte_p
7168 != !NILP (current_buffer->enable_multibyte_characters))
7169 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7170
7171 /* Raise the frame containing the echo area. */
7172 if (minibuffer_auto_raise)
7173 {
7174 struct frame *sf = SELECTED_FRAME ();
7175 Lisp_Object mini_window;
7176 mini_window = FRAME_MINIBUF_WINDOW (sf);
7177 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7178 }
7179
7180 message_log_maybe_newline ();
7181 message_buf_print = 1;
7182 }
7183 else
7184 {
7185 if (NILP (echo_area_buffer[0]))
7186 {
7187 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7188 echo_area_buffer[0] = echo_buffer[1];
7189 else
7190 echo_area_buffer[0] = echo_buffer[0];
7191 }
7192
7193 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7194 {
7195 /* Someone switched buffers between print requests. */
7196 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7197 current_buffer->truncate_lines = Qnil;
7198 }
7199 }
7200 }
7201
7202
7203 /* Display an echo area message in window W. Value is non-zero if W's
7204 height is changed. If display_last_displayed_message_p is
7205 non-zero, display the message that was last displayed, otherwise
7206 display the current message. */
7207
7208 static int
7209 display_echo_area (w)
7210 struct window *w;
7211 {
7212 int i, no_message_p, window_height_changed_p, count;
7213
7214 /* Temporarily disable garbage collections while displaying the echo
7215 area. This is done because a GC can print a message itself.
7216 That message would modify the echo area buffer's contents while a
7217 redisplay of the buffer is going on, and seriously confuse
7218 redisplay. */
7219 count = inhibit_garbage_collection ();
7220
7221 /* If there is no message, we must call display_echo_area_1
7222 nevertheless because it resizes the window. But we will have to
7223 reset the echo_area_buffer in question to nil at the end because
7224 with_echo_area_buffer will sets it to an empty buffer. */
7225 i = display_last_displayed_message_p ? 1 : 0;
7226 no_message_p = NILP (echo_area_buffer[i]);
7227
7228 window_height_changed_p
7229 = with_echo_area_buffer (w, display_last_displayed_message_p,
7230 display_echo_area_1,
7231 (EMACS_INT) w, Qnil, 0, 0);
7232
7233 if (no_message_p)
7234 echo_area_buffer[i] = Qnil;
7235
7236 unbind_to (count, Qnil);
7237 return window_height_changed_p;
7238 }
7239
7240
7241 /* Helper for display_echo_area. Display the current buffer which
7242 contains the current echo area message in window W, a mini-window,
7243 a pointer to which is passed in A1. A2..A4 are currently not used.
7244 Change the height of W so that all of the message is displayed.
7245 Value is non-zero if height of W was changed. */
7246
7247 static int
7248 display_echo_area_1 (a1, a2, a3, a4)
7249 EMACS_INT a1;
7250 Lisp_Object a2;
7251 EMACS_INT a3, a4;
7252 {
7253 struct window *w = (struct window *) a1;
7254 Lisp_Object window;
7255 struct text_pos start;
7256 int window_height_changed_p = 0;
7257
7258 /* Do this before displaying, so that we have a large enough glyph
7259 matrix for the display. */
7260 window_height_changed_p = resize_mini_window (w, 0);
7261
7262 /* Display. */
7263 clear_glyph_matrix (w->desired_matrix);
7264 XSETWINDOW (window, w);
7265 SET_TEXT_POS (start, BEG, BEG_BYTE);
7266 try_window (window, start);
7267
7268 return window_height_changed_p;
7269 }
7270
7271
7272 /* Resize the echo area window to exactly the size needed for the
7273 currently displayed message, if there is one. If a mini-buffer
7274 is active, don't shrink it. */
7275
7276 void
7277 resize_echo_area_exactly ()
7278 {
7279 if (BUFFERP (echo_area_buffer[0])
7280 && WINDOWP (echo_area_window))
7281 {
7282 struct window *w = XWINDOW (echo_area_window);
7283 int resized_p;
7284 Lisp_Object resize_exactly;
7285
7286 if (minibuf_level == 0)
7287 resize_exactly = Qt;
7288 else
7289 resize_exactly = Qnil;
7290
7291 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7292 (EMACS_INT) w, resize_exactly, 0, 0);
7293 if (resized_p)
7294 {
7295 ++windows_or_buffers_changed;
7296 ++update_mode_lines;
7297 redisplay_internal (0);
7298 }
7299 }
7300 }
7301
7302
7303 /* Callback function for with_echo_area_buffer, when used from
7304 resize_echo_area_exactly. A1 contains a pointer to the window to
7305 resize, EXACTLY non-nil means resize the mini-window exactly to the
7306 size of the text displayed. A3 and A4 are not used. Value is what
7307 resize_mini_window returns. */
7308
7309 static int
7310 resize_mini_window_1 (a1, exactly, a3, a4)
7311 EMACS_INT a1;
7312 Lisp_Object exactly;
7313 EMACS_INT a3, a4;
7314 {
7315 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7316 }
7317
7318
7319 /* Resize mini-window W to fit the size of its contents. EXACT:P
7320 means size the window exactly to the size needed. Otherwise, it's
7321 only enlarged until W's buffer is empty. Value is non-zero if
7322 the window height has been changed. */
7323
7324 int
7325 resize_mini_window (w, exact_p)
7326 struct window *w;
7327 int exact_p;
7328 {
7329 struct frame *f = XFRAME (w->frame);
7330 int window_height_changed_p = 0;
7331
7332 xassert (MINI_WINDOW_P (w));
7333
7334 /* Don't resize windows while redisplaying a window; it would
7335 confuse redisplay functions when the size of the window they are
7336 displaying changes from under them. Such a resizing can happen,
7337 for instance, when which-func prints a long message while
7338 we are running fontification-functions. We're running these
7339 functions with safe_call which binds inhibit-redisplay to t. */
7340 if (!NILP (Vinhibit_redisplay))
7341 return 0;
7342
7343 /* Nil means don't try to resize. */
7344 if (NILP (Vresize_mini_windows)
7345 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7346 return 0;
7347
7348 if (!FRAME_MINIBUF_ONLY_P (f))
7349 {
7350 struct it it;
7351 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7352 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7353 int height, max_height;
7354 int unit = FRAME_LINE_HEIGHT (f);
7355 struct text_pos start;
7356 struct buffer *old_current_buffer = NULL;
7357
7358 if (current_buffer != XBUFFER (w->buffer))
7359 {
7360 old_current_buffer = current_buffer;
7361 set_buffer_internal (XBUFFER (w->buffer));
7362 }
7363
7364 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7365
7366 /* Compute the max. number of lines specified by the user. */
7367 if (FLOATP (Vmax_mini_window_height))
7368 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7369 else if (INTEGERP (Vmax_mini_window_height))
7370 max_height = XINT (Vmax_mini_window_height);
7371 else
7372 max_height = total_height / 4;
7373
7374 /* Correct that max. height if it's bogus. */
7375 max_height = max (1, max_height);
7376 max_height = min (total_height, max_height);
7377
7378 /* Find out the height of the text in the window. */
7379 if (it.truncate_lines_p)
7380 height = 1;
7381 else
7382 {
7383 last_height = 0;
7384 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7385 if (it.max_ascent == 0 && it.max_descent == 0)
7386 height = it.current_y + last_height;
7387 else
7388 height = it.current_y + it.max_ascent + it.max_descent;
7389 height -= it.extra_line_spacing;
7390 height = (height + unit - 1) / unit;
7391 }
7392
7393 /* Compute a suitable window start. */
7394 if (height > max_height)
7395 {
7396 height = max_height;
7397 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7398 move_it_vertically_backward (&it, (height - 1) * unit);
7399 start = it.current.pos;
7400 }
7401 else
7402 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7403 SET_MARKER_FROM_TEXT_POS (w->start, start);
7404
7405 if (EQ (Vresize_mini_windows, Qgrow_only))
7406 {
7407 /* Let it grow only, until we display an empty message, in which
7408 case the window shrinks again. */
7409 if (height > WINDOW_TOTAL_LINES (w))
7410 {
7411 int old_height = WINDOW_TOTAL_LINES (w);
7412 freeze_window_starts (f, 1);
7413 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7414 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7415 }
7416 else if (height < WINDOW_TOTAL_LINES (w)
7417 && (exact_p || BEGV == ZV))
7418 {
7419 int old_height = WINDOW_TOTAL_LINES (w);
7420 freeze_window_starts (f, 0);
7421 shrink_mini_window (w);
7422 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7423 }
7424 }
7425 else
7426 {
7427 /* Always resize to exact size needed. */
7428 if (height > WINDOW_TOTAL_LINES (w))
7429 {
7430 int old_height = WINDOW_TOTAL_LINES (w);
7431 freeze_window_starts (f, 1);
7432 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7433 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7434 }
7435 else if (height < WINDOW_TOTAL_LINES (w))
7436 {
7437 int old_height = WINDOW_TOTAL_LINES (w);
7438 freeze_window_starts (f, 0);
7439 shrink_mini_window (w);
7440
7441 if (height)
7442 {
7443 freeze_window_starts (f, 1);
7444 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7445 }
7446
7447 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7448 }
7449 }
7450
7451 if (old_current_buffer)
7452 set_buffer_internal (old_current_buffer);
7453 }
7454
7455 return window_height_changed_p;
7456 }
7457
7458
7459 /* Value is the current message, a string, or nil if there is no
7460 current message. */
7461
7462 Lisp_Object
7463 current_message ()
7464 {
7465 Lisp_Object msg;
7466
7467 if (NILP (echo_area_buffer[0]))
7468 msg = Qnil;
7469 else
7470 {
7471 with_echo_area_buffer (0, 0, current_message_1,
7472 (EMACS_INT) &msg, Qnil, 0, 0);
7473 if (NILP (msg))
7474 echo_area_buffer[0] = Qnil;
7475 }
7476
7477 return msg;
7478 }
7479
7480
7481 static int
7482 current_message_1 (a1, a2, a3, a4)
7483 EMACS_INT a1;
7484 Lisp_Object a2;
7485 EMACS_INT a3, a4;
7486 {
7487 Lisp_Object *msg = (Lisp_Object *) a1;
7488
7489 if (Z > BEG)
7490 *msg = make_buffer_string (BEG, Z, 1);
7491 else
7492 *msg = Qnil;
7493 return 0;
7494 }
7495
7496
7497 /* Push the current message on Vmessage_stack for later restauration
7498 by restore_message. Value is non-zero if the current message isn't
7499 empty. This is a relatively infrequent operation, so it's not
7500 worth optimizing. */
7501
7502 int
7503 push_message ()
7504 {
7505 Lisp_Object msg;
7506 msg = current_message ();
7507 Vmessage_stack = Fcons (msg, Vmessage_stack);
7508 return STRINGP (msg);
7509 }
7510
7511
7512 /* Restore message display from the top of Vmessage_stack. */
7513
7514 void
7515 restore_message ()
7516 {
7517 Lisp_Object msg;
7518
7519 xassert (CONSP (Vmessage_stack));
7520 msg = XCAR (Vmessage_stack);
7521 if (STRINGP (msg))
7522 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7523 else
7524 message3_nolog (msg, 0, 0);
7525 }
7526
7527
7528 /* Handler for record_unwind_protect calling pop_message. */
7529
7530 Lisp_Object
7531 pop_message_unwind (dummy)
7532 Lisp_Object dummy;
7533 {
7534 pop_message ();
7535 return Qnil;
7536 }
7537
7538 /* Pop the top-most entry off Vmessage_stack. */
7539
7540 void
7541 pop_message ()
7542 {
7543 xassert (CONSP (Vmessage_stack));
7544 Vmessage_stack = XCDR (Vmessage_stack);
7545 }
7546
7547
7548 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7549 exits. If the stack is not empty, we have a missing pop_message
7550 somewhere. */
7551
7552 void
7553 check_message_stack ()
7554 {
7555 if (!NILP (Vmessage_stack))
7556 abort ();
7557 }
7558
7559
7560 /* Truncate to NCHARS what will be displayed in the echo area the next
7561 time we display it---but don't redisplay it now. */
7562
7563 void
7564 truncate_echo_area (nchars)
7565 int nchars;
7566 {
7567 if (nchars == 0)
7568 echo_area_buffer[0] = Qnil;
7569 /* A null message buffer means that the frame hasn't really been
7570 initialized yet. Error messages get reported properly by
7571 cmd_error, so this must be just an informative message; toss it. */
7572 else if (!noninteractive
7573 && INTERACTIVE
7574 && !NILP (echo_area_buffer[0]))
7575 {
7576 struct frame *sf = SELECTED_FRAME ();
7577 if (FRAME_MESSAGE_BUF (sf))
7578 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7579 }
7580 }
7581
7582
7583 /* Helper function for truncate_echo_area. Truncate the current
7584 message to at most NCHARS characters. */
7585
7586 static int
7587 truncate_message_1 (nchars, a2, a3, a4)
7588 EMACS_INT nchars;
7589 Lisp_Object a2;
7590 EMACS_INT a3, a4;
7591 {
7592 if (BEG + nchars < Z)
7593 del_range (BEG + nchars, Z);
7594 if (Z == BEG)
7595 echo_area_buffer[0] = Qnil;
7596 return 0;
7597 }
7598
7599
7600 /* Set the current message to a substring of S or STRING.
7601
7602 If STRING is a Lisp string, set the message to the first NBYTES
7603 bytes from STRING. NBYTES zero means use the whole string. If
7604 STRING is multibyte, the message will be displayed multibyte.
7605
7606 If S is not null, set the message to the first LEN bytes of S. LEN
7607 zero means use the whole string. MULTIBYTE_P non-zero means S is
7608 multibyte. Display the message multibyte in that case. */
7609
7610 void
7611 set_message (s, string, nbytes, multibyte_p)
7612 const char *s;
7613 Lisp_Object string;
7614 int nbytes, multibyte_p;
7615 {
7616 message_enable_multibyte
7617 = ((s && multibyte_p)
7618 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7619
7620 with_echo_area_buffer (0, -1, set_message_1,
7621 (EMACS_INT) s, string, nbytes, multibyte_p);
7622 message_buf_print = 0;
7623 help_echo_showing_p = 0;
7624 }
7625
7626
7627 /* Helper function for set_message. Arguments have the same meaning
7628 as there, with A1 corresponding to S and A2 corresponding to STRING
7629 This function is called with the echo area buffer being
7630 current. */
7631
7632 static int
7633 set_message_1 (a1, a2, nbytes, multibyte_p)
7634 EMACS_INT a1;
7635 Lisp_Object a2;
7636 EMACS_INT nbytes, multibyte_p;
7637 {
7638 const char *s = (const char *) a1;
7639 Lisp_Object string = a2;
7640
7641 xassert (BEG == Z);
7642
7643 /* Change multibyteness of the echo buffer appropriately. */
7644 if (message_enable_multibyte
7645 != !NILP (current_buffer->enable_multibyte_characters))
7646 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7647
7648 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7649
7650 /* Insert new message at BEG. */
7651 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7652
7653 if (STRINGP (string))
7654 {
7655 int nchars;
7656
7657 if (nbytes == 0)
7658 nbytes = SBYTES (string);
7659 nchars = string_byte_to_char (string, nbytes);
7660
7661 /* This function takes care of single/multibyte conversion. We
7662 just have to ensure that the echo area buffer has the right
7663 setting of enable_multibyte_characters. */
7664 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7665 }
7666 else if (s)
7667 {
7668 if (nbytes == 0)
7669 nbytes = strlen (s);
7670
7671 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7672 {
7673 /* Convert from multi-byte to single-byte. */
7674 int i, c, n;
7675 unsigned char work[1];
7676
7677 /* Convert a multibyte string to single-byte. */
7678 for (i = 0; i < nbytes; i += n)
7679 {
7680 c = string_char_and_length (s + i, nbytes - i, &n);
7681 work[0] = (SINGLE_BYTE_CHAR_P (c)
7682 ? c
7683 : multibyte_char_to_unibyte (c, Qnil));
7684 insert_1_both (work, 1, 1, 1, 0, 0);
7685 }
7686 }
7687 else if (!multibyte_p
7688 && !NILP (current_buffer->enable_multibyte_characters))
7689 {
7690 /* Convert from single-byte to multi-byte. */
7691 int i, c, n;
7692 const unsigned char *msg = (const unsigned char *) s;
7693 unsigned char str[MAX_MULTIBYTE_LENGTH];
7694
7695 /* Convert a single-byte string to multibyte. */
7696 for (i = 0; i < nbytes; i++)
7697 {
7698 c = unibyte_char_to_multibyte (msg[i]);
7699 n = CHAR_STRING (c, str);
7700 insert_1_both (str, 1, n, 1, 0, 0);
7701 }
7702 }
7703 else
7704 insert_1 (s, nbytes, 1, 0, 0);
7705 }
7706
7707 return 0;
7708 }
7709
7710
7711 /* Clear messages. CURRENT_P non-zero means clear the current
7712 message. LAST_DISPLAYED_P non-zero means clear the message
7713 last displayed. */
7714
7715 void
7716 clear_message (current_p, last_displayed_p)
7717 int current_p, last_displayed_p;
7718 {
7719 if (current_p)
7720 {
7721 echo_area_buffer[0] = Qnil;
7722 message_cleared_p = 1;
7723 }
7724
7725 if (last_displayed_p)
7726 echo_area_buffer[1] = Qnil;
7727
7728 message_buf_print = 0;
7729 }
7730
7731 /* Clear garbaged frames.
7732
7733 This function is used where the old redisplay called
7734 redraw_garbaged_frames which in turn called redraw_frame which in
7735 turn called clear_frame. The call to clear_frame was a source of
7736 flickering. I believe a clear_frame is not necessary. It should
7737 suffice in the new redisplay to invalidate all current matrices,
7738 and ensure a complete redisplay of all windows. */
7739
7740 static void
7741 clear_garbaged_frames ()
7742 {
7743 if (frame_garbaged)
7744 {
7745 Lisp_Object tail, frame;
7746 int changed_count = 0;
7747
7748 FOR_EACH_FRAME (tail, frame)
7749 {
7750 struct frame *f = XFRAME (frame);
7751
7752 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7753 {
7754 if (f->resized_p)
7755 {
7756 Fredraw_frame (frame);
7757 f->force_flush_display_p = 1;
7758 }
7759 clear_current_matrices (f);
7760 changed_count++;
7761 f->garbaged = 0;
7762 f->resized_p = 0;
7763 }
7764 }
7765
7766 frame_garbaged = 0;
7767 if (changed_count)
7768 ++windows_or_buffers_changed;
7769 }
7770 }
7771
7772
7773 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7774 is non-zero update selected_frame. Value is non-zero if the
7775 mini-windows height has been changed. */
7776
7777 static int
7778 echo_area_display (update_frame_p)
7779 int update_frame_p;
7780 {
7781 Lisp_Object mini_window;
7782 struct window *w;
7783 struct frame *f;
7784 int window_height_changed_p = 0;
7785 struct frame *sf = SELECTED_FRAME ();
7786
7787 mini_window = FRAME_MINIBUF_WINDOW (sf);
7788 w = XWINDOW (mini_window);
7789 f = XFRAME (WINDOW_FRAME (w));
7790
7791 /* Don't display if frame is invisible or not yet initialized. */
7792 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7793 return 0;
7794
7795 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7796 #ifndef MAC_OS8
7797 #ifdef HAVE_WINDOW_SYSTEM
7798 /* When Emacs starts, selected_frame may be a visible terminal
7799 frame, even if we run under a window system. If we let this
7800 through, a message would be displayed on the terminal. */
7801 if (EQ (selected_frame, Vterminal_frame)
7802 && !NILP (Vwindow_system))
7803 return 0;
7804 #endif /* HAVE_WINDOW_SYSTEM */
7805 #endif
7806
7807 /* Redraw garbaged frames. */
7808 if (frame_garbaged)
7809 clear_garbaged_frames ();
7810
7811 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7812 {
7813 echo_area_window = mini_window;
7814 window_height_changed_p = display_echo_area (w);
7815 w->must_be_updated_p = 1;
7816
7817 /* Update the display, unless called from redisplay_internal.
7818 Also don't update the screen during redisplay itself. The
7819 update will happen at the end of redisplay, and an update
7820 here could cause confusion. */
7821 if (update_frame_p && !redisplaying_p)
7822 {
7823 int n = 0;
7824
7825 /* If the display update has been interrupted by pending
7826 input, update mode lines in the frame. Due to the
7827 pending input, it might have been that redisplay hasn't
7828 been called, so that mode lines above the echo area are
7829 garbaged. This looks odd, so we prevent it here. */
7830 if (!display_completed)
7831 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7832
7833 if (window_height_changed_p
7834 /* Don't do this if Emacs is shutting down. Redisplay
7835 needs to run hooks. */
7836 && !NILP (Vrun_hooks))
7837 {
7838 /* Must update other windows. Likewise as in other
7839 cases, don't let this update be interrupted by
7840 pending input. */
7841 int count = SPECPDL_INDEX ();
7842 specbind (Qredisplay_dont_pause, Qt);
7843 windows_or_buffers_changed = 1;
7844 redisplay_internal (0);
7845 unbind_to (count, Qnil);
7846 }
7847 else if (FRAME_WINDOW_P (f) && n == 0)
7848 {
7849 /* Window configuration is the same as before.
7850 Can do with a display update of the echo area,
7851 unless we displayed some mode lines. */
7852 update_single_window (w, 1);
7853 rif->flush_display (f);
7854 }
7855 else
7856 update_frame (f, 1, 1);
7857
7858 /* If cursor is in the echo area, make sure that the next
7859 redisplay displays the minibuffer, so that the cursor will
7860 be replaced with what the minibuffer wants. */
7861 if (cursor_in_echo_area)
7862 ++windows_or_buffers_changed;
7863 }
7864 }
7865 else if (!EQ (mini_window, selected_window))
7866 windows_or_buffers_changed++;
7867
7868 /* Last displayed message is now the current message. */
7869 echo_area_buffer[1] = echo_area_buffer[0];
7870
7871 /* Prevent redisplay optimization in redisplay_internal by resetting
7872 this_line_start_pos. This is done because the mini-buffer now
7873 displays the message instead of its buffer text. */
7874 if (EQ (mini_window, selected_window))
7875 CHARPOS (this_line_start_pos) = 0;
7876
7877 return window_height_changed_p;
7878 }
7879
7880
7881 \f
7882 /***********************************************************************
7883 Frame Titles
7884 ***********************************************************************/
7885
7886
7887 /* The frame title buffering code is also used by Fformat_mode_line.
7888 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7889
7890 /* A buffer for constructing frame titles in it; allocated from the
7891 heap in init_xdisp and resized as needed in store_frame_title_char. */
7892
7893 static char *frame_title_buf;
7894
7895 /* The buffer's end, and a current output position in it. */
7896
7897 static char *frame_title_buf_end;
7898 static char *frame_title_ptr;
7899
7900
7901 /* Store a single character C for the frame title in frame_title_buf.
7902 Re-allocate frame_title_buf if necessary. */
7903
7904 static void
7905 #ifdef PROTOTYPES
7906 store_frame_title_char (char c)
7907 #else
7908 store_frame_title_char (c)
7909 char c;
7910 #endif
7911 {
7912 /* If output position has reached the end of the allocated buffer,
7913 double the buffer's size. */
7914 if (frame_title_ptr == frame_title_buf_end)
7915 {
7916 int len = frame_title_ptr - frame_title_buf;
7917 int new_size = 2 * len * sizeof *frame_title_buf;
7918 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7919 frame_title_buf_end = frame_title_buf + new_size;
7920 frame_title_ptr = frame_title_buf + len;
7921 }
7922
7923 *frame_title_ptr++ = c;
7924 }
7925
7926
7927 /* Store part of a frame title in frame_title_buf, beginning at
7928 frame_title_ptr. STR is the string to store. Do not copy
7929 characters that yield more columns than PRECISION; PRECISION <= 0
7930 means copy the whole string. Pad with spaces until FIELD_WIDTH
7931 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7932 pad. Called from display_mode_element when it is used to build a
7933 frame title. */
7934
7935 static int
7936 store_frame_title (str, field_width, precision)
7937 const unsigned char *str;
7938 int field_width, precision;
7939 {
7940 int n = 0;
7941 int dummy, nbytes;
7942
7943 /* Copy at most PRECISION chars from STR. */
7944 nbytes = strlen (str);
7945 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7946 while (nbytes--)
7947 store_frame_title_char (*str++);
7948
7949 /* Fill up with spaces until FIELD_WIDTH reached. */
7950 while (field_width > 0
7951 && n < field_width)
7952 {
7953 store_frame_title_char (' ');
7954 ++n;
7955 }
7956
7957 return n;
7958 }
7959
7960 #ifdef HAVE_WINDOW_SYSTEM
7961
7962 /* Set the title of FRAME, if it has changed. The title format is
7963 Vicon_title_format if FRAME is iconified, otherwise it is
7964 frame_title_format. */
7965
7966 static void
7967 x_consider_frame_title (frame)
7968 Lisp_Object frame;
7969 {
7970 struct frame *f = XFRAME (frame);
7971
7972 if (FRAME_WINDOW_P (f)
7973 || FRAME_MINIBUF_ONLY_P (f)
7974 || f->explicit_name)
7975 {
7976 /* Do we have more than one visible frame on this X display? */
7977 Lisp_Object tail;
7978 Lisp_Object fmt;
7979 struct buffer *obuf;
7980 int len;
7981 struct it it;
7982
7983 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7984 {
7985 Lisp_Object other_frame = XCAR (tail);
7986 struct frame *tf = XFRAME (other_frame);
7987
7988 if (tf != f
7989 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
7990 && !FRAME_MINIBUF_ONLY_P (tf)
7991 && !EQ (other_frame, tip_frame)
7992 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
7993 break;
7994 }
7995
7996 /* Set global variable indicating that multiple frames exist. */
7997 multiple_frames = CONSP (tail);
7998
7999 /* Switch to the buffer of selected window of the frame. Set up
8000 frame_title_ptr so that display_mode_element will output into it;
8001 then display the title. */
8002 obuf = current_buffer;
8003 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8004 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8005 frame_title_ptr = frame_title_buf;
8006 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8007 NULL, DEFAULT_FACE_ID);
8008 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8009 len = frame_title_ptr - frame_title_buf;
8010 frame_title_ptr = NULL;
8011 set_buffer_internal_1 (obuf);
8012
8013 /* Set the title only if it's changed. This avoids consing in
8014 the common case where it hasn't. (If it turns out that we've
8015 already wasted too much time by walking through the list with
8016 display_mode_element, then we might need to optimize at a
8017 higher level than this.) */
8018 if (! STRINGP (f->name)
8019 || SBYTES (f->name) != len
8020 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8021 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8022 }
8023 }
8024
8025 #endif /* not HAVE_WINDOW_SYSTEM */
8026
8027
8028
8029 \f
8030 /***********************************************************************
8031 Menu Bars
8032 ***********************************************************************/
8033
8034
8035 /* Prepare for redisplay by updating menu-bar item lists when
8036 appropriate. This can call eval. */
8037
8038 void
8039 prepare_menu_bars ()
8040 {
8041 int all_windows;
8042 struct gcpro gcpro1, gcpro2;
8043 struct frame *f;
8044 Lisp_Object tooltip_frame;
8045
8046 #ifdef HAVE_WINDOW_SYSTEM
8047 tooltip_frame = tip_frame;
8048 #else
8049 tooltip_frame = Qnil;
8050 #endif
8051
8052 /* Update all frame titles based on their buffer names, etc. We do
8053 this before the menu bars so that the buffer-menu will show the
8054 up-to-date frame titles. */
8055 #ifdef HAVE_WINDOW_SYSTEM
8056 if (windows_or_buffers_changed || update_mode_lines)
8057 {
8058 Lisp_Object tail, frame;
8059
8060 FOR_EACH_FRAME (tail, frame)
8061 {
8062 f = XFRAME (frame);
8063 if (!EQ (frame, tooltip_frame)
8064 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8065 x_consider_frame_title (frame);
8066 }
8067 }
8068 #endif /* HAVE_WINDOW_SYSTEM */
8069
8070 /* Update the menu bar item lists, if appropriate. This has to be
8071 done before any actual redisplay or generation of display lines. */
8072 all_windows = (update_mode_lines
8073 || buffer_shared > 1
8074 || windows_or_buffers_changed);
8075 if (all_windows)
8076 {
8077 Lisp_Object tail, frame;
8078 int count = SPECPDL_INDEX ();
8079
8080 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8081
8082 FOR_EACH_FRAME (tail, frame)
8083 {
8084 f = XFRAME (frame);
8085
8086 /* Ignore tooltip frame. */
8087 if (EQ (frame, tooltip_frame))
8088 continue;
8089
8090 /* If a window on this frame changed size, report that to
8091 the user and clear the size-change flag. */
8092 if (FRAME_WINDOW_SIZES_CHANGED (f))
8093 {
8094 Lisp_Object functions;
8095
8096 /* Clear flag first in case we get an error below. */
8097 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8098 functions = Vwindow_size_change_functions;
8099 GCPRO2 (tail, functions);
8100
8101 while (CONSP (functions))
8102 {
8103 call1 (XCAR (functions), frame);
8104 functions = XCDR (functions);
8105 }
8106 UNGCPRO;
8107 }
8108
8109 GCPRO1 (tail);
8110 update_menu_bar (f, 0);
8111 #ifdef HAVE_WINDOW_SYSTEM
8112 update_tool_bar (f, 0);
8113 #endif
8114 UNGCPRO;
8115 }
8116
8117 unbind_to (count, Qnil);
8118 }
8119 else
8120 {
8121 struct frame *sf = SELECTED_FRAME ();
8122 update_menu_bar (sf, 1);
8123 #ifdef HAVE_WINDOW_SYSTEM
8124 update_tool_bar (sf, 1);
8125 #endif
8126 }
8127
8128 /* Motif needs this. See comment in xmenu.c. Turn it off when
8129 pending_menu_activation is not defined. */
8130 #ifdef USE_X_TOOLKIT
8131 pending_menu_activation = 0;
8132 #endif
8133 }
8134
8135
8136 /* Update the menu bar item list for frame F. This has to be done
8137 before we start to fill in any display lines, because it can call
8138 eval.
8139
8140 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8141
8142 static void
8143 update_menu_bar (f, save_match_data)
8144 struct frame *f;
8145 int save_match_data;
8146 {
8147 Lisp_Object window;
8148 register struct window *w;
8149
8150 /* If called recursively during a menu update, do nothing. This can
8151 happen when, for instance, an activate-menubar-hook causes a
8152 redisplay. */
8153 if (inhibit_menubar_update)
8154 return;
8155
8156 window = FRAME_SELECTED_WINDOW (f);
8157 w = XWINDOW (window);
8158
8159 #if 0 /* The if statement below this if statement used to include the
8160 condition !NILP (w->update_mode_line), rather than using
8161 update_mode_lines directly, and this if statement may have
8162 been added to make that condition work. Now the if
8163 statement below matches its comment, this isn't needed. */
8164 if (update_mode_lines)
8165 w->update_mode_line = Qt;
8166 #endif
8167
8168 if (FRAME_WINDOW_P (f)
8169 ?
8170 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8171 || defined (USE_GTK)
8172 FRAME_EXTERNAL_MENU_BAR (f)
8173 #else
8174 FRAME_MENU_BAR_LINES (f) > 0
8175 #endif
8176 : FRAME_MENU_BAR_LINES (f) > 0)
8177 {
8178 /* If the user has switched buffers or windows, we need to
8179 recompute to reflect the new bindings. But we'll
8180 recompute when update_mode_lines is set too; that means
8181 that people can use force-mode-line-update to request
8182 that the menu bar be recomputed. The adverse effect on
8183 the rest of the redisplay algorithm is about the same as
8184 windows_or_buffers_changed anyway. */
8185 if (windows_or_buffers_changed
8186 /* This used to test w->update_mode_line, but we believe
8187 there is no need to recompute the menu in that case. */
8188 || update_mode_lines
8189 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8190 < BUF_MODIFF (XBUFFER (w->buffer)))
8191 != !NILP (w->last_had_star))
8192 || ((!NILP (Vtransient_mark_mode)
8193 && !NILP (XBUFFER (w->buffer)->mark_active))
8194 != !NILP (w->region_showing)))
8195 {
8196 struct buffer *prev = current_buffer;
8197 int count = SPECPDL_INDEX ();
8198
8199 specbind (Qinhibit_menubar_update, Qt);
8200
8201 set_buffer_internal_1 (XBUFFER (w->buffer));
8202 if (save_match_data)
8203 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8204 if (NILP (Voverriding_local_map_menu_flag))
8205 {
8206 specbind (Qoverriding_terminal_local_map, Qnil);
8207 specbind (Qoverriding_local_map, Qnil);
8208 }
8209
8210 /* Run the Lucid hook. */
8211 safe_run_hooks (Qactivate_menubar_hook);
8212
8213 /* If it has changed current-menubar from previous value,
8214 really recompute the menu-bar from the value. */
8215 if (! NILP (Vlucid_menu_bar_dirty_flag))
8216 call0 (Qrecompute_lucid_menubar);
8217
8218 safe_run_hooks (Qmenu_bar_update_hook);
8219 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8220
8221 /* Redisplay the menu bar in case we changed it. */
8222 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8223 || defined (USE_GTK)
8224 if (FRAME_WINDOW_P (f)
8225 #if defined (MAC_OS)
8226 /* All frames on Mac OS share the same menubar. So only the
8227 selected frame should be allowed to set it. */
8228 && f == SELECTED_FRAME ()
8229 #endif
8230 )
8231 set_frame_menubar (f, 0, 0);
8232 else
8233 /* On a terminal screen, the menu bar is an ordinary screen
8234 line, and this makes it get updated. */
8235 w->update_mode_line = Qt;
8236 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8237 /* In the non-toolkit version, the menu bar is an ordinary screen
8238 line, and this makes it get updated. */
8239 w->update_mode_line = Qt;
8240 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8241
8242 unbind_to (count, Qnil);
8243 set_buffer_internal_1 (prev);
8244 }
8245 }
8246 }
8247
8248
8249 \f
8250 /***********************************************************************
8251 Output Cursor
8252 ***********************************************************************/
8253
8254 #ifdef HAVE_WINDOW_SYSTEM
8255
8256 /* EXPORT:
8257 Nominal cursor position -- where to draw output.
8258 HPOS and VPOS are window relative glyph matrix coordinates.
8259 X and Y are window relative pixel coordinates. */
8260
8261 struct cursor_pos output_cursor;
8262
8263
8264 /* EXPORT:
8265 Set the global variable output_cursor to CURSOR. All cursor
8266 positions are relative to updated_window. */
8267
8268 void
8269 set_output_cursor (cursor)
8270 struct cursor_pos *cursor;
8271 {
8272 output_cursor.hpos = cursor->hpos;
8273 output_cursor.vpos = cursor->vpos;
8274 output_cursor.x = cursor->x;
8275 output_cursor.y = cursor->y;
8276 }
8277
8278
8279 /* EXPORT for RIF:
8280 Set a nominal cursor position.
8281
8282 HPOS and VPOS are column/row positions in a window glyph matrix. X
8283 and Y are window text area relative pixel positions.
8284
8285 If this is done during an update, updated_window will contain the
8286 window that is being updated and the position is the future output
8287 cursor position for that window. If updated_window is null, use
8288 selected_window and display the cursor at the given position. */
8289
8290 void
8291 x_cursor_to (vpos, hpos, y, x)
8292 int vpos, hpos, y, x;
8293 {
8294 struct window *w;
8295
8296 /* If updated_window is not set, work on selected_window. */
8297 if (updated_window)
8298 w = updated_window;
8299 else
8300 w = XWINDOW (selected_window);
8301
8302 /* Set the output cursor. */
8303 output_cursor.hpos = hpos;
8304 output_cursor.vpos = vpos;
8305 output_cursor.x = x;
8306 output_cursor.y = y;
8307
8308 /* If not called as part of an update, really display the cursor.
8309 This will also set the cursor position of W. */
8310 if (updated_window == NULL)
8311 {
8312 BLOCK_INPUT;
8313 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8314 if (rif->flush_display_optional)
8315 rif->flush_display_optional (SELECTED_FRAME ());
8316 UNBLOCK_INPUT;
8317 }
8318 }
8319
8320 #endif /* HAVE_WINDOW_SYSTEM */
8321
8322 \f
8323 /***********************************************************************
8324 Tool-bars
8325 ***********************************************************************/
8326
8327 #ifdef HAVE_WINDOW_SYSTEM
8328
8329 /* Where the mouse was last time we reported a mouse event. */
8330
8331 FRAME_PTR last_mouse_frame;
8332
8333 /* Tool-bar item index of the item on which a mouse button was pressed
8334 or -1. */
8335
8336 int last_tool_bar_item;
8337
8338
8339 /* Update the tool-bar item list for frame F. This has to be done
8340 before we start to fill in any display lines. Called from
8341 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8342 and restore it here. */
8343
8344 static void
8345 update_tool_bar (f, save_match_data)
8346 struct frame *f;
8347 int save_match_data;
8348 {
8349 #ifdef USE_GTK
8350 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8351 #else
8352 int do_update = WINDOWP (f->tool_bar_window)
8353 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8354 #endif
8355
8356 if (do_update)
8357 {
8358 Lisp_Object window;
8359 struct window *w;
8360
8361 window = FRAME_SELECTED_WINDOW (f);
8362 w = XWINDOW (window);
8363
8364 /* If the user has switched buffers or windows, we need to
8365 recompute to reflect the new bindings. But we'll
8366 recompute when update_mode_lines is set too; that means
8367 that people can use force-mode-line-update to request
8368 that the menu bar be recomputed. The adverse effect on
8369 the rest of the redisplay algorithm is about the same as
8370 windows_or_buffers_changed anyway. */
8371 if (windows_or_buffers_changed
8372 || !NILP (w->update_mode_line)
8373 || update_mode_lines
8374 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8375 < BUF_MODIFF (XBUFFER (w->buffer)))
8376 != !NILP (w->last_had_star))
8377 || ((!NILP (Vtransient_mark_mode)
8378 && !NILP (XBUFFER (w->buffer)->mark_active))
8379 != !NILP (w->region_showing)))
8380 {
8381 struct buffer *prev = current_buffer;
8382 int count = SPECPDL_INDEX ();
8383 Lisp_Object old_tool_bar;
8384 struct gcpro gcpro1;
8385
8386 /* Set current_buffer to the buffer of the selected
8387 window of the frame, so that we get the right local
8388 keymaps. */
8389 set_buffer_internal_1 (XBUFFER (w->buffer));
8390
8391 /* Save match data, if we must. */
8392 if (save_match_data)
8393 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8394
8395 /* Make sure that we don't accidentally use bogus keymaps. */
8396 if (NILP (Voverriding_local_map_menu_flag))
8397 {
8398 specbind (Qoverriding_terminal_local_map, Qnil);
8399 specbind (Qoverriding_local_map, Qnil);
8400 }
8401
8402 old_tool_bar = f->tool_bar_items;
8403 GCPRO1 (old_tool_bar);
8404
8405 /* Build desired tool-bar items from keymaps. */
8406 BLOCK_INPUT;
8407 f->tool_bar_items
8408 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8409 UNBLOCK_INPUT;
8410
8411 /* Redisplay the tool-bar if we changed it. */
8412 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8413 w->update_mode_line = Qt;
8414
8415 UNGCPRO;
8416
8417 unbind_to (count, Qnil);
8418 set_buffer_internal_1 (prev);
8419 }
8420 }
8421 }
8422
8423
8424 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8425 F's desired tool-bar contents. F->tool_bar_items must have
8426 been set up previously by calling prepare_menu_bars. */
8427
8428 static void
8429 build_desired_tool_bar_string (f)
8430 struct frame *f;
8431 {
8432 int i, size, size_needed;
8433 struct gcpro gcpro1, gcpro2, gcpro3;
8434 Lisp_Object image, plist, props;
8435
8436 image = plist = props = Qnil;
8437 GCPRO3 (image, plist, props);
8438
8439 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8440 Otherwise, make a new string. */
8441
8442 /* The size of the string we might be able to reuse. */
8443 size = (STRINGP (f->desired_tool_bar_string)
8444 ? SCHARS (f->desired_tool_bar_string)
8445 : 0);
8446
8447 /* We need one space in the string for each image. */
8448 size_needed = f->n_tool_bar_items;
8449
8450 /* Reuse f->desired_tool_bar_string, if possible. */
8451 if (size < size_needed || NILP (f->desired_tool_bar_string))
8452 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8453 make_number (' '));
8454 else
8455 {
8456 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8457 Fremove_text_properties (make_number (0), make_number (size),
8458 props, f->desired_tool_bar_string);
8459 }
8460
8461 /* Put a `display' property on the string for the images to display,
8462 put a `menu_item' property on tool-bar items with a value that
8463 is the index of the item in F's tool-bar item vector. */
8464 for (i = 0; i < f->n_tool_bar_items; ++i)
8465 {
8466 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8467
8468 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8469 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8470 int hmargin, vmargin, relief, idx, end;
8471 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8472
8473 /* If image is a vector, choose the image according to the
8474 button state. */
8475 image = PROP (TOOL_BAR_ITEM_IMAGES);
8476 if (VECTORP (image))
8477 {
8478 if (enabled_p)
8479 idx = (selected_p
8480 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8481 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8482 else
8483 idx = (selected_p
8484 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8485 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8486
8487 xassert (ASIZE (image) >= idx);
8488 image = AREF (image, idx);
8489 }
8490 else
8491 idx = -1;
8492
8493 /* Ignore invalid image specifications. */
8494 if (!valid_image_p (image))
8495 continue;
8496
8497 /* Display the tool-bar button pressed, or depressed. */
8498 plist = Fcopy_sequence (XCDR (image));
8499
8500 /* Compute margin and relief to draw. */
8501 relief = (tool_bar_button_relief >= 0
8502 ? tool_bar_button_relief
8503 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8504 hmargin = vmargin = relief;
8505
8506 if (INTEGERP (Vtool_bar_button_margin)
8507 && XINT (Vtool_bar_button_margin) > 0)
8508 {
8509 hmargin += XFASTINT (Vtool_bar_button_margin);
8510 vmargin += XFASTINT (Vtool_bar_button_margin);
8511 }
8512 else if (CONSP (Vtool_bar_button_margin))
8513 {
8514 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8515 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8516 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8517
8518 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8519 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8520 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8521 }
8522
8523 if (auto_raise_tool_bar_buttons_p)
8524 {
8525 /* Add a `:relief' property to the image spec if the item is
8526 selected. */
8527 if (selected_p)
8528 {
8529 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8530 hmargin -= relief;
8531 vmargin -= relief;
8532 }
8533 }
8534 else
8535 {
8536 /* If image is selected, display it pressed, i.e. with a
8537 negative relief. If it's not selected, display it with a
8538 raised relief. */
8539 plist = Fplist_put (plist, QCrelief,
8540 (selected_p
8541 ? make_number (-relief)
8542 : make_number (relief)));
8543 hmargin -= relief;
8544 vmargin -= relief;
8545 }
8546
8547 /* Put a margin around the image. */
8548 if (hmargin || vmargin)
8549 {
8550 if (hmargin == vmargin)
8551 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8552 else
8553 plist = Fplist_put (plist, QCmargin,
8554 Fcons (make_number (hmargin),
8555 make_number (vmargin)));
8556 }
8557
8558 /* If button is not enabled, and we don't have special images
8559 for the disabled state, make the image appear disabled by
8560 applying an appropriate algorithm to it. */
8561 if (!enabled_p && idx < 0)
8562 plist = Fplist_put (plist, QCconversion, Qdisabled);
8563
8564 /* Put a `display' text property on the string for the image to
8565 display. Put a `menu-item' property on the string that gives
8566 the start of this item's properties in the tool-bar items
8567 vector. */
8568 image = Fcons (Qimage, plist);
8569 props = list4 (Qdisplay, image,
8570 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8571
8572 /* Let the last image hide all remaining spaces in the tool bar
8573 string. The string can be longer than needed when we reuse a
8574 previous string. */
8575 if (i + 1 == f->n_tool_bar_items)
8576 end = SCHARS (f->desired_tool_bar_string);
8577 else
8578 end = i + 1;
8579 Fadd_text_properties (make_number (i), make_number (end),
8580 props, f->desired_tool_bar_string);
8581 #undef PROP
8582 }
8583
8584 UNGCPRO;
8585 }
8586
8587
8588 /* Display one line of the tool-bar of frame IT->f. */
8589
8590 static void
8591 display_tool_bar_line (it)
8592 struct it *it;
8593 {
8594 struct glyph_row *row = it->glyph_row;
8595 int max_x = it->last_visible_x;
8596 struct glyph *last;
8597
8598 prepare_desired_row (row);
8599 row->y = it->current_y;
8600
8601 /* Note that this isn't made use of if the face hasn't a box,
8602 so there's no need to check the face here. */
8603 it->start_of_box_run_p = 1;
8604
8605 while (it->current_x < max_x)
8606 {
8607 int x_before, x, n_glyphs_before, i, nglyphs;
8608
8609 /* Get the next display element. */
8610 if (!get_next_display_element (it))
8611 break;
8612
8613 /* Produce glyphs. */
8614 x_before = it->current_x;
8615 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8616 PRODUCE_GLYPHS (it);
8617
8618 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8619 i = 0;
8620 x = x_before;
8621 while (i < nglyphs)
8622 {
8623 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8624
8625 if (x + glyph->pixel_width > max_x)
8626 {
8627 /* Glyph doesn't fit on line. */
8628 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8629 it->current_x = x;
8630 goto out;
8631 }
8632
8633 ++it->hpos;
8634 x += glyph->pixel_width;
8635 ++i;
8636 }
8637
8638 /* Stop at line ends. */
8639 if (ITERATOR_AT_END_OF_LINE_P (it))
8640 break;
8641
8642 set_iterator_to_next (it, 1);
8643 }
8644
8645 out:;
8646
8647 row->displays_text_p = row->used[TEXT_AREA] != 0;
8648 extend_face_to_end_of_line (it);
8649 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8650 last->right_box_line_p = 1;
8651 if (last == row->glyphs[TEXT_AREA])
8652 last->left_box_line_p = 1;
8653 compute_line_metrics (it);
8654
8655 /* If line is empty, make it occupy the rest of the tool-bar. */
8656 if (!row->displays_text_p)
8657 {
8658 row->height = row->phys_height = it->last_visible_y - row->y;
8659 row->ascent = row->phys_ascent = 0;
8660 }
8661
8662 row->full_width_p = 1;
8663 row->continued_p = 0;
8664 row->truncated_on_left_p = 0;
8665 row->truncated_on_right_p = 0;
8666
8667 it->current_x = it->hpos = 0;
8668 it->current_y += row->height;
8669 ++it->vpos;
8670 ++it->glyph_row;
8671 }
8672
8673
8674 /* Value is the number of screen lines needed to make all tool-bar
8675 items of frame F visible. */
8676
8677 static int
8678 tool_bar_lines_needed (f)
8679 struct frame *f;
8680 {
8681 struct window *w = XWINDOW (f->tool_bar_window);
8682 struct it it;
8683
8684 /* Initialize an iterator for iteration over
8685 F->desired_tool_bar_string in the tool-bar window of frame F. */
8686 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8687 it.first_visible_x = 0;
8688 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8689 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8690
8691 while (!ITERATOR_AT_END_P (&it))
8692 {
8693 it.glyph_row = w->desired_matrix->rows;
8694 clear_glyph_row (it.glyph_row);
8695 display_tool_bar_line (&it);
8696 }
8697
8698 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8699 }
8700
8701
8702 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8703 0, 1, 0,
8704 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8705 (frame)
8706 Lisp_Object frame;
8707 {
8708 struct frame *f;
8709 struct window *w;
8710 int nlines = 0;
8711
8712 if (NILP (frame))
8713 frame = selected_frame;
8714 else
8715 CHECK_FRAME (frame);
8716 f = XFRAME (frame);
8717
8718 if (WINDOWP (f->tool_bar_window)
8719 || (w = XWINDOW (f->tool_bar_window),
8720 WINDOW_TOTAL_LINES (w) > 0))
8721 {
8722 update_tool_bar (f, 1);
8723 if (f->n_tool_bar_items)
8724 {
8725 build_desired_tool_bar_string (f);
8726 nlines = tool_bar_lines_needed (f);
8727 }
8728 }
8729
8730 return make_number (nlines);
8731 }
8732
8733
8734 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8735 height should be changed. */
8736
8737 static int
8738 redisplay_tool_bar (f)
8739 struct frame *f;
8740 {
8741 struct window *w;
8742 struct it it;
8743 struct glyph_row *row;
8744 int change_height_p = 0;
8745
8746 #ifdef USE_GTK
8747 if (FRAME_EXTERNAL_TOOL_BAR (f))
8748 update_frame_tool_bar (f);
8749 return 0;
8750 #endif
8751
8752 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8753 do anything. This means you must start with tool-bar-lines
8754 non-zero to get the auto-sizing effect. Or in other words, you
8755 can turn off tool-bars by specifying tool-bar-lines zero. */
8756 if (!WINDOWP (f->tool_bar_window)
8757 || (w = XWINDOW (f->tool_bar_window),
8758 WINDOW_TOTAL_LINES (w) == 0))
8759 return 0;
8760
8761 /* Set up an iterator for the tool-bar window. */
8762 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8763 it.first_visible_x = 0;
8764 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8765 row = it.glyph_row;
8766
8767 /* Build a string that represents the contents of the tool-bar. */
8768 build_desired_tool_bar_string (f);
8769 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8770
8771 /* Display as many lines as needed to display all tool-bar items. */
8772 while (it.current_y < it.last_visible_y)
8773 display_tool_bar_line (&it);
8774
8775 /* It doesn't make much sense to try scrolling in the tool-bar
8776 window, so don't do it. */
8777 w->desired_matrix->no_scrolling_p = 1;
8778 w->must_be_updated_p = 1;
8779
8780 if (auto_resize_tool_bars_p)
8781 {
8782 int nlines;
8783
8784 /* If we couldn't display everything, change the tool-bar's
8785 height. */
8786 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8787 change_height_p = 1;
8788
8789 /* If there are blank lines at the end, except for a partially
8790 visible blank line at the end that is smaller than
8791 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8792 row = it.glyph_row - 1;
8793 if (!row->displays_text_p
8794 && row->height >= FRAME_LINE_HEIGHT (f))
8795 change_height_p = 1;
8796
8797 /* If row displays tool-bar items, but is partially visible,
8798 change the tool-bar's height. */
8799 if (row->displays_text_p
8800 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8801 change_height_p = 1;
8802
8803 /* Resize windows as needed by changing the `tool-bar-lines'
8804 frame parameter. */
8805 if (change_height_p
8806 && (nlines = tool_bar_lines_needed (f),
8807 nlines != WINDOW_TOTAL_LINES (w)))
8808 {
8809 extern Lisp_Object Qtool_bar_lines;
8810 Lisp_Object frame;
8811 int old_height = WINDOW_TOTAL_LINES (w);
8812
8813 XSETFRAME (frame, f);
8814 clear_glyph_matrix (w->desired_matrix);
8815 Fmodify_frame_parameters (frame,
8816 Fcons (Fcons (Qtool_bar_lines,
8817 make_number (nlines)),
8818 Qnil));
8819 if (WINDOW_TOTAL_LINES (w) != old_height)
8820 fonts_changed_p = 1;
8821 }
8822 }
8823
8824 return change_height_p;
8825 }
8826
8827
8828 /* Get information about the tool-bar item which is displayed in GLYPH
8829 on frame F. Return in *PROP_IDX the index where tool-bar item
8830 properties start in F->tool_bar_items. Value is zero if
8831 GLYPH doesn't display a tool-bar item. */
8832
8833 static int
8834 tool_bar_item_info (f, glyph, prop_idx)
8835 struct frame *f;
8836 struct glyph *glyph;
8837 int *prop_idx;
8838 {
8839 Lisp_Object prop;
8840 int success_p;
8841 int charpos;
8842
8843 /* This function can be called asynchronously, which means we must
8844 exclude any possibility that Fget_text_property signals an
8845 error. */
8846 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8847 charpos = max (0, charpos);
8848
8849 /* Get the text property `menu-item' at pos. The value of that
8850 property is the start index of this item's properties in
8851 F->tool_bar_items. */
8852 prop = Fget_text_property (make_number (charpos),
8853 Qmenu_item, f->current_tool_bar_string);
8854 if (INTEGERP (prop))
8855 {
8856 *prop_idx = XINT (prop);
8857 success_p = 1;
8858 }
8859 else
8860 success_p = 0;
8861
8862 return success_p;
8863 }
8864
8865 \f
8866 /* Get information about the tool-bar item at position X/Y on frame F.
8867 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8868 the current matrix of the tool-bar window of F, or NULL if not
8869 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8870 item in F->tool_bar_items. Value is
8871
8872 -1 if X/Y is not on a tool-bar item
8873 0 if X/Y is on the same item that was highlighted before.
8874 1 otherwise. */
8875
8876 static int
8877 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8878 struct frame *f;
8879 int x, y;
8880 struct glyph **glyph;
8881 int *hpos, *vpos, *prop_idx;
8882 {
8883 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8884 struct window *w = XWINDOW (f->tool_bar_window);
8885 int area;
8886
8887 /* Find the glyph under X/Y. */
8888 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8889 if (*glyph == NULL)
8890 return -1;
8891
8892 /* Get the start of this tool-bar item's properties in
8893 f->tool_bar_items. */
8894 if (!tool_bar_item_info (f, *glyph, prop_idx))
8895 return -1;
8896
8897 /* Is mouse on the highlighted item? */
8898 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8899 && *vpos >= dpyinfo->mouse_face_beg_row
8900 && *vpos <= dpyinfo->mouse_face_end_row
8901 && (*vpos > dpyinfo->mouse_face_beg_row
8902 || *hpos >= dpyinfo->mouse_face_beg_col)
8903 && (*vpos < dpyinfo->mouse_face_end_row
8904 || *hpos < dpyinfo->mouse_face_end_col
8905 || dpyinfo->mouse_face_past_end))
8906 return 0;
8907
8908 return 1;
8909 }
8910
8911
8912 /* EXPORT:
8913 Handle mouse button event on the tool-bar of frame F, at
8914 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8915 0 for button release. MODIFIERS is event modifiers for button
8916 release. */
8917
8918 void
8919 handle_tool_bar_click (f, x, y, down_p, modifiers)
8920 struct frame *f;
8921 int x, y, down_p;
8922 unsigned int modifiers;
8923 {
8924 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8925 struct window *w = XWINDOW (f->tool_bar_window);
8926 int hpos, vpos, prop_idx;
8927 struct glyph *glyph;
8928 Lisp_Object enabled_p;
8929
8930 /* If not on the highlighted tool-bar item, return. */
8931 frame_to_window_pixel_xy (w, &x, &y);
8932 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8933 return;
8934
8935 /* If item is disabled, do nothing. */
8936 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8937 if (NILP (enabled_p))
8938 return;
8939
8940 if (down_p)
8941 {
8942 /* Show item in pressed state. */
8943 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8944 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8945 last_tool_bar_item = prop_idx;
8946 }
8947 else
8948 {
8949 Lisp_Object key, frame;
8950 struct input_event event;
8951 EVENT_INIT (event);
8952
8953 /* Show item in released state. */
8954 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8955 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8956
8957 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8958
8959 XSETFRAME (frame, f);
8960 event.kind = TOOL_BAR_EVENT;
8961 event.frame_or_window = frame;
8962 event.arg = frame;
8963 kbd_buffer_store_event (&event);
8964
8965 event.kind = TOOL_BAR_EVENT;
8966 event.frame_or_window = frame;
8967 event.arg = key;
8968 event.modifiers = modifiers;
8969 kbd_buffer_store_event (&event);
8970 last_tool_bar_item = -1;
8971 }
8972 }
8973
8974
8975 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8976 tool-bar window-relative coordinates X/Y. Called from
8977 note_mouse_highlight. */
8978
8979 static void
8980 note_tool_bar_highlight (f, x, y)
8981 struct frame *f;
8982 int x, y;
8983 {
8984 Lisp_Object window = f->tool_bar_window;
8985 struct window *w = XWINDOW (window);
8986 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8987 int hpos, vpos;
8988 struct glyph *glyph;
8989 struct glyph_row *row;
8990 int i;
8991 Lisp_Object enabled_p;
8992 int prop_idx;
8993 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8994 int mouse_down_p, rc;
8995
8996 /* Function note_mouse_highlight is called with negative x(y
8997 values when mouse moves outside of the frame. */
8998 if (x <= 0 || y <= 0)
8999 {
9000 clear_mouse_face (dpyinfo);
9001 return;
9002 }
9003
9004 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9005 if (rc < 0)
9006 {
9007 /* Not on tool-bar item. */
9008 clear_mouse_face (dpyinfo);
9009 return;
9010 }
9011 else if (rc == 0)
9012 /* On same tool-bar item as before. */
9013 goto set_help_echo;
9014
9015 clear_mouse_face (dpyinfo);
9016
9017 /* Mouse is down, but on different tool-bar item? */
9018 mouse_down_p = (dpyinfo->grabbed
9019 && f == last_mouse_frame
9020 && FRAME_LIVE_P (f));
9021 if (mouse_down_p
9022 && last_tool_bar_item != prop_idx)
9023 return;
9024
9025 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9026 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9027
9028 /* If tool-bar item is not enabled, don't highlight it. */
9029 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9030 if (!NILP (enabled_p))
9031 {
9032 /* Compute the x-position of the glyph. In front and past the
9033 image is a space. We include this in the highlighted area. */
9034 row = MATRIX_ROW (w->current_matrix, vpos);
9035 for (i = x = 0; i < hpos; ++i)
9036 x += row->glyphs[TEXT_AREA][i].pixel_width;
9037
9038 /* Record this as the current active region. */
9039 dpyinfo->mouse_face_beg_col = hpos;
9040 dpyinfo->mouse_face_beg_row = vpos;
9041 dpyinfo->mouse_face_beg_x = x;
9042 dpyinfo->mouse_face_beg_y = row->y;
9043 dpyinfo->mouse_face_past_end = 0;
9044
9045 dpyinfo->mouse_face_end_col = hpos + 1;
9046 dpyinfo->mouse_face_end_row = vpos;
9047 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9048 dpyinfo->mouse_face_end_y = row->y;
9049 dpyinfo->mouse_face_window = window;
9050 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9051
9052 /* Display it as active. */
9053 show_mouse_face (dpyinfo, draw);
9054 dpyinfo->mouse_face_image_state = draw;
9055 }
9056
9057 set_help_echo:
9058
9059 /* Set help_echo_string to a help string to display for this tool-bar item.
9060 XTread_socket does the rest. */
9061 help_echo_object = help_echo_window = Qnil;
9062 help_echo_pos = -1;
9063 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9064 if (NILP (help_echo_string))
9065 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9066 }
9067
9068 #endif /* HAVE_WINDOW_SYSTEM */
9069
9070
9071 \f
9072 /************************************************************************
9073 Horizontal scrolling
9074 ************************************************************************/
9075
9076 static int hscroll_window_tree P_ ((Lisp_Object));
9077 static int hscroll_windows P_ ((Lisp_Object));
9078
9079 /* For all leaf windows in the window tree rooted at WINDOW, set their
9080 hscroll value so that PT is (i) visible in the window, and (ii) so
9081 that it is not within a certain margin at the window's left and
9082 right border. Value is non-zero if any window's hscroll has been
9083 changed. */
9084
9085 static int
9086 hscroll_window_tree (window)
9087 Lisp_Object window;
9088 {
9089 int hscrolled_p = 0;
9090 int hscroll_relative_p = FLOATP (Vhscroll_step);
9091 int hscroll_step_abs = 0;
9092 double hscroll_step_rel = 0;
9093
9094 if (hscroll_relative_p)
9095 {
9096 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9097 if (hscroll_step_rel < 0)
9098 {
9099 hscroll_relative_p = 0;
9100 hscroll_step_abs = 0;
9101 }
9102 }
9103 else if (INTEGERP (Vhscroll_step))
9104 {
9105 hscroll_step_abs = XINT (Vhscroll_step);
9106 if (hscroll_step_abs < 0)
9107 hscroll_step_abs = 0;
9108 }
9109 else
9110 hscroll_step_abs = 0;
9111
9112 while (WINDOWP (window))
9113 {
9114 struct window *w = XWINDOW (window);
9115
9116 if (WINDOWP (w->hchild))
9117 hscrolled_p |= hscroll_window_tree (w->hchild);
9118 else if (WINDOWP (w->vchild))
9119 hscrolled_p |= hscroll_window_tree (w->vchild);
9120 else if (w->cursor.vpos >= 0)
9121 {
9122 int h_margin;
9123 int text_area_width;
9124 struct glyph_row *current_cursor_row
9125 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9126 struct glyph_row *desired_cursor_row
9127 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9128 struct glyph_row *cursor_row
9129 = (desired_cursor_row->enabled_p
9130 ? desired_cursor_row
9131 : current_cursor_row);
9132
9133 text_area_width = window_box_width (w, TEXT_AREA);
9134
9135 /* Scroll when cursor is inside this scroll margin. */
9136 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9137
9138 if ((XFASTINT (w->hscroll)
9139 && w->cursor.x <= h_margin)
9140 || (cursor_row->enabled_p
9141 && cursor_row->truncated_on_right_p
9142 && (w->cursor.x >= text_area_width - h_margin)))
9143 {
9144 struct it it;
9145 int hscroll;
9146 struct buffer *saved_current_buffer;
9147 int pt;
9148 int wanted_x;
9149
9150 /* Find point in a display of infinite width. */
9151 saved_current_buffer = current_buffer;
9152 current_buffer = XBUFFER (w->buffer);
9153
9154 if (w == XWINDOW (selected_window))
9155 pt = BUF_PT (current_buffer);
9156 else
9157 {
9158 pt = marker_position (w->pointm);
9159 pt = max (BEGV, pt);
9160 pt = min (ZV, pt);
9161 }
9162
9163 /* Move iterator to pt starting at cursor_row->start in
9164 a line with infinite width. */
9165 init_to_row_start (&it, w, cursor_row);
9166 it.last_visible_x = INFINITY;
9167 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9168 current_buffer = saved_current_buffer;
9169
9170 /* Position cursor in window. */
9171 if (!hscroll_relative_p && hscroll_step_abs == 0)
9172 hscroll = max (0, (it.current_x
9173 - (ITERATOR_AT_END_OF_LINE_P (&it)
9174 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9175 : (text_area_width / 2))))
9176 / FRAME_COLUMN_WIDTH (it.f);
9177 else if (w->cursor.x >= text_area_width - h_margin)
9178 {
9179 if (hscroll_relative_p)
9180 wanted_x = text_area_width * (1 - hscroll_step_rel)
9181 - h_margin;
9182 else
9183 wanted_x = text_area_width
9184 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9185 - h_margin;
9186 hscroll
9187 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9188 }
9189 else
9190 {
9191 if (hscroll_relative_p)
9192 wanted_x = text_area_width * hscroll_step_rel
9193 + h_margin;
9194 else
9195 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9196 + h_margin;
9197 hscroll
9198 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9199 }
9200 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9201
9202 /* Don't call Fset_window_hscroll if value hasn't
9203 changed because it will prevent redisplay
9204 optimizations. */
9205 if (XFASTINT (w->hscroll) != hscroll)
9206 {
9207 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9208 w->hscroll = make_number (hscroll);
9209 hscrolled_p = 1;
9210 }
9211 }
9212 }
9213
9214 window = w->next;
9215 }
9216
9217 /* Value is non-zero if hscroll of any leaf window has been changed. */
9218 return hscrolled_p;
9219 }
9220
9221
9222 /* Set hscroll so that cursor is visible and not inside horizontal
9223 scroll margins for all windows in the tree rooted at WINDOW. See
9224 also hscroll_window_tree above. Value is non-zero if any window's
9225 hscroll has been changed. If it has, desired matrices on the frame
9226 of WINDOW are cleared. */
9227
9228 static int
9229 hscroll_windows (window)
9230 Lisp_Object window;
9231 {
9232 int hscrolled_p;
9233
9234 if (automatic_hscrolling_p)
9235 {
9236 hscrolled_p = hscroll_window_tree (window);
9237 if (hscrolled_p)
9238 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9239 }
9240 else
9241 hscrolled_p = 0;
9242 return hscrolled_p;
9243 }
9244
9245
9246 \f
9247 /************************************************************************
9248 Redisplay
9249 ************************************************************************/
9250
9251 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9252 to a non-zero value. This is sometimes handy to have in a debugger
9253 session. */
9254
9255 #if GLYPH_DEBUG
9256
9257 /* First and last unchanged row for try_window_id. */
9258
9259 int debug_first_unchanged_at_end_vpos;
9260 int debug_last_unchanged_at_beg_vpos;
9261
9262 /* Delta vpos and y. */
9263
9264 int debug_dvpos, debug_dy;
9265
9266 /* Delta in characters and bytes for try_window_id. */
9267
9268 int debug_delta, debug_delta_bytes;
9269
9270 /* Values of window_end_pos and window_end_vpos at the end of
9271 try_window_id. */
9272
9273 EMACS_INT debug_end_pos, debug_end_vpos;
9274
9275 /* Append a string to W->desired_matrix->method. FMT is a printf
9276 format string. A1...A9 are a supplement for a variable-length
9277 argument list. If trace_redisplay_p is non-zero also printf the
9278 resulting string to stderr. */
9279
9280 static void
9281 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9282 struct window *w;
9283 char *fmt;
9284 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9285 {
9286 char buffer[512];
9287 char *method = w->desired_matrix->method;
9288 int len = strlen (method);
9289 int size = sizeof w->desired_matrix->method;
9290 int remaining = size - len - 1;
9291
9292 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9293 if (len && remaining)
9294 {
9295 method[len] = '|';
9296 --remaining, ++len;
9297 }
9298
9299 strncpy (method + len, buffer, remaining);
9300
9301 if (trace_redisplay_p)
9302 fprintf (stderr, "%p (%s): %s\n",
9303 w,
9304 ((BUFFERP (w->buffer)
9305 && STRINGP (XBUFFER (w->buffer)->name))
9306 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9307 : "no buffer"),
9308 buffer);
9309 }
9310
9311 #endif /* GLYPH_DEBUG */
9312
9313
9314 /* Value is non-zero if all changes in window W, which displays
9315 current_buffer, are in the text between START and END. START is a
9316 buffer position, END is given as a distance from Z. Used in
9317 redisplay_internal for display optimization. */
9318
9319 static INLINE int
9320 text_outside_line_unchanged_p (w, start, end)
9321 struct window *w;
9322 int start, end;
9323 {
9324 int unchanged_p = 1;
9325
9326 /* If text or overlays have changed, see where. */
9327 if (XFASTINT (w->last_modified) < MODIFF
9328 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9329 {
9330 /* Gap in the line? */
9331 if (GPT < start || Z - GPT < end)
9332 unchanged_p = 0;
9333
9334 /* Changes start in front of the line, or end after it? */
9335 if (unchanged_p
9336 && (BEG_UNCHANGED < start - 1
9337 || END_UNCHANGED < end))
9338 unchanged_p = 0;
9339
9340 /* If selective display, can't optimize if changes start at the
9341 beginning of the line. */
9342 if (unchanged_p
9343 && INTEGERP (current_buffer->selective_display)
9344 && XINT (current_buffer->selective_display) > 0
9345 && (BEG_UNCHANGED < start || GPT <= start))
9346 unchanged_p = 0;
9347
9348 /* If there are overlays at the start or end of the line, these
9349 may have overlay strings with newlines in them. A change at
9350 START, for instance, may actually concern the display of such
9351 overlay strings as well, and they are displayed on different
9352 lines. So, quickly rule out this case. (For the future, it
9353 might be desirable to implement something more telling than
9354 just BEG/END_UNCHANGED.) */
9355 if (unchanged_p)
9356 {
9357 if (BEG + BEG_UNCHANGED == start
9358 && overlay_touches_p (start))
9359 unchanged_p = 0;
9360 if (END_UNCHANGED == end
9361 && overlay_touches_p (Z - end))
9362 unchanged_p = 0;
9363 }
9364 }
9365
9366 return unchanged_p;
9367 }
9368
9369
9370 /* Do a frame update, taking possible shortcuts into account. This is
9371 the main external entry point for redisplay.
9372
9373 If the last redisplay displayed an echo area message and that message
9374 is no longer requested, we clear the echo area or bring back the
9375 mini-buffer if that is in use. */
9376
9377 void
9378 redisplay ()
9379 {
9380 redisplay_internal (0);
9381 }
9382
9383
9384 static Lisp_Object
9385 overlay_arrow_string_or_property (var, pbitmap)
9386 Lisp_Object var;
9387 int *pbitmap;
9388 {
9389 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9390 Lisp_Object bitmap;
9391
9392 if (pbitmap)
9393 {
9394 *pbitmap = 0;
9395 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9396 *pbitmap = XINT (bitmap);
9397 }
9398
9399 if (!NILP (pstr))
9400 return pstr;
9401 return Voverlay_arrow_string;
9402 }
9403
9404 /* Return 1 if there are any overlay-arrows in current_buffer. */
9405 static int
9406 overlay_arrow_in_current_buffer_p ()
9407 {
9408 Lisp_Object vlist;
9409
9410 for (vlist = Voverlay_arrow_variable_list;
9411 CONSP (vlist);
9412 vlist = XCDR (vlist))
9413 {
9414 Lisp_Object var = XCAR (vlist);
9415 Lisp_Object val;
9416
9417 if (!SYMBOLP (var))
9418 continue;
9419 val = find_symbol_value (var);
9420 if (MARKERP (val)
9421 && current_buffer == XMARKER (val)->buffer)
9422 return 1;
9423 }
9424 return 0;
9425 }
9426
9427
9428 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9429 has changed. */
9430
9431 static int
9432 overlay_arrows_changed_p ()
9433 {
9434 Lisp_Object vlist;
9435
9436 for (vlist = Voverlay_arrow_variable_list;
9437 CONSP (vlist);
9438 vlist = XCDR (vlist))
9439 {
9440 Lisp_Object var = XCAR (vlist);
9441 Lisp_Object val, pstr;
9442
9443 if (!SYMBOLP (var))
9444 continue;
9445 val = find_symbol_value (var);
9446 if (!MARKERP (val))
9447 continue;
9448 if (! EQ (COERCE_MARKER (val),
9449 Fget (var, Qlast_arrow_position))
9450 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9451 EQ (pstr, Fget (var, Qlast_arrow_string))))
9452 return 1;
9453 }
9454 return 0;
9455 }
9456
9457 /* Mark overlay arrows to be updated on next redisplay. */
9458
9459 static void
9460 update_overlay_arrows (up_to_date)
9461 int up_to_date;
9462 {
9463 Lisp_Object vlist;
9464
9465 for (vlist = Voverlay_arrow_variable_list;
9466 CONSP (vlist);
9467 vlist = XCDR (vlist))
9468 {
9469 Lisp_Object var = XCAR (vlist);
9470
9471 if (!SYMBOLP (var))
9472 continue;
9473
9474 if (up_to_date > 0)
9475 {
9476 Lisp_Object val = find_symbol_value (var);
9477 Fput (var, Qlast_arrow_position,
9478 COERCE_MARKER (val));
9479 Fput (var, Qlast_arrow_string,
9480 overlay_arrow_string_or_property (var, 0));
9481 }
9482 else if (up_to_date < 0
9483 || !NILP (Fget (var, Qlast_arrow_position)))
9484 {
9485 Fput (var, Qlast_arrow_position, Qt);
9486 Fput (var, Qlast_arrow_string, Qt);
9487 }
9488 }
9489 }
9490
9491
9492 /* Return overlay arrow string at row, or nil. */
9493
9494 static Lisp_Object
9495 overlay_arrow_at_row (f, row, pbitmap)
9496 struct frame *f;
9497 struct glyph_row *row;
9498 int *pbitmap;
9499 {
9500 Lisp_Object vlist;
9501
9502 for (vlist = Voverlay_arrow_variable_list;
9503 CONSP (vlist);
9504 vlist = XCDR (vlist))
9505 {
9506 Lisp_Object var = XCAR (vlist);
9507 Lisp_Object val;
9508
9509 if (!SYMBOLP (var))
9510 continue;
9511
9512 val = find_symbol_value (var);
9513
9514 if (MARKERP (val)
9515 && current_buffer == XMARKER (val)->buffer
9516 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9517 {
9518 val = overlay_arrow_string_or_property (var, pbitmap);
9519 if (FRAME_WINDOW_P (f))
9520 return Qt;
9521 else if (STRINGP (val))
9522 return val;
9523 break;
9524 }
9525 }
9526
9527 *pbitmap = 0;
9528 return Qnil;
9529 }
9530
9531 /* Return 1 if point moved out of or into a composition. Otherwise
9532 return 0. PREV_BUF and PREV_PT are the last point buffer and
9533 position. BUF and PT are the current point buffer and position. */
9534
9535 int
9536 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9537 struct buffer *prev_buf, *buf;
9538 int prev_pt, pt;
9539 {
9540 int start, end;
9541 Lisp_Object prop;
9542 Lisp_Object buffer;
9543
9544 XSETBUFFER (buffer, buf);
9545 /* Check a composition at the last point if point moved within the
9546 same buffer. */
9547 if (prev_buf == buf)
9548 {
9549 if (prev_pt == pt)
9550 /* Point didn't move. */
9551 return 0;
9552
9553 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9554 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9555 && COMPOSITION_VALID_P (start, end, prop)
9556 && start < prev_pt && end > prev_pt)
9557 /* The last point was within the composition. Return 1 iff
9558 point moved out of the composition. */
9559 return (pt <= start || pt >= end);
9560 }
9561
9562 /* Check a composition at the current point. */
9563 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9564 && find_composition (pt, -1, &start, &end, &prop, buffer)
9565 && COMPOSITION_VALID_P (start, end, prop)
9566 && start < pt && end > pt);
9567 }
9568
9569
9570 /* Reconsider the setting of B->clip_changed which is displayed
9571 in window W. */
9572
9573 static INLINE void
9574 reconsider_clip_changes (w, b)
9575 struct window *w;
9576 struct buffer *b;
9577 {
9578 if (b->clip_changed
9579 && !NILP (w->window_end_valid)
9580 && w->current_matrix->buffer == b
9581 && w->current_matrix->zv == BUF_ZV (b)
9582 && w->current_matrix->begv == BUF_BEGV (b))
9583 b->clip_changed = 0;
9584
9585 /* If display wasn't paused, and W is not a tool bar window, see if
9586 point has been moved into or out of a composition. In that case,
9587 we set b->clip_changed to 1 to force updating the screen. If
9588 b->clip_changed has already been set to 1, we can skip this
9589 check. */
9590 if (!b->clip_changed
9591 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9592 {
9593 int pt;
9594
9595 if (w == XWINDOW (selected_window))
9596 pt = BUF_PT (current_buffer);
9597 else
9598 pt = marker_position (w->pointm);
9599
9600 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9601 || pt != XINT (w->last_point))
9602 && check_point_in_composition (w->current_matrix->buffer,
9603 XINT (w->last_point),
9604 XBUFFER (w->buffer), pt))
9605 b->clip_changed = 1;
9606 }
9607 }
9608 \f
9609
9610 /* Select FRAME to forward the values of frame-local variables into C
9611 variables so that the redisplay routines can access those values
9612 directly. */
9613
9614 static void
9615 select_frame_for_redisplay (frame)
9616 Lisp_Object frame;
9617 {
9618 Lisp_Object tail, sym, val;
9619 Lisp_Object old = selected_frame;
9620
9621 selected_frame = frame;
9622
9623 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9624 if (CONSP (XCAR (tail))
9625 && (sym = XCAR (XCAR (tail)),
9626 SYMBOLP (sym))
9627 && (sym = indirect_variable (sym),
9628 val = SYMBOL_VALUE (sym),
9629 (BUFFER_LOCAL_VALUEP (val)
9630 || SOME_BUFFER_LOCAL_VALUEP (val)))
9631 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9632 Fsymbol_value (sym);
9633
9634 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9635 if (CONSP (XCAR (tail))
9636 && (sym = XCAR (XCAR (tail)),
9637 SYMBOLP (sym))
9638 && (sym = indirect_variable (sym),
9639 val = SYMBOL_VALUE (sym),
9640 (BUFFER_LOCAL_VALUEP (val)
9641 || SOME_BUFFER_LOCAL_VALUEP (val)))
9642 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9643 Fsymbol_value (sym);
9644 }
9645
9646
9647 #define STOP_POLLING \
9648 do { if (! polling_stopped_here) stop_polling (); \
9649 polling_stopped_here = 1; } while (0)
9650
9651 #define RESUME_POLLING \
9652 do { if (polling_stopped_here) start_polling (); \
9653 polling_stopped_here = 0; } while (0)
9654
9655
9656 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9657 response to any user action; therefore, we should preserve the echo
9658 area. (Actually, our caller does that job.) Perhaps in the future
9659 avoid recentering windows if it is not necessary; currently that
9660 causes some problems. */
9661
9662 static void
9663 redisplay_internal (preserve_echo_area)
9664 int preserve_echo_area;
9665 {
9666 struct window *w = XWINDOW (selected_window);
9667 struct frame *f = XFRAME (w->frame);
9668 int pause;
9669 int must_finish = 0;
9670 struct text_pos tlbufpos, tlendpos;
9671 int number_of_visible_frames;
9672 int count;
9673 struct frame *sf = SELECTED_FRAME ();
9674 int polling_stopped_here = 0;
9675
9676 /* Non-zero means redisplay has to consider all windows on all
9677 frames. Zero means, only selected_window is considered. */
9678 int consider_all_windows_p;
9679
9680 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9681
9682 /* No redisplay if running in batch mode or frame is not yet fully
9683 initialized, or redisplay is explicitly turned off by setting
9684 Vinhibit_redisplay. */
9685 if (noninteractive
9686 || !NILP (Vinhibit_redisplay)
9687 || !f->glyphs_initialized_p)
9688 return;
9689
9690 /* The flag redisplay_performed_directly_p is set by
9691 direct_output_for_insert when it already did the whole screen
9692 update necessary. */
9693 if (redisplay_performed_directly_p)
9694 {
9695 redisplay_performed_directly_p = 0;
9696 if (!hscroll_windows (selected_window))
9697 return;
9698 }
9699
9700 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9701 if (popup_activated ())
9702 return;
9703 #endif
9704
9705 /* I don't think this happens but let's be paranoid. */
9706 if (redisplaying_p)
9707 return;
9708
9709 /* Record a function that resets redisplaying_p to its old value
9710 when we leave this function. */
9711 count = SPECPDL_INDEX ();
9712 record_unwind_protect (unwind_redisplay,
9713 Fcons (make_number (redisplaying_p), selected_frame));
9714 ++redisplaying_p;
9715 specbind (Qinhibit_free_realized_faces, Qnil);
9716
9717 retry:
9718 pause = 0;
9719 reconsider_clip_changes (w, current_buffer);
9720
9721 /* If new fonts have been loaded that make a glyph matrix adjustment
9722 necessary, do it. */
9723 if (fonts_changed_p)
9724 {
9725 adjust_glyphs (NULL);
9726 ++windows_or_buffers_changed;
9727 fonts_changed_p = 0;
9728 }
9729
9730 /* If face_change_count is non-zero, init_iterator will free all
9731 realized faces, which includes the faces referenced from current
9732 matrices. So, we can't reuse current matrices in this case. */
9733 if (face_change_count)
9734 ++windows_or_buffers_changed;
9735
9736 if (! FRAME_WINDOW_P (sf)
9737 && previous_terminal_frame != sf)
9738 {
9739 /* Since frames on an ASCII terminal share the same display
9740 area, displaying a different frame means redisplay the whole
9741 thing. */
9742 windows_or_buffers_changed++;
9743 SET_FRAME_GARBAGED (sf);
9744 XSETFRAME (Vterminal_frame, sf);
9745 }
9746 previous_terminal_frame = sf;
9747
9748 /* Set the visible flags for all frames. Do this before checking
9749 for resized or garbaged frames; they want to know if their frames
9750 are visible. See the comment in frame.h for
9751 FRAME_SAMPLE_VISIBILITY. */
9752 {
9753 Lisp_Object tail, frame;
9754
9755 number_of_visible_frames = 0;
9756
9757 FOR_EACH_FRAME (tail, frame)
9758 {
9759 struct frame *f = XFRAME (frame);
9760
9761 FRAME_SAMPLE_VISIBILITY (f);
9762 if (FRAME_VISIBLE_P (f))
9763 ++number_of_visible_frames;
9764 clear_desired_matrices (f);
9765 }
9766 }
9767
9768 /* Notice any pending interrupt request to change frame size. */
9769 do_pending_window_change (1);
9770
9771 /* Clear frames marked as garbaged. */
9772 if (frame_garbaged)
9773 clear_garbaged_frames ();
9774
9775 /* Build menubar and tool-bar items. */
9776 prepare_menu_bars ();
9777
9778 if (windows_or_buffers_changed)
9779 update_mode_lines++;
9780
9781 /* Detect case that we need to write or remove a star in the mode line. */
9782 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9783 {
9784 w->update_mode_line = Qt;
9785 if (buffer_shared > 1)
9786 update_mode_lines++;
9787 }
9788
9789 /* If %c is in the mode line, update it if needed. */
9790 if (!NILP (w->column_number_displayed)
9791 /* This alternative quickly identifies a common case
9792 where no change is needed. */
9793 && !(PT == XFASTINT (w->last_point)
9794 && XFASTINT (w->last_modified) >= MODIFF
9795 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9796 && (XFASTINT (w->column_number_displayed)
9797 != (int) current_column ())) /* iftc */
9798 w->update_mode_line = Qt;
9799
9800 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9801
9802 /* The variable buffer_shared is set in redisplay_window and
9803 indicates that we redisplay a buffer in different windows. See
9804 there. */
9805 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9806 || cursor_type_changed);
9807
9808 /* If specs for an arrow have changed, do thorough redisplay
9809 to ensure we remove any arrow that should no longer exist. */
9810 if (overlay_arrows_changed_p ())
9811 consider_all_windows_p = windows_or_buffers_changed = 1;
9812
9813 /* Normally the message* functions will have already displayed and
9814 updated the echo area, but the frame may have been trashed, or
9815 the update may have been preempted, so display the echo area
9816 again here. Checking message_cleared_p captures the case that
9817 the echo area should be cleared. */
9818 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9819 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9820 || (message_cleared_p
9821 && minibuf_level == 0
9822 /* If the mini-window is currently selected, this means the
9823 echo-area doesn't show through. */
9824 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9825 {
9826 int window_height_changed_p = echo_area_display (0);
9827 must_finish = 1;
9828
9829 /* If we don't display the current message, don't clear the
9830 message_cleared_p flag, because, if we did, we wouldn't clear
9831 the echo area in the next redisplay which doesn't preserve
9832 the echo area. */
9833 if (!display_last_displayed_message_p)
9834 message_cleared_p = 0;
9835
9836 if (fonts_changed_p)
9837 goto retry;
9838 else if (window_height_changed_p)
9839 {
9840 consider_all_windows_p = 1;
9841 ++update_mode_lines;
9842 ++windows_or_buffers_changed;
9843
9844 /* If window configuration was changed, frames may have been
9845 marked garbaged. Clear them or we will experience
9846 surprises wrt scrolling. */
9847 if (frame_garbaged)
9848 clear_garbaged_frames ();
9849 }
9850 }
9851 else if (EQ (selected_window, minibuf_window)
9852 && (current_buffer->clip_changed
9853 || XFASTINT (w->last_modified) < MODIFF
9854 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9855 && resize_mini_window (w, 0))
9856 {
9857 /* Resized active mini-window to fit the size of what it is
9858 showing if its contents might have changed. */
9859 must_finish = 1;
9860 consider_all_windows_p = 1;
9861 ++windows_or_buffers_changed;
9862 ++update_mode_lines;
9863
9864 /* If window configuration was changed, frames may have been
9865 marked garbaged. Clear them or we will experience
9866 surprises wrt scrolling. */
9867 if (frame_garbaged)
9868 clear_garbaged_frames ();
9869 }
9870
9871
9872 /* If showing the region, and mark has changed, we must redisplay
9873 the whole window. The assignment to this_line_start_pos prevents
9874 the optimization directly below this if-statement. */
9875 if (((!NILP (Vtransient_mark_mode)
9876 && !NILP (XBUFFER (w->buffer)->mark_active))
9877 != !NILP (w->region_showing))
9878 || (!NILP (w->region_showing)
9879 && !EQ (w->region_showing,
9880 Fmarker_position (XBUFFER (w->buffer)->mark))))
9881 CHARPOS (this_line_start_pos) = 0;
9882
9883 /* Optimize the case that only the line containing the cursor in the
9884 selected window has changed. Variables starting with this_ are
9885 set in display_line and record information about the line
9886 containing the cursor. */
9887 tlbufpos = this_line_start_pos;
9888 tlendpos = this_line_end_pos;
9889 if (!consider_all_windows_p
9890 && CHARPOS (tlbufpos) > 0
9891 && NILP (w->update_mode_line)
9892 && !current_buffer->clip_changed
9893 && !current_buffer->prevent_redisplay_optimizations_p
9894 && FRAME_VISIBLE_P (XFRAME (w->frame))
9895 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9896 /* Make sure recorded data applies to current buffer, etc. */
9897 && this_line_buffer == current_buffer
9898 && current_buffer == XBUFFER (w->buffer)
9899 && NILP (w->force_start)
9900 && NILP (w->optional_new_start)
9901 /* Point must be on the line that we have info recorded about. */
9902 && PT >= CHARPOS (tlbufpos)
9903 && PT <= Z - CHARPOS (tlendpos)
9904 /* All text outside that line, including its final newline,
9905 must be unchanged */
9906 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9907 CHARPOS (tlendpos)))
9908 {
9909 if (CHARPOS (tlbufpos) > BEGV
9910 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9911 && (CHARPOS (tlbufpos) == ZV
9912 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9913 /* Former continuation line has disappeared by becoming empty */
9914 goto cancel;
9915 else if (XFASTINT (w->last_modified) < MODIFF
9916 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9917 || MINI_WINDOW_P (w))
9918 {
9919 /* We have to handle the case of continuation around a
9920 wide-column character (See the comment in indent.c around
9921 line 885).
9922
9923 For instance, in the following case:
9924
9925 -------- Insert --------
9926 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9927 J_I_ ==> J_I_ `^^' are cursors.
9928 ^^ ^^
9929 -------- --------
9930
9931 As we have to redraw the line above, we should goto cancel. */
9932
9933 struct it it;
9934 int line_height_before = this_line_pixel_height;
9935
9936 /* Note that start_display will handle the case that the
9937 line starting at tlbufpos is a continuation lines. */
9938 start_display (&it, w, tlbufpos);
9939
9940 /* Implementation note: It this still necessary? */
9941 if (it.current_x != this_line_start_x)
9942 goto cancel;
9943
9944 TRACE ((stderr, "trying display optimization 1\n"));
9945 w->cursor.vpos = -1;
9946 overlay_arrow_seen = 0;
9947 it.vpos = this_line_vpos;
9948 it.current_y = this_line_y;
9949 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9950 display_line (&it);
9951
9952 /* If line contains point, is not continued,
9953 and ends at same distance from eob as before, we win */
9954 if (w->cursor.vpos >= 0
9955 /* Line is not continued, otherwise this_line_start_pos
9956 would have been set to 0 in display_line. */
9957 && CHARPOS (this_line_start_pos)
9958 /* Line ends as before. */
9959 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9960 /* Line has same height as before. Otherwise other lines
9961 would have to be shifted up or down. */
9962 && this_line_pixel_height == line_height_before)
9963 {
9964 /* If this is not the window's last line, we must adjust
9965 the charstarts of the lines below. */
9966 if (it.current_y < it.last_visible_y)
9967 {
9968 struct glyph_row *row
9969 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
9970 int delta, delta_bytes;
9971
9972 if (Z - CHARPOS (tlendpos) == ZV)
9973 {
9974 /* This line ends at end of (accessible part of)
9975 buffer. There is no newline to count. */
9976 delta = (Z
9977 - CHARPOS (tlendpos)
9978 - MATRIX_ROW_START_CHARPOS (row));
9979 delta_bytes = (Z_BYTE
9980 - BYTEPOS (tlendpos)
9981 - MATRIX_ROW_START_BYTEPOS (row));
9982 }
9983 else
9984 {
9985 /* This line ends in a newline. Must take
9986 account of the newline and the rest of the
9987 text that follows. */
9988 delta = (Z
9989 - CHARPOS (tlendpos)
9990 - MATRIX_ROW_START_CHARPOS (row));
9991 delta_bytes = (Z_BYTE
9992 - BYTEPOS (tlendpos)
9993 - MATRIX_ROW_START_BYTEPOS (row));
9994 }
9995
9996 increment_matrix_positions (w->current_matrix,
9997 this_line_vpos + 1,
9998 w->current_matrix->nrows,
9999 delta, delta_bytes);
10000 }
10001
10002 /* If this row displays text now but previously didn't,
10003 or vice versa, w->window_end_vpos may have to be
10004 adjusted. */
10005 if ((it.glyph_row - 1)->displays_text_p)
10006 {
10007 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10008 XSETINT (w->window_end_vpos, this_line_vpos);
10009 }
10010 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10011 && this_line_vpos > 0)
10012 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10013 w->window_end_valid = Qnil;
10014
10015 /* Update hint: No need to try to scroll in update_window. */
10016 w->desired_matrix->no_scrolling_p = 1;
10017
10018 #if GLYPH_DEBUG
10019 *w->desired_matrix->method = 0;
10020 debug_method_add (w, "optimization 1");
10021 #endif
10022 #ifdef HAVE_WINDOW_SYSTEM
10023 update_window_fringes (w, 0);
10024 #endif
10025 goto update;
10026 }
10027 else
10028 goto cancel;
10029 }
10030 else if (/* Cursor position hasn't changed. */
10031 PT == XFASTINT (w->last_point)
10032 /* Make sure the cursor was last displayed
10033 in this window. Otherwise we have to reposition it. */
10034 && 0 <= w->cursor.vpos
10035 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10036 {
10037 if (!must_finish)
10038 {
10039 do_pending_window_change (1);
10040
10041 /* We used to always goto end_of_redisplay here, but this
10042 isn't enough if we have a blinking cursor. */
10043 if (w->cursor_off_p == w->last_cursor_off_p)
10044 goto end_of_redisplay;
10045 }
10046 goto update;
10047 }
10048 /* If highlighting the region, or if the cursor is in the echo area,
10049 then we can't just move the cursor. */
10050 else if (! (!NILP (Vtransient_mark_mode)
10051 && !NILP (current_buffer->mark_active))
10052 && (EQ (selected_window, current_buffer->last_selected_window)
10053 || highlight_nonselected_windows)
10054 && NILP (w->region_showing)
10055 && NILP (Vshow_trailing_whitespace)
10056 && !cursor_in_echo_area)
10057 {
10058 struct it it;
10059 struct glyph_row *row;
10060
10061 /* Skip from tlbufpos to PT and see where it is. Note that
10062 PT may be in invisible text. If so, we will end at the
10063 next visible position. */
10064 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10065 NULL, DEFAULT_FACE_ID);
10066 it.current_x = this_line_start_x;
10067 it.current_y = this_line_y;
10068 it.vpos = this_line_vpos;
10069
10070 /* The call to move_it_to stops in front of PT, but
10071 moves over before-strings. */
10072 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10073
10074 if (it.vpos == this_line_vpos
10075 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10076 row->enabled_p))
10077 {
10078 xassert (this_line_vpos == it.vpos);
10079 xassert (this_line_y == it.current_y);
10080 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10081 #if GLYPH_DEBUG
10082 *w->desired_matrix->method = 0;
10083 debug_method_add (w, "optimization 3");
10084 #endif
10085 goto update;
10086 }
10087 else
10088 goto cancel;
10089 }
10090
10091 cancel:
10092 /* Text changed drastically or point moved off of line. */
10093 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10094 }
10095
10096 CHARPOS (this_line_start_pos) = 0;
10097 consider_all_windows_p |= buffer_shared > 1;
10098 ++clear_face_cache_count;
10099
10100
10101 /* Build desired matrices, and update the display. If
10102 consider_all_windows_p is non-zero, do it for all windows on all
10103 frames. Otherwise do it for selected_window, only. */
10104
10105 if (consider_all_windows_p)
10106 {
10107 Lisp_Object tail, frame;
10108 int i, n = 0, size = 50;
10109 struct frame **updated
10110 = (struct frame **) alloca (size * sizeof *updated);
10111
10112 /* Clear the face cache eventually. */
10113 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10114 {
10115 clear_face_cache (0);
10116 clear_face_cache_count = 0;
10117 }
10118
10119 /* Recompute # windows showing selected buffer. This will be
10120 incremented each time such a window is displayed. */
10121 buffer_shared = 0;
10122
10123 FOR_EACH_FRAME (tail, frame)
10124 {
10125 struct frame *f = XFRAME (frame);
10126
10127 if (FRAME_WINDOW_P (f) || f == sf)
10128 {
10129 if (! EQ (frame, selected_frame))
10130 /* Select the frame, for the sake of frame-local
10131 variables. */
10132 select_frame_for_redisplay (frame);
10133
10134 #ifdef HAVE_WINDOW_SYSTEM
10135 if (clear_face_cache_count % 50 == 0
10136 && FRAME_WINDOW_P (f))
10137 clear_image_cache (f, 0);
10138 #endif /* HAVE_WINDOW_SYSTEM */
10139
10140 /* Mark all the scroll bars to be removed; we'll redeem
10141 the ones we want when we redisplay their windows. */
10142 if (condemn_scroll_bars_hook)
10143 condemn_scroll_bars_hook (f);
10144
10145 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10146 redisplay_windows (FRAME_ROOT_WINDOW (f));
10147
10148 /* Any scroll bars which redisplay_windows should have
10149 nuked should now go away. */
10150 if (judge_scroll_bars_hook)
10151 judge_scroll_bars_hook (f);
10152
10153 /* If fonts changed, display again. */
10154 /* ??? rms: I suspect it is a mistake to jump all the way
10155 back to retry here. It should just retry this frame. */
10156 if (fonts_changed_p)
10157 goto retry;
10158
10159 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10160 {
10161 /* See if we have to hscroll. */
10162 if (hscroll_windows (f->root_window))
10163 goto retry;
10164
10165 /* Prevent various kinds of signals during display
10166 update. stdio is not robust about handling
10167 signals, which can cause an apparent I/O
10168 error. */
10169 if (interrupt_input)
10170 unrequest_sigio ();
10171 STOP_POLLING;
10172
10173 /* Update the display. */
10174 set_window_update_flags (XWINDOW (f->root_window), 1);
10175 pause |= update_frame (f, 0, 0);
10176 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10177 if (pause)
10178 break;
10179 #endif
10180
10181 if (n == size)
10182 {
10183 int nbytes = size * sizeof *updated;
10184 struct frame **p = (struct frame **) alloca (2 * nbytes);
10185 bcopy (updated, p, nbytes);
10186 size *= 2;
10187 }
10188
10189 updated[n++] = f;
10190 }
10191 }
10192 }
10193
10194 if (!pause)
10195 {
10196 /* Do the mark_window_display_accurate after all windows have
10197 been redisplayed because this call resets flags in buffers
10198 which are needed for proper redisplay. */
10199 for (i = 0; i < n; ++i)
10200 {
10201 struct frame *f = updated[i];
10202 mark_window_display_accurate (f->root_window, 1);
10203 if (frame_up_to_date_hook)
10204 frame_up_to_date_hook (f);
10205 }
10206 }
10207 }
10208 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10209 {
10210 Lisp_Object mini_window;
10211 struct frame *mini_frame;
10212
10213 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10214 /* Use list_of_error, not Qerror, so that
10215 we catch only errors and don't run the debugger. */
10216 internal_condition_case_1 (redisplay_window_1, selected_window,
10217 list_of_error,
10218 redisplay_window_error);
10219
10220 /* Compare desired and current matrices, perform output. */
10221
10222 update:
10223 /* If fonts changed, display again. */
10224 if (fonts_changed_p)
10225 goto retry;
10226
10227 /* Prevent various kinds of signals during display update.
10228 stdio is not robust about handling signals,
10229 which can cause an apparent I/O error. */
10230 if (interrupt_input)
10231 unrequest_sigio ();
10232 STOP_POLLING;
10233
10234 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10235 {
10236 if (hscroll_windows (selected_window))
10237 goto retry;
10238
10239 XWINDOW (selected_window)->must_be_updated_p = 1;
10240 pause = update_frame (sf, 0, 0);
10241 }
10242
10243 /* We may have called echo_area_display at the top of this
10244 function. If the echo area is on another frame, that may
10245 have put text on a frame other than the selected one, so the
10246 above call to update_frame would not have caught it. Catch
10247 it here. */
10248 mini_window = FRAME_MINIBUF_WINDOW (sf);
10249 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10250
10251 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10252 {
10253 XWINDOW (mini_window)->must_be_updated_p = 1;
10254 pause |= update_frame (mini_frame, 0, 0);
10255 if (!pause && hscroll_windows (mini_window))
10256 goto retry;
10257 }
10258 }
10259
10260 /* If display was paused because of pending input, make sure we do a
10261 thorough update the next time. */
10262 if (pause)
10263 {
10264 /* Prevent the optimization at the beginning of
10265 redisplay_internal that tries a single-line update of the
10266 line containing the cursor in the selected window. */
10267 CHARPOS (this_line_start_pos) = 0;
10268
10269 /* Let the overlay arrow be updated the next time. */
10270 update_overlay_arrows (0);
10271
10272 /* If we pause after scrolling, some rows in the current
10273 matrices of some windows are not valid. */
10274 if (!WINDOW_FULL_WIDTH_P (w)
10275 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10276 update_mode_lines = 1;
10277 }
10278 else
10279 {
10280 if (!consider_all_windows_p)
10281 {
10282 /* This has already been done above if
10283 consider_all_windows_p is set. */
10284 mark_window_display_accurate_1 (w, 1);
10285
10286 /* Say overlay arrows are up to date. */
10287 update_overlay_arrows (1);
10288
10289 if (frame_up_to_date_hook != 0)
10290 frame_up_to_date_hook (sf);
10291 }
10292
10293 update_mode_lines = 0;
10294 windows_or_buffers_changed = 0;
10295 cursor_type_changed = 0;
10296 }
10297
10298 /* Start SIGIO interrupts coming again. Having them off during the
10299 code above makes it less likely one will discard output, but not
10300 impossible, since there might be stuff in the system buffer here.
10301 But it is much hairier to try to do anything about that. */
10302 if (interrupt_input)
10303 request_sigio ();
10304 RESUME_POLLING;
10305
10306 /* If a frame has become visible which was not before, redisplay
10307 again, so that we display it. Expose events for such a frame
10308 (which it gets when becoming visible) don't call the parts of
10309 redisplay constructing glyphs, so simply exposing a frame won't
10310 display anything in this case. So, we have to display these
10311 frames here explicitly. */
10312 if (!pause)
10313 {
10314 Lisp_Object tail, frame;
10315 int new_count = 0;
10316
10317 FOR_EACH_FRAME (tail, frame)
10318 {
10319 int this_is_visible = 0;
10320
10321 if (XFRAME (frame)->visible)
10322 this_is_visible = 1;
10323 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10324 if (XFRAME (frame)->visible)
10325 this_is_visible = 1;
10326
10327 if (this_is_visible)
10328 new_count++;
10329 }
10330
10331 if (new_count != number_of_visible_frames)
10332 windows_or_buffers_changed++;
10333 }
10334
10335 /* Change frame size now if a change is pending. */
10336 do_pending_window_change (1);
10337
10338 /* If we just did a pending size change, or have additional
10339 visible frames, redisplay again. */
10340 if (windows_or_buffers_changed && !pause)
10341 goto retry;
10342
10343 end_of_redisplay:
10344 unbind_to (count, Qnil);
10345 RESUME_POLLING;
10346 }
10347
10348
10349 /* Redisplay, but leave alone any recent echo area message unless
10350 another message has been requested in its place.
10351
10352 This is useful in situations where you need to redisplay but no
10353 user action has occurred, making it inappropriate for the message
10354 area to be cleared. See tracking_off and
10355 wait_reading_process_input for examples of these situations.
10356
10357 FROM_WHERE is an integer saying from where this function was
10358 called. This is useful for debugging. */
10359
10360 void
10361 redisplay_preserve_echo_area (from_where)
10362 int from_where;
10363 {
10364 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10365
10366 if (!NILP (echo_area_buffer[1]))
10367 {
10368 /* We have a previously displayed message, but no current
10369 message. Redisplay the previous message. */
10370 display_last_displayed_message_p = 1;
10371 redisplay_internal (1);
10372 display_last_displayed_message_p = 0;
10373 }
10374 else
10375 redisplay_internal (1);
10376 }
10377
10378
10379 /* Function registered with record_unwind_protect in
10380 redisplay_internal. Reset redisplaying_p to the value it had
10381 before redisplay_internal was called, and clear
10382 prevent_freeing_realized_faces_p. It also selects the previously
10383 selected frame. */
10384
10385 static Lisp_Object
10386 unwind_redisplay (val)
10387 Lisp_Object val;
10388 {
10389 Lisp_Object old_redisplaying_p, old_frame;
10390
10391 old_redisplaying_p = XCAR (val);
10392 redisplaying_p = XFASTINT (old_redisplaying_p);
10393 old_frame = XCDR (val);
10394 if (! EQ (old_frame, selected_frame))
10395 select_frame_for_redisplay (old_frame);
10396 return Qnil;
10397 }
10398
10399
10400 /* Mark the display of window W as accurate or inaccurate. If
10401 ACCURATE_P is non-zero mark display of W as accurate. If
10402 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10403 redisplay_internal is called. */
10404
10405 static void
10406 mark_window_display_accurate_1 (w, accurate_p)
10407 struct window *w;
10408 int accurate_p;
10409 {
10410 if (BUFFERP (w->buffer))
10411 {
10412 struct buffer *b = XBUFFER (w->buffer);
10413
10414 w->last_modified
10415 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10416 w->last_overlay_modified
10417 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10418 w->last_had_star
10419 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10420
10421 if (accurate_p)
10422 {
10423 b->clip_changed = 0;
10424 b->prevent_redisplay_optimizations_p = 0;
10425
10426 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10427 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10428 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10429 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10430
10431 w->current_matrix->buffer = b;
10432 w->current_matrix->begv = BUF_BEGV (b);
10433 w->current_matrix->zv = BUF_ZV (b);
10434
10435 w->last_cursor = w->cursor;
10436 w->last_cursor_off_p = w->cursor_off_p;
10437
10438 if (w == XWINDOW (selected_window))
10439 w->last_point = make_number (BUF_PT (b));
10440 else
10441 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10442 }
10443 }
10444
10445 if (accurate_p)
10446 {
10447 w->window_end_valid = w->buffer;
10448 #if 0 /* This is incorrect with variable-height lines. */
10449 xassert (XINT (w->window_end_vpos)
10450 < (WINDOW_TOTAL_LINES (w)
10451 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10452 #endif
10453 w->update_mode_line = Qnil;
10454 }
10455 }
10456
10457
10458 /* Mark the display of windows in the window tree rooted at WINDOW as
10459 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10460 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10461 be redisplayed the next time redisplay_internal is called. */
10462
10463 void
10464 mark_window_display_accurate (window, accurate_p)
10465 Lisp_Object window;
10466 int accurate_p;
10467 {
10468 struct window *w;
10469
10470 for (; !NILP (window); window = w->next)
10471 {
10472 w = XWINDOW (window);
10473 mark_window_display_accurate_1 (w, accurate_p);
10474
10475 if (!NILP (w->vchild))
10476 mark_window_display_accurate (w->vchild, accurate_p);
10477 if (!NILP (w->hchild))
10478 mark_window_display_accurate (w->hchild, accurate_p);
10479 }
10480
10481 if (accurate_p)
10482 {
10483 update_overlay_arrows (1);
10484 }
10485 else
10486 {
10487 /* Force a thorough redisplay the next time by setting
10488 last_arrow_position and last_arrow_string to t, which is
10489 unequal to any useful value of Voverlay_arrow_... */
10490 update_overlay_arrows (-1);
10491 }
10492 }
10493
10494
10495 /* Return value in display table DP (Lisp_Char_Table *) for character
10496 C. Since a display table doesn't have any parent, we don't have to
10497 follow parent. Do not call this function directly but use the
10498 macro DISP_CHAR_VECTOR. */
10499
10500 Lisp_Object
10501 disp_char_vector (dp, c)
10502 struct Lisp_Char_Table *dp;
10503 int c;
10504 {
10505 int code[4], i;
10506 Lisp_Object val;
10507
10508 if (SINGLE_BYTE_CHAR_P (c))
10509 return (dp->contents[c]);
10510
10511 SPLIT_CHAR (c, code[0], code[1], code[2]);
10512 if (code[1] < 32)
10513 code[1] = -1;
10514 else if (code[2] < 32)
10515 code[2] = -1;
10516
10517 /* Here, the possible range of code[0] (== charset ID) is
10518 128..max_charset. Since the top level char table contains data
10519 for multibyte characters after 256th element, we must increment
10520 code[0] by 128 to get a correct index. */
10521 code[0] += 128;
10522 code[3] = -1; /* anchor */
10523
10524 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10525 {
10526 val = dp->contents[code[i]];
10527 if (!SUB_CHAR_TABLE_P (val))
10528 return (NILP (val) ? dp->defalt : val);
10529 }
10530
10531 /* Here, val is a sub char table. We return the default value of
10532 it. */
10533 return (dp->defalt);
10534 }
10535
10536
10537 \f
10538 /***********************************************************************
10539 Window Redisplay
10540 ***********************************************************************/
10541
10542 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10543
10544 static void
10545 redisplay_windows (window)
10546 Lisp_Object window;
10547 {
10548 while (!NILP (window))
10549 {
10550 struct window *w = XWINDOW (window);
10551
10552 if (!NILP (w->hchild))
10553 redisplay_windows (w->hchild);
10554 else if (!NILP (w->vchild))
10555 redisplay_windows (w->vchild);
10556 else
10557 {
10558 displayed_buffer = XBUFFER (w->buffer);
10559 /* Use list_of_error, not Qerror, so that
10560 we catch only errors and don't run the debugger. */
10561 internal_condition_case_1 (redisplay_window_0, window,
10562 list_of_error,
10563 redisplay_window_error);
10564 }
10565
10566 window = w->next;
10567 }
10568 }
10569
10570 static Lisp_Object
10571 redisplay_window_error ()
10572 {
10573 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10574 return Qnil;
10575 }
10576
10577 static Lisp_Object
10578 redisplay_window_0 (window)
10579 Lisp_Object window;
10580 {
10581 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10582 redisplay_window (window, 0);
10583 return Qnil;
10584 }
10585
10586 static Lisp_Object
10587 redisplay_window_1 (window)
10588 Lisp_Object window;
10589 {
10590 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10591 redisplay_window (window, 1);
10592 return Qnil;
10593 }
10594 \f
10595
10596 /* Increment GLYPH until it reaches END or CONDITION fails while
10597 adding (GLYPH)->pixel_width to X. */
10598
10599 #define SKIP_GLYPHS(glyph, end, x, condition) \
10600 do \
10601 { \
10602 (x) += (glyph)->pixel_width; \
10603 ++(glyph); \
10604 } \
10605 while ((glyph) < (end) && (condition))
10606
10607
10608 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10609 DELTA is the number of bytes by which positions recorded in ROW
10610 differ from current buffer positions. */
10611
10612 void
10613 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10614 struct window *w;
10615 struct glyph_row *row;
10616 struct glyph_matrix *matrix;
10617 int delta, delta_bytes, dy, dvpos;
10618 {
10619 struct glyph *glyph = row->glyphs[TEXT_AREA];
10620 struct glyph *end = glyph + row->used[TEXT_AREA];
10621 /* The first glyph that starts a sequence of glyphs from string. */
10622 struct glyph *string_start;
10623 /* The X coordinate of string_start. */
10624 int string_start_x;
10625 /* The last known character position. */
10626 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10627 /* The last known character position before string_start. */
10628 int string_before_pos;
10629 int x = row->x;
10630 int pt_old = PT - delta;
10631
10632 /* Skip over glyphs not having an object at the start of the row.
10633 These are special glyphs like truncation marks on terminal
10634 frames. */
10635 if (row->displays_text_p)
10636 while (glyph < end
10637 && INTEGERP (glyph->object)
10638 && glyph->charpos < 0)
10639 {
10640 x += glyph->pixel_width;
10641 ++glyph;
10642 }
10643
10644 string_start = NULL;
10645 while (glyph < end
10646 && !INTEGERP (glyph->object)
10647 && (!BUFFERP (glyph->object)
10648 || (last_pos = glyph->charpos) < pt_old))
10649 {
10650 if (! STRINGP (glyph->object))
10651 {
10652 string_start = NULL;
10653 x += glyph->pixel_width;
10654 ++glyph;
10655 }
10656 else
10657 {
10658 string_before_pos = last_pos;
10659 string_start = glyph;
10660 string_start_x = x;
10661 /* Skip all glyphs from string. */
10662 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10663 }
10664 }
10665
10666 if (string_start
10667 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10668 {
10669 /* We may have skipped over point because the previous glyphs
10670 are from string. As there's no easy way to know the
10671 character position of the current glyph, find the correct
10672 glyph on point by scanning from string_start again. */
10673 Lisp_Object limit;
10674 Lisp_Object string;
10675 int pos;
10676
10677 limit = make_number (pt_old + 1);
10678 end = glyph;
10679 glyph = string_start;
10680 x = string_start_x;
10681 string = glyph->object;
10682 pos = string_buffer_position (w, string, string_before_pos);
10683 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10684 because we always put cursor after overlay strings. */
10685 while (pos == 0 && glyph < end)
10686 {
10687 string = glyph->object;
10688 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10689 if (glyph < end)
10690 pos = string_buffer_position (w, glyph->object, string_before_pos);
10691 }
10692
10693 while (glyph < end)
10694 {
10695 pos = XINT (Fnext_single_char_property_change
10696 (make_number (pos), Qdisplay, Qnil, limit));
10697 if (pos > pt_old)
10698 break;
10699 /* Skip glyphs from the same string. */
10700 string = glyph->object;
10701 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10702 /* Skip glyphs from an overlay. */
10703 while (glyph < end
10704 && ! string_buffer_position (w, glyph->object, pos))
10705 {
10706 string = glyph->object;
10707 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10708 }
10709 }
10710 }
10711
10712 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10713 w->cursor.x = x;
10714 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10715 w->cursor.y = row->y + dy;
10716
10717 if (w == XWINDOW (selected_window))
10718 {
10719 if (!row->continued_p
10720 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10721 && row->x == 0)
10722 {
10723 this_line_buffer = XBUFFER (w->buffer);
10724
10725 CHARPOS (this_line_start_pos)
10726 = MATRIX_ROW_START_CHARPOS (row) + delta;
10727 BYTEPOS (this_line_start_pos)
10728 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10729
10730 CHARPOS (this_line_end_pos)
10731 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10732 BYTEPOS (this_line_end_pos)
10733 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10734
10735 this_line_y = w->cursor.y;
10736 this_line_pixel_height = row->height;
10737 this_line_vpos = w->cursor.vpos;
10738 this_line_start_x = row->x;
10739 }
10740 else
10741 CHARPOS (this_line_start_pos) = 0;
10742 }
10743 }
10744
10745
10746 /* Run window scroll functions, if any, for WINDOW with new window
10747 start STARTP. Sets the window start of WINDOW to that position.
10748
10749 We assume that the window's buffer is really current. */
10750
10751 static INLINE struct text_pos
10752 run_window_scroll_functions (window, startp)
10753 Lisp_Object window;
10754 struct text_pos startp;
10755 {
10756 struct window *w = XWINDOW (window);
10757 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10758
10759 if (current_buffer != XBUFFER (w->buffer))
10760 abort ();
10761
10762 if (!NILP (Vwindow_scroll_functions))
10763 {
10764 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10765 make_number (CHARPOS (startp)));
10766 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10767 /* In case the hook functions switch buffers. */
10768 if (current_buffer != XBUFFER (w->buffer))
10769 set_buffer_internal_1 (XBUFFER (w->buffer));
10770 }
10771
10772 return startp;
10773 }
10774
10775
10776 /* Make sure the line containing the cursor is fully visible.
10777 A value of 1 means there is nothing to be done.
10778 (Either the line is fully visible, or it cannot be made so,
10779 or we cannot tell.)
10780
10781 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10782 is higher than window.
10783
10784 A value of 0 means the caller should do scrolling
10785 as if point had gone off the screen. */
10786
10787 static int
10788 make_cursor_line_fully_visible (w, force_p)
10789 struct window *w;
10790 int force_p;
10791 {
10792 struct glyph_matrix *matrix;
10793 struct glyph_row *row;
10794 int window_height;
10795
10796 /* It's not always possible to find the cursor, e.g, when a window
10797 is full of overlay strings. Don't do anything in that case. */
10798 if (w->cursor.vpos < 0)
10799 return 1;
10800
10801 matrix = w->desired_matrix;
10802 row = MATRIX_ROW (matrix, w->cursor.vpos);
10803
10804 /* If the cursor row is not partially visible, there's nothing to do. */
10805 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10806 return 1;
10807
10808 /* If the row the cursor is in is taller than the window's height,
10809 it's not clear what to do, so do nothing. */
10810 window_height = window_box_height (w);
10811 if (row->height >= window_height)
10812 {
10813 if (!force_p || w->vscroll)
10814 return 1;
10815 }
10816 return 0;
10817
10818 #if 0
10819 /* This code used to try to scroll the window just enough to make
10820 the line visible. It returned 0 to say that the caller should
10821 allocate larger glyph matrices. */
10822
10823 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10824 {
10825 int dy = row->height - row->visible_height;
10826 w->vscroll = 0;
10827 w->cursor.y += dy;
10828 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10829 }
10830 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10831 {
10832 int dy = - (row->height - row->visible_height);
10833 w->vscroll = dy;
10834 w->cursor.y += dy;
10835 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10836 }
10837
10838 /* When we change the cursor y-position of the selected window,
10839 change this_line_y as well so that the display optimization for
10840 the cursor line of the selected window in redisplay_internal uses
10841 the correct y-position. */
10842 if (w == XWINDOW (selected_window))
10843 this_line_y = w->cursor.y;
10844
10845 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10846 redisplay with larger matrices. */
10847 if (matrix->nrows < required_matrix_height (w))
10848 {
10849 fonts_changed_p = 1;
10850 return 0;
10851 }
10852
10853 return 1;
10854 #endif /* 0 */
10855 }
10856
10857
10858 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10859 non-zero means only WINDOW is redisplayed in redisplay_internal.
10860 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10861 in redisplay_window to bring a partially visible line into view in
10862 the case that only the cursor has moved.
10863
10864 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10865 last screen line's vertical height extends past the end of the screen.
10866
10867 Value is
10868
10869 1 if scrolling succeeded
10870
10871 0 if scrolling didn't find point.
10872
10873 -1 if new fonts have been loaded so that we must interrupt
10874 redisplay, adjust glyph matrices, and try again. */
10875
10876 enum
10877 {
10878 SCROLLING_SUCCESS,
10879 SCROLLING_FAILED,
10880 SCROLLING_NEED_LARGER_MATRICES
10881 };
10882
10883 static int
10884 try_scrolling (window, just_this_one_p, scroll_conservatively,
10885 scroll_step, temp_scroll_step, last_line_misfit)
10886 Lisp_Object window;
10887 int just_this_one_p;
10888 EMACS_INT scroll_conservatively, scroll_step;
10889 int temp_scroll_step;
10890 int last_line_misfit;
10891 {
10892 struct window *w = XWINDOW (window);
10893 struct frame *f = XFRAME (w->frame);
10894 struct text_pos scroll_margin_pos;
10895 struct text_pos pos;
10896 struct text_pos startp;
10897 struct it it;
10898 Lisp_Object window_end;
10899 int this_scroll_margin;
10900 int dy = 0;
10901 int scroll_max;
10902 int rc;
10903 int amount_to_scroll = 0;
10904 Lisp_Object aggressive;
10905 int height;
10906 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
10907
10908 #if GLYPH_DEBUG
10909 debug_method_add (w, "try_scrolling");
10910 #endif
10911
10912 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10913
10914 /* Compute scroll margin height in pixels. We scroll when point is
10915 within this distance from the top or bottom of the window. */
10916 if (scroll_margin > 0)
10917 {
10918 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10919 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10920 }
10921 else
10922 this_scroll_margin = 0;
10923
10924 /* Force scroll_conservatively to have a reasonable value so it doesn't
10925 cause an overflow while computing how much to scroll. */
10926 if (scroll_conservatively)
10927 scroll_conservatively = min (scroll_conservatively,
10928 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
10929
10930 /* Compute how much we should try to scroll maximally to bring point
10931 into view. */
10932 if (scroll_step || scroll_conservatively || temp_scroll_step)
10933 scroll_max = max (scroll_step,
10934 max (scroll_conservatively, temp_scroll_step));
10935 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10936 || NUMBERP (current_buffer->scroll_up_aggressively))
10937 /* We're trying to scroll because of aggressive scrolling
10938 but no scroll_step is set. Choose an arbitrary one. Maybe
10939 there should be a variable for this. */
10940 scroll_max = 10;
10941 else
10942 scroll_max = 0;
10943 scroll_max *= FRAME_LINE_HEIGHT (f);
10944
10945 /* Decide whether we have to scroll down. Start at the window end
10946 and move this_scroll_margin up to find the position of the scroll
10947 margin. */
10948 window_end = Fwindow_end (window, Qt);
10949
10950 too_near_end:
10951
10952 CHARPOS (scroll_margin_pos) = XINT (window_end);
10953 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10954
10955 if (this_scroll_margin || extra_scroll_margin_lines)
10956 {
10957 start_display (&it, w, scroll_margin_pos);
10958 if (this_scroll_margin)
10959 move_it_vertically (&it, - this_scroll_margin);
10960 if (extra_scroll_margin_lines)
10961 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
10962 scroll_margin_pos = it.current.pos;
10963 }
10964
10965 if (PT >= CHARPOS (scroll_margin_pos))
10966 {
10967 int y0;
10968
10969 /* Point is in the scroll margin at the bottom of the window, or
10970 below. Compute a new window start that makes point visible. */
10971
10972 /* Compute the distance from the scroll margin to PT.
10973 Give up if the distance is greater than scroll_max. */
10974 start_display (&it, w, scroll_margin_pos);
10975 y0 = it.current_y;
10976 move_it_to (&it, PT, 0, it.last_visible_y, -1,
10977 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10978
10979 /* To make point visible, we have to move the window start
10980 down so that the line the cursor is in is visible, which
10981 means we have to add in the height of the cursor line. */
10982 dy = line_bottom_y (&it) - y0;
10983
10984 if (dy > scroll_max)
10985 return SCROLLING_FAILED;
10986
10987 /* Move the window start down. If scrolling conservatively,
10988 move it just enough down to make point visible. If
10989 scroll_step is set, move it down by scroll_step. */
10990 start_display (&it, w, startp);
10991
10992 if (scroll_conservatively)
10993 /* Set AMOUNT_TO_SCROLL to at least one line,
10994 and at most scroll_conservatively lines. */
10995 amount_to_scroll
10996 = min (max (dy, FRAME_LINE_HEIGHT (f)),
10997 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
10998 else if (scroll_step || temp_scroll_step)
10999 amount_to_scroll = scroll_max;
11000 else
11001 {
11002 aggressive = current_buffer->scroll_up_aggressively;
11003 height = WINDOW_BOX_TEXT_HEIGHT (w);
11004 if (NUMBERP (aggressive))
11005 {
11006 double float_amount = XFLOATINT (aggressive) * height;
11007 amount_to_scroll = float_amount;
11008 if (amount_to_scroll == 0 && float_amount > 0)
11009 amount_to_scroll = 1;
11010 }
11011 }
11012
11013 if (amount_to_scroll <= 0)
11014 return SCROLLING_FAILED;
11015
11016 /* If moving by amount_to_scroll leaves STARTP unchanged,
11017 move it down one screen line. */
11018
11019 move_it_vertically (&it, amount_to_scroll);
11020 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11021 move_it_by_lines (&it, 1, 1);
11022 startp = it.current.pos;
11023 }
11024 else
11025 {
11026 /* See if point is inside the scroll margin at the top of the
11027 window. */
11028 scroll_margin_pos = startp;
11029 if (this_scroll_margin)
11030 {
11031 start_display (&it, w, startp);
11032 move_it_vertically (&it, this_scroll_margin);
11033 scroll_margin_pos = it.current.pos;
11034 }
11035
11036 if (PT < CHARPOS (scroll_margin_pos))
11037 {
11038 /* Point is in the scroll margin at the top of the window or
11039 above what is displayed in the window. */
11040 int y0;
11041
11042 /* Compute the vertical distance from PT to the scroll
11043 margin position. Give up if distance is greater than
11044 scroll_max. */
11045 SET_TEXT_POS (pos, PT, PT_BYTE);
11046 start_display (&it, w, pos);
11047 y0 = it.current_y;
11048 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11049 it.last_visible_y, -1,
11050 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11051 dy = it.current_y - y0;
11052 if (dy > scroll_max)
11053 return SCROLLING_FAILED;
11054
11055 /* Compute new window start. */
11056 start_display (&it, w, startp);
11057
11058 if (scroll_conservatively)
11059 amount_to_scroll =
11060 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11061 else if (scroll_step || temp_scroll_step)
11062 amount_to_scroll = scroll_max;
11063 else
11064 {
11065 aggressive = current_buffer->scroll_down_aggressively;
11066 height = WINDOW_BOX_TEXT_HEIGHT (w);
11067 if (NUMBERP (aggressive))
11068 {
11069 double float_amount = XFLOATINT (aggressive) * height;
11070 amount_to_scroll = float_amount;
11071 if (amount_to_scroll == 0 && float_amount > 0)
11072 amount_to_scroll = 1;
11073 }
11074 }
11075
11076 if (amount_to_scroll <= 0)
11077 return SCROLLING_FAILED;
11078
11079 move_it_vertically (&it, - amount_to_scroll);
11080 startp = it.current.pos;
11081 }
11082 }
11083
11084 /* Run window scroll functions. */
11085 startp = run_window_scroll_functions (window, startp);
11086
11087 /* Display the window. Give up if new fonts are loaded, or if point
11088 doesn't appear. */
11089 if (!try_window (window, startp))
11090 rc = SCROLLING_NEED_LARGER_MATRICES;
11091 else if (w->cursor.vpos < 0)
11092 {
11093 clear_glyph_matrix (w->desired_matrix);
11094 rc = SCROLLING_FAILED;
11095 }
11096 else
11097 {
11098 /* Maybe forget recorded base line for line number display. */
11099 if (!just_this_one_p
11100 || current_buffer->clip_changed
11101 || BEG_UNCHANGED < CHARPOS (startp))
11102 w->base_line_number = Qnil;
11103
11104 /* If cursor ends up on a partially visible line,
11105 treat that as being off the bottom of the screen. */
11106 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11107 {
11108 clear_glyph_matrix (w->desired_matrix);
11109 ++extra_scroll_margin_lines;
11110 goto too_near_end;
11111 }
11112 rc = SCROLLING_SUCCESS;
11113 }
11114
11115 return rc;
11116 }
11117
11118
11119 /* Compute a suitable window start for window W if display of W starts
11120 on a continuation line. Value is non-zero if a new window start
11121 was computed.
11122
11123 The new window start will be computed, based on W's width, starting
11124 from the start of the continued line. It is the start of the
11125 screen line with the minimum distance from the old start W->start. */
11126
11127 static int
11128 compute_window_start_on_continuation_line (w)
11129 struct window *w;
11130 {
11131 struct text_pos pos, start_pos;
11132 int window_start_changed_p = 0;
11133
11134 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11135
11136 /* If window start is on a continuation line... Window start may be
11137 < BEGV in case there's invisible text at the start of the
11138 buffer (M-x rmail, for example). */
11139 if (CHARPOS (start_pos) > BEGV
11140 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11141 {
11142 struct it it;
11143 struct glyph_row *row;
11144
11145 /* Handle the case that the window start is out of range. */
11146 if (CHARPOS (start_pos) < BEGV)
11147 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11148 else if (CHARPOS (start_pos) > ZV)
11149 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11150
11151 /* Find the start of the continued line. This should be fast
11152 because scan_buffer is fast (newline cache). */
11153 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11154 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11155 row, DEFAULT_FACE_ID);
11156 reseat_at_previous_visible_line_start (&it);
11157
11158 /* If the line start is "too far" away from the window start,
11159 say it takes too much time to compute a new window start. */
11160 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11161 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11162 {
11163 int min_distance, distance;
11164
11165 /* Move forward by display lines to find the new window
11166 start. If window width was enlarged, the new start can
11167 be expected to be > the old start. If window width was
11168 decreased, the new window start will be < the old start.
11169 So, we're looking for the display line start with the
11170 minimum distance from the old window start. */
11171 pos = it.current.pos;
11172 min_distance = INFINITY;
11173 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11174 distance < min_distance)
11175 {
11176 min_distance = distance;
11177 pos = it.current.pos;
11178 move_it_by_lines (&it, 1, 0);
11179 }
11180
11181 /* Set the window start there. */
11182 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11183 window_start_changed_p = 1;
11184 }
11185 }
11186
11187 return window_start_changed_p;
11188 }
11189
11190
11191 /* Try cursor movement in case text has not changed in window WINDOW,
11192 with window start STARTP. Value is
11193
11194 CURSOR_MOVEMENT_SUCCESS if successful
11195
11196 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11197
11198 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11199 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11200 we want to scroll as if scroll-step were set to 1. See the code.
11201
11202 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11203 which case we have to abort this redisplay, and adjust matrices
11204 first. */
11205
11206 enum
11207 {
11208 CURSOR_MOVEMENT_SUCCESS,
11209 CURSOR_MOVEMENT_CANNOT_BE_USED,
11210 CURSOR_MOVEMENT_MUST_SCROLL,
11211 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11212 };
11213
11214 static int
11215 try_cursor_movement (window, startp, scroll_step)
11216 Lisp_Object window;
11217 struct text_pos startp;
11218 int *scroll_step;
11219 {
11220 struct window *w = XWINDOW (window);
11221 struct frame *f = XFRAME (w->frame);
11222 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11223
11224 #if GLYPH_DEBUG
11225 if (inhibit_try_cursor_movement)
11226 return rc;
11227 #endif
11228
11229 /* Handle case where text has not changed, only point, and it has
11230 not moved off the frame. */
11231 if (/* Point may be in this window. */
11232 PT >= CHARPOS (startp)
11233 /* Selective display hasn't changed. */
11234 && !current_buffer->clip_changed
11235 /* Function force-mode-line-update is used to force a thorough
11236 redisplay. It sets either windows_or_buffers_changed or
11237 update_mode_lines. So don't take a shortcut here for these
11238 cases. */
11239 && !update_mode_lines
11240 && !windows_or_buffers_changed
11241 && !cursor_type_changed
11242 /* Can't use this case if highlighting a region. When a
11243 region exists, cursor movement has to do more than just
11244 set the cursor. */
11245 && !(!NILP (Vtransient_mark_mode)
11246 && !NILP (current_buffer->mark_active))
11247 && NILP (w->region_showing)
11248 && NILP (Vshow_trailing_whitespace)
11249 /* Right after splitting windows, last_point may be nil. */
11250 && INTEGERP (w->last_point)
11251 /* This code is not used for mini-buffer for the sake of the case
11252 of redisplaying to replace an echo area message; since in
11253 that case the mini-buffer contents per se are usually
11254 unchanged. This code is of no real use in the mini-buffer
11255 since the handling of this_line_start_pos, etc., in redisplay
11256 handles the same cases. */
11257 && !EQ (window, minibuf_window)
11258 /* When splitting windows or for new windows, it happens that
11259 redisplay is called with a nil window_end_vpos or one being
11260 larger than the window. This should really be fixed in
11261 window.c. I don't have this on my list, now, so we do
11262 approximately the same as the old redisplay code. --gerd. */
11263 && INTEGERP (w->window_end_vpos)
11264 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11265 && (FRAME_WINDOW_P (f)
11266 || !overlay_arrow_in_current_buffer_p ()))
11267 {
11268 int this_scroll_margin;
11269 struct glyph_row *row = NULL;
11270
11271 #if GLYPH_DEBUG
11272 debug_method_add (w, "cursor movement");
11273 #endif
11274
11275 /* Scroll if point within this distance from the top or bottom
11276 of the window. This is a pixel value. */
11277 this_scroll_margin = max (0, scroll_margin);
11278 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11279 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11280
11281 /* Start with the row the cursor was displayed during the last
11282 not paused redisplay. Give up if that row is not valid. */
11283 if (w->last_cursor.vpos < 0
11284 || w->last_cursor.vpos >= w->current_matrix->nrows)
11285 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11286 else
11287 {
11288 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11289 if (row->mode_line_p)
11290 ++row;
11291 if (!row->enabled_p)
11292 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11293 }
11294
11295 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11296 {
11297 int scroll_p = 0;
11298 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11299
11300 if (PT > XFASTINT (w->last_point))
11301 {
11302 /* Point has moved forward. */
11303 while (MATRIX_ROW_END_CHARPOS (row) < PT
11304 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11305 {
11306 xassert (row->enabled_p);
11307 ++row;
11308 }
11309
11310 /* The end position of a row equals the start position
11311 of the next row. If PT is there, we would rather
11312 display it in the next line. */
11313 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11314 && MATRIX_ROW_END_CHARPOS (row) == PT
11315 && !cursor_row_p (w, row))
11316 ++row;
11317
11318 /* If within the scroll margin, scroll. Note that
11319 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11320 the next line would be drawn, and that
11321 this_scroll_margin can be zero. */
11322 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11323 || PT > MATRIX_ROW_END_CHARPOS (row)
11324 /* Line is completely visible last line in window
11325 and PT is to be set in the next line. */
11326 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11327 && PT == MATRIX_ROW_END_CHARPOS (row)
11328 && !row->ends_at_zv_p
11329 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11330 scroll_p = 1;
11331 }
11332 else if (PT < XFASTINT (w->last_point))
11333 {
11334 /* Cursor has to be moved backward. Note that PT >=
11335 CHARPOS (startp) because of the outer
11336 if-statement. */
11337 while (!row->mode_line_p
11338 && (MATRIX_ROW_START_CHARPOS (row) > PT
11339 || (MATRIX_ROW_START_CHARPOS (row) == PT
11340 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11341 && (row->y > this_scroll_margin
11342 || CHARPOS (startp) == BEGV))
11343 {
11344 xassert (row->enabled_p);
11345 --row;
11346 }
11347
11348 /* Consider the following case: Window starts at BEGV,
11349 there is invisible, intangible text at BEGV, so that
11350 display starts at some point START > BEGV. It can
11351 happen that we are called with PT somewhere between
11352 BEGV and START. Try to handle that case. */
11353 if (row < w->current_matrix->rows
11354 || row->mode_line_p)
11355 {
11356 row = w->current_matrix->rows;
11357 if (row->mode_line_p)
11358 ++row;
11359 }
11360
11361 /* Due to newlines in overlay strings, we may have to
11362 skip forward over overlay strings. */
11363 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11364 && MATRIX_ROW_END_CHARPOS (row) == PT
11365 && !cursor_row_p (w, row))
11366 ++row;
11367
11368 /* If within the scroll margin, scroll. */
11369 if (row->y < this_scroll_margin
11370 && CHARPOS (startp) != BEGV)
11371 scroll_p = 1;
11372 }
11373
11374 if (PT < MATRIX_ROW_START_CHARPOS (row)
11375 || PT > MATRIX_ROW_END_CHARPOS (row))
11376 {
11377 /* if PT is not in the glyph row, give up. */
11378 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11379 }
11380 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11381 {
11382 if (PT == MATRIX_ROW_END_CHARPOS (row)
11383 && !row->ends_at_zv_p
11384 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11385 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11386 else if (row->height > window_box_height (w))
11387 {
11388 /* If we end up in a partially visible line, let's
11389 make it fully visible, except when it's taller
11390 than the window, in which case we can't do much
11391 about it. */
11392 *scroll_step = 1;
11393 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11394 }
11395 else
11396 {
11397 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11398 if (!make_cursor_line_fully_visible (w, 0))
11399 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11400 else
11401 rc = CURSOR_MOVEMENT_SUCCESS;
11402 }
11403 }
11404 else if (scroll_p)
11405 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11406 else
11407 {
11408 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11409 rc = CURSOR_MOVEMENT_SUCCESS;
11410 }
11411 }
11412 }
11413
11414 return rc;
11415 }
11416
11417 void
11418 set_vertical_scroll_bar (w)
11419 struct window *w;
11420 {
11421 int start, end, whole;
11422
11423 /* Calculate the start and end positions for the current window.
11424 At some point, it would be nice to choose between scrollbars
11425 which reflect the whole buffer size, with special markers
11426 indicating narrowing, and scrollbars which reflect only the
11427 visible region.
11428
11429 Note that mini-buffers sometimes aren't displaying any text. */
11430 if (!MINI_WINDOW_P (w)
11431 || (w == XWINDOW (minibuf_window)
11432 && NILP (echo_area_buffer[0])))
11433 {
11434 struct buffer *buf = XBUFFER (w->buffer);
11435 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11436 start = marker_position (w->start) - BUF_BEGV (buf);
11437 /* I don't think this is guaranteed to be right. For the
11438 moment, we'll pretend it is. */
11439 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11440
11441 if (end < start)
11442 end = start;
11443 if (whole < (end - start))
11444 whole = end - start;
11445 }
11446 else
11447 start = end = whole = 0;
11448
11449 /* Indicate what this scroll bar ought to be displaying now. */
11450 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11451 }
11452
11453
11454 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11455 selected_window is redisplayed.
11456
11457 We can return without actually redisplaying the window if
11458 fonts_changed_p is nonzero. In that case, redisplay_internal will
11459 retry. */
11460
11461 static void
11462 redisplay_window (window, just_this_one_p)
11463 Lisp_Object window;
11464 int just_this_one_p;
11465 {
11466 struct window *w = XWINDOW (window);
11467 struct frame *f = XFRAME (w->frame);
11468 struct buffer *buffer = XBUFFER (w->buffer);
11469 struct buffer *old = current_buffer;
11470 struct text_pos lpoint, opoint, startp;
11471 int update_mode_line;
11472 int tem;
11473 struct it it;
11474 /* Record it now because it's overwritten. */
11475 int current_matrix_up_to_date_p = 0;
11476 int used_current_matrix_p = 0;
11477 /* This is less strict than current_matrix_up_to_date_p.
11478 It indictes that the buffer contents and narrowing are unchanged. */
11479 int buffer_unchanged_p = 0;
11480 int temp_scroll_step = 0;
11481 int count = SPECPDL_INDEX ();
11482 int rc;
11483 int centering_position;
11484 int last_line_misfit = 0;
11485
11486 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11487 opoint = lpoint;
11488
11489 /* W must be a leaf window here. */
11490 xassert (!NILP (w->buffer));
11491 #if GLYPH_DEBUG
11492 *w->desired_matrix->method = 0;
11493 #endif
11494
11495 specbind (Qinhibit_point_motion_hooks, Qt);
11496
11497 reconsider_clip_changes (w, buffer);
11498
11499 /* Has the mode line to be updated? */
11500 update_mode_line = (!NILP (w->update_mode_line)
11501 || update_mode_lines
11502 || buffer->clip_changed
11503 || buffer->prevent_redisplay_optimizations_p);
11504
11505 if (MINI_WINDOW_P (w))
11506 {
11507 if (w == XWINDOW (echo_area_window)
11508 && !NILP (echo_area_buffer[0]))
11509 {
11510 if (update_mode_line)
11511 /* We may have to update a tty frame's menu bar or a
11512 tool-bar. Example `M-x C-h C-h C-g'. */
11513 goto finish_menu_bars;
11514 else
11515 /* We've already displayed the echo area glyphs in this window. */
11516 goto finish_scroll_bars;
11517 }
11518 else if ((w != XWINDOW (minibuf_window)
11519 || minibuf_level == 0)
11520 /* When buffer is nonempty, redisplay window normally. */
11521 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11522 /* Quail displays non-mini buffers in minibuffer window.
11523 In that case, redisplay the window normally. */
11524 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11525 {
11526 /* W is a mini-buffer window, but it's not active, so clear
11527 it. */
11528 int yb = window_text_bottom_y (w);
11529 struct glyph_row *row;
11530 int y;
11531
11532 for (y = 0, row = w->desired_matrix->rows;
11533 y < yb;
11534 y += row->height, ++row)
11535 blank_row (w, row, y);
11536 goto finish_scroll_bars;
11537 }
11538
11539 clear_glyph_matrix (w->desired_matrix);
11540 }
11541
11542 /* Otherwise set up data on this window; select its buffer and point
11543 value. */
11544 /* Really select the buffer, for the sake of buffer-local
11545 variables. */
11546 set_buffer_internal_1 (XBUFFER (w->buffer));
11547 SET_TEXT_POS (opoint, PT, PT_BYTE);
11548
11549 current_matrix_up_to_date_p
11550 = (!NILP (w->window_end_valid)
11551 && !current_buffer->clip_changed
11552 && !current_buffer->prevent_redisplay_optimizations_p
11553 && XFASTINT (w->last_modified) >= MODIFF
11554 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11555
11556 buffer_unchanged_p
11557 = (!NILP (w->window_end_valid)
11558 && !current_buffer->clip_changed
11559 && XFASTINT (w->last_modified) >= MODIFF
11560 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11561
11562 /* When windows_or_buffers_changed is non-zero, we can't rely on
11563 the window end being valid, so set it to nil there. */
11564 if (windows_or_buffers_changed)
11565 {
11566 /* If window starts on a continuation line, maybe adjust the
11567 window start in case the window's width changed. */
11568 if (XMARKER (w->start)->buffer == current_buffer)
11569 compute_window_start_on_continuation_line (w);
11570
11571 w->window_end_valid = Qnil;
11572 }
11573
11574 /* Some sanity checks. */
11575 CHECK_WINDOW_END (w);
11576 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11577 abort ();
11578 if (BYTEPOS (opoint) < CHARPOS (opoint))
11579 abort ();
11580
11581 /* If %c is in mode line, update it if needed. */
11582 if (!NILP (w->column_number_displayed)
11583 /* This alternative quickly identifies a common case
11584 where no change is needed. */
11585 && !(PT == XFASTINT (w->last_point)
11586 && XFASTINT (w->last_modified) >= MODIFF
11587 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11588 && (XFASTINT (w->column_number_displayed)
11589 != (int) current_column ())) /* iftc */
11590 update_mode_line = 1;
11591
11592 /* Count number of windows showing the selected buffer. An indirect
11593 buffer counts as its base buffer. */
11594 if (!just_this_one_p)
11595 {
11596 struct buffer *current_base, *window_base;
11597 current_base = current_buffer;
11598 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11599 if (current_base->base_buffer)
11600 current_base = current_base->base_buffer;
11601 if (window_base->base_buffer)
11602 window_base = window_base->base_buffer;
11603 if (current_base == window_base)
11604 buffer_shared++;
11605 }
11606
11607 /* Point refers normally to the selected window. For any other
11608 window, set up appropriate value. */
11609 if (!EQ (window, selected_window))
11610 {
11611 int new_pt = XMARKER (w->pointm)->charpos;
11612 int new_pt_byte = marker_byte_position (w->pointm);
11613 if (new_pt < BEGV)
11614 {
11615 new_pt = BEGV;
11616 new_pt_byte = BEGV_BYTE;
11617 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11618 }
11619 else if (new_pt > (ZV - 1))
11620 {
11621 new_pt = ZV;
11622 new_pt_byte = ZV_BYTE;
11623 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11624 }
11625
11626 /* We don't use SET_PT so that the point-motion hooks don't run. */
11627 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11628 }
11629
11630 /* If any of the character widths specified in the display table
11631 have changed, invalidate the width run cache. It's true that
11632 this may be a bit late to catch such changes, but the rest of
11633 redisplay goes (non-fatally) haywire when the display table is
11634 changed, so why should we worry about doing any better? */
11635 if (current_buffer->width_run_cache)
11636 {
11637 struct Lisp_Char_Table *disptab = buffer_display_table ();
11638
11639 if (! disptab_matches_widthtab (disptab,
11640 XVECTOR (current_buffer->width_table)))
11641 {
11642 invalidate_region_cache (current_buffer,
11643 current_buffer->width_run_cache,
11644 BEG, Z);
11645 recompute_width_table (current_buffer, disptab);
11646 }
11647 }
11648
11649 /* If window-start is screwed up, choose a new one. */
11650 if (XMARKER (w->start)->buffer != current_buffer)
11651 goto recenter;
11652
11653 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11654
11655 /* If someone specified a new starting point but did not insist,
11656 check whether it can be used. */
11657 if (!NILP (w->optional_new_start)
11658 && CHARPOS (startp) >= BEGV
11659 && CHARPOS (startp) <= ZV)
11660 {
11661 w->optional_new_start = Qnil;
11662 start_display (&it, w, startp);
11663 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11664 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11665 if (IT_CHARPOS (it) == PT)
11666 w->force_start = Qt;
11667 /* IT may overshoot PT if text at PT is invisible. */
11668 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11669 w->force_start = Qt;
11670
11671
11672 }
11673
11674 /* Handle case where place to start displaying has been specified,
11675 unless the specified location is outside the accessible range. */
11676 if (!NILP (w->force_start)
11677 || w->frozen_window_start_p)
11678 {
11679 /* We set this later on if we have to adjust point. */
11680 int new_vpos = -1;
11681
11682 w->force_start = Qnil;
11683 w->vscroll = 0;
11684 w->window_end_valid = Qnil;
11685
11686 /* Forget any recorded base line for line number display. */
11687 if (!buffer_unchanged_p)
11688 w->base_line_number = Qnil;
11689
11690 /* Redisplay the mode line. Select the buffer properly for that.
11691 Also, run the hook window-scroll-functions
11692 because we have scrolled. */
11693 /* Note, we do this after clearing force_start because
11694 if there's an error, it is better to forget about force_start
11695 than to get into an infinite loop calling the hook functions
11696 and having them get more errors. */
11697 if (!update_mode_line
11698 || ! NILP (Vwindow_scroll_functions))
11699 {
11700 update_mode_line = 1;
11701 w->update_mode_line = Qt;
11702 startp = run_window_scroll_functions (window, startp);
11703 }
11704
11705 w->last_modified = make_number (0);
11706 w->last_overlay_modified = make_number (0);
11707 if (CHARPOS (startp) < BEGV)
11708 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11709 else if (CHARPOS (startp) > ZV)
11710 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11711
11712 /* Redisplay, then check if cursor has been set during the
11713 redisplay. Give up if new fonts were loaded. */
11714 if (!try_window (window, startp))
11715 {
11716 w->force_start = Qt;
11717 clear_glyph_matrix (w->desired_matrix);
11718 goto need_larger_matrices;
11719 }
11720
11721 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11722 {
11723 /* If point does not appear, try to move point so it does
11724 appear. The desired matrix has been built above, so we
11725 can use it here. */
11726 new_vpos = window_box_height (w) / 2;
11727 }
11728
11729 if (!make_cursor_line_fully_visible (w, 0))
11730 {
11731 /* Point does appear, but on a line partly visible at end of window.
11732 Move it back to a fully-visible line. */
11733 new_vpos = window_box_height (w);
11734 }
11735
11736 /* If we need to move point for either of the above reasons,
11737 now actually do it. */
11738 if (new_vpos >= 0)
11739 {
11740 struct glyph_row *row;
11741
11742 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11743 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11744 ++row;
11745
11746 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11747 MATRIX_ROW_START_BYTEPOS (row));
11748
11749 if (w != XWINDOW (selected_window))
11750 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11751 else if (current_buffer == old)
11752 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11753
11754 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11755
11756 /* If we are highlighting the region, then we just changed
11757 the region, so redisplay to show it. */
11758 if (!NILP (Vtransient_mark_mode)
11759 && !NILP (current_buffer->mark_active))
11760 {
11761 clear_glyph_matrix (w->desired_matrix);
11762 if (!try_window (window, startp))
11763 goto need_larger_matrices;
11764 }
11765 }
11766
11767 #if GLYPH_DEBUG
11768 debug_method_add (w, "forced window start");
11769 #endif
11770 goto done;
11771 }
11772
11773 /* Handle case where text has not changed, only point, and it has
11774 not moved off the frame, and we are not retrying after hscroll.
11775 (current_matrix_up_to_date_p is nonzero when retrying.) */
11776 if (current_matrix_up_to_date_p
11777 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11778 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11779 {
11780 switch (rc)
11781 {
11782 case CURSOR_MOVEMENT_SUCCESS:
11783 used_current_matrix_p = 1;
11784 goto done;
11785
11786 #if 0 /* try_cursor_movement never returns this value. */
11787 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11788 goto need_larger_matrices;
11789 #endif
11790
11791 case CURSOR_MOVEMENT_MUST_SCROLL:
11792 goto try_to_scroll;
11793
11794 default:
11795 abort ();
11796 }
11797 }
11798 /* If current starting point was originally the beginning of a line
11799 but no longer is, find a new starting point. */
11800 else if (!NILP (w->start_at_line_beg)
11801 && !(CHARPOS (startp) <= BEGV
11802 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11803 {
11804 #if GLYPH_DEBUG
11805 debug_method_add (w, "recenter 1");
11806 #endif
11807 goto recenter;
11808 }
11809
11810 /* Try scrolling with try_window_id. Value is > 0 if update has
11811 been done, it is -1 if we know that the same window start will
11812 not work. It is 0 if unsuccessful for some other reason. */
11813 else if ((tem = try_window_id (w)) != 0)
11814 {
11815 #if GLYPH_DEBUG
11816 debug_method_add (w, "try_window_id %d", tem);
11817 #endif
11818
11819 if (fonts_changed_p)
11820 goto need_larger_matrices;
11821 if (tem > 0)
11822 goto done;
11823
11824 /* Otherwise try_window_id has returned -1 which means that we
11825 don't want the alternative below this comment to execute. */
11826 }
11827 else if (CHARPOS (startp) >= BEGV
11828 && CHARPOS (startp) <= ZV
11829 && PT >= CHARPOS (startp)
11830 && (CHARPOS (startp) < ZV
11831 /* Avoid starting at end of buffer. */
11832 || CHARPOS (startp) == BEGV
11833 || (XFASTINT (w->last_modified) >= MODIFF
11834 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11835 {
11836 #if GLYPH_DEBUG
11837 debug_method_add (w, "same window start");
11838 #endif
11839
11840 /* Try to redisplay starting at same place as before.
11841 If point has not moved off frame, accept the results. */
11842 if (!current_matrix_up_to_date_p
11843 /* Don't use try_window_reusing_current_matrix in this case
11844 because a window scroll function can have changed the
11845 buffer. */
11846 || !NILP (Vwindow_scroll_functions)
11847 || MINI_WINDOW_P (w)
11848 || !(used_current_matrix_p =
11849 try_window_reusing_current_matrix (w)))
11850 {
11851 IF_DEBUG (debug_method_add (w, "1"));
11852 try_window (window, startp);
11853 }
11854
11855 if (fonts_changed_p)
11856 goto need_larger_matrices;
11857
11858 if (w->cursor.vpos >= 0)
11859 {
11860 if (!just_this_one_p
11861 || current_buffer->clip_changed
11862 || BEG_UNCHANGED < CHARPOS (startp))
11863 /* Forget any recorded base line for line number display. */
11864 w->base_line_number = Qnil;
11865
11866 if (!make_cursor_line_fully_visible (w, 1))
11867 {
11868 clear_glyph_matrix (w->desired_matrix);
11869 last_line_misfit = 1;
11870 }
11871 /* Drop through and scroll. */
11872 else
11873 goto done;
11874 }
11875 else
11876 clear_glyph_matrix (w->desired_matrix);
11877 }
11878
11879 try_to_scroll:
11880
11881 w->last_modified = make_number (0);
11882 w->last_overlay_modified = make_number (0);
11883
11884 /* Redisplay the mode line. Select the buffer properly for that. */
11885 if (!update_mode_line)
11886 {
11887 update_mode_line = 1;
11888 w->update_mode_line = Qt;
11889 }
11890
11891 /* Try to scroll by specified few lines. */
11892 if ((scroll_conservatively
11893 || scroll_step
11894 || temp_scroll_step
11895 || NUMBERP (current_buffer->scroll_up_aggressively)
11896 || NUMBERP (current_buffer->scroll_down_aggressively))
11897 && !current_buffer->clip_changed
11898 && CHARPOS (startp) >= BEGV
11899 && CHARPOS (startp) <= ZV)
11900 {
11901 /* The function returns -1 if new fonts were loaded, 1 if
11902 successful, 0 if not successful. */
11903 int rc = try_scrolling (window, just_this_one_p,
11904 scroll_conservatively,
11905 scroll_step,
11906 temp_scroll_step, last_line_misfit);
11907 switch (rc)
11908 {
11909 case SCROLLING_SUCCESS:
11910 goto done;
11911
11912 case SCROLLING_NEED_LARGER_MATRICES:
11913 goto need_larger_matrices;
11914
11915 case SCROLLING_FAILED:
11916 break;
11917
11918 default:
11919 abort ();
11920 }
11921 }
11922
11923 /* Finally, just choose place to start which centers point */
11924
11925 recenter:
11926 centering_position = window_box_height (w) / 2;
11927
11928 point_at_top:
11929 /* Jump here with centering_position already set to 0. */
11930
11931 #if GLYPH_DEBUG
11932 debug_method_add (w, "recenter");
11933 #endif
11934
11935 /* w->vscroll = 0; */
11936
11937 /* Forget any previously recorded base line for line number display. */
11938 if (!buffer_unchanged_p)
11939 w->base_line_number = Qnil;
11940
11941 /* Move backward half the height of the window. */
11942 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11943 it.current_y = it.last_visible_y;
11944 move_it_vertically_backward (&it, centering_position);
11945 xassert (IT_CHARPOS (it) >= BEGV);
11946
11947 /* The function move_it_vertically_backward may move over more
11948 than the specified y-distance. If it->w is small, e.g. a
11949 mini-buffer window, we may end up in front of the window's
11950 display area. Start displaying at the start of the line
11951 containing PT in this case. */
11952 if (it.current_y <= 0)
11953 {
11954 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11955 move_it_vertically (&it, 0);
11956 xassert (IT_CHARPOS (it) <= PT);
11957 it.current_y = 0;
11958 }
11959
11960 it.current_x = it.hpos = 0;
11961
11962 /* Set startp here explicitly in case that helps avoid an infinite loop
11963 in case the window-scroll-functions functions get errors. */
11964 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
11965
11966 /* Run scroll hooks. */
11967 startp = run_window_scroll_functions (window, it.current.pos);
11968
11969 /* Redisplay the window. */
11970 if (!current_matrix_up_to_date_p
11971 || windows_or_buffers_changed
11972 || cursor_type_changed
11973 /* Don't use try_window_reusing_current_matrix in this case
11974 because it can have changed the buffer. */
11975 || !NILP (Vwindow_scroll_functions)
11976 || !just_this_one_p
11977 || MINI_WINDOW_P (w)
11978 || !(used_current_matrix_p =
11979 try_window_reusing_current_matrix (w)))
11980 try_window (window, startp);
11981
11982 /* If new fonts have been loaded (due to fontsets), give up. We
11983 have to start a new redisplay since we need to re-adjust glyph
11984 matrices. */
11985 if (fonts_changed_p)
11986 goto need_larger_matrices;
11987
11988 /* If cursor did not appear assume that the middle of the window is
11989 in the first line of the window. Do it again with the next line.
11990 (Imagine a window of height 100, displaying two lines of height
11991 60. Moving back 50 from it->last_visible_y will end in the first
11992 line.) */
11993 if (w->cursor.vpos < 0)
11994 {
11995 if (!NILP (w->window_end_valid)
11996 && PT >= Z - XFASTINT (w->window_end_pos))
11997 {
11998 clear_glyph_matrix (w->desired_matrix);
11999 move_it_by_lines (&it, 1, 0);
12000 try_window (window, it.current.pos);
12001 }
12002 else if (PT < IT_CHARPOS (it))
12003 {
12004 clear_glyph_matrix (w->desired_matrix);
12005 move_it_by_lines (&it, -1, 0);
12006 try_window (window, it.current.pos);
12007 }
12008 else
12009 {
12010 /* Not much we can do about it. */
12011 }
12012 }
12013
12014 /* Consider the following case: Window starts at BEGV, there is
12015 invisible, intangible text at BEGV, so that display starts at
12016 some point START > BEGV. It can happen that we are called with
12017 PT somewhere between BEGV and START. Try to handle that case. */
12018 if (w->cursor.vpos < 0)
12019 {
12020 struct glyph_row *row = w->current_matrix->rows;
12021 if (row->mode_line_p)
12022 ++row;
12023 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12024 }
12025
12026 if (!make_cursor_line_fully_visible (w, centering_position > 0))
12027 {
12028 /* If vscroll is enabled, disable it and try again. */
12029 if (w->vscroll)
12030 {
12031 w->vscroll = 0;
12032 clear_glyph_matrix (w->desired_matrix);
12033 goto recenter;
12034 }
12035
12036 /* If centering point failed to make the whole line visible,
12037 put point at the top instead. That has to make the whole line
12038 visible, if it can be done. */
12039 clear_glyph_matrix (w->desired_matrix);
12040 centering_position = 0;
12041 goto point_at_top;
12042 }
12043
12044 done:
12045
12046 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12047 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12048 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12049 ? Qt : Qnil);
12050
12051 /* Display the mode line, if we must. */
12052 if ((update_mode_line
12053 /* If window not full width, must redo its mode line
12054 if (a) the window to its side is being redone and
12055 (b) we do a frame-based redisplay. This is a consequence
12056 of how inverted lines are drawn in frame-based redisplay. */
12057 || (!just_this_one_p
12058 && !FRAME_WINDOW_P (f)
12059 && !WINDOW_FULL_WIDTH_P (w))
12060 /* Line number to display. */
12061 || INTEGERP (w->base_line_pos)
12062 /* Column number is displayed and different from the one displayed. */
12063 || (!NILP (w->column_number_displayed)
12064 && (XFASTINT (w->column_number_displayed)
12065 != (int) current_column ()))) /* iftc */
12066 /* This means that the window has a mode line. */
12067 && (WINDOW_WANTS_MODELINE_P (w)
12068 || WINDOW_WANTS_HEADER_LINE_P (w)))
12069 {
12070 display_mode_lines (w);
12071
12072 /* If mode line height has changed, arrange for a thorough
12073 immediate redisplay using the correct mode line height. */
12074 if (WINDOW_WANTS_MODELINE_P (w)
12075 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12076 {
12077 fonts_changed_p = 1;
12078 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12079 = DESIRED_MODE_LINE_HEIGHT (w);
12080 }
12081
12082 /* If top line height has changed, arrange for a thorough
12083 immediate redisplay using the correct mode line height. */
12084 if (WINDOW_WANTS_HEADER_LINE_P (w)
12085 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12086 {
12087 fonts_changed_p = 1;
12088 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12089 = DESIRED_HEADER_LINE_HEIGHT (w);
12090 }
12091
12092 if (fonts_changed_p)
12093 goto need_larger_matrices;
12094 }
12095
12096 if (!line_number_displayed
12097 && !BUFFERP (w->base_line_pos))
12098 {
12099 w->base_line_pos = Qnil;
12100 w->base_line_number = Qnil;
12101 }
12102
12103 finish_menu_bars:
12104
12105 /* When we reach a frame's selected window, redo the frame's menu bar. */
12106 if (update_mode_line
12107 && EQ (FRAME_SELECTED_WINDOW (f), window))
12108 {
12109 int redisplay_menu_p = 0;
12110 int redisplay_tool_bar_p = 0;
12111
12112 if (FRAME_WINDOW_P (f))
12113 {
12114 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12115 || defined (USE_GTK)
12116 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12117 #else
12118 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12119 #endif
12120 }
12121 else
12122 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12123
12124 if (redisplay_menu_p)
12125 display_menu_bar (w);
12126
12127 #ifdef HAVE_WINDOW_SYSTEM
12128 #ifdef USE_GTK
12129 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12130 #else
12131 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12132 && (FRAME_TOOL_BAR_LINES (f) > 0
12133 || auto_resize_tool_bars_p);
12134
12135 #endif
12136
12137 if (redisplay_tool_bar_p)
12138 redisplay_tool_bar (f);
12139 #endif
12140 }
12141
12142 #ifdef HAVE_WINDOW_SYSTEM
12143 if (update_window_fringes (w, 0)
12144 && !just_this_one_p
12145 && (used_current_matrix_p || overlay_arrow_seen)
12146 && !w->pseudo_window_p)
12147 {
12148 update_begin (f);
12149 BLOCK_INPUT;
12150 draw_window_fringes (w);
12151 UNBLOCK_INPUT;
12152 update_end (f);
12153 }
12154 #endif /* HAVE_WINDOW_SYSTEM */
12155
12156 /* We go to this label, with fonts_changed_p nonzero,
12157 if it is necessary to try again using larger glyph matrices.
12158 We have to redeem the scroll bar even in this case,
12159 because the loop in redisplay_internal expects that. */
12160 need_larger_matrices:
12161 ;
12162 finish_scroll_bars:
12163
12164 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12165 {
12166 /* Set the thumb's position and size. */
12167 set_vertical_scroll_bar (w);
12168
12169 /* Note that we actually used the scroll bar attached to this
12170 window, so it shouldn't be deleted at the end of redisplay. */
12171 redeem_scroll_bar_hook (w);
12172 }
12173
12174 /* Restore current_buffer and value of point in it. */
12175 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12176 set_buffer_internal_1 (old);
12177 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12178
12179 unbind_to (count, Qnil);
12180 }
12181
12182
12183 /* Build the complete desired matrix of WINDOW with a window start
12184 buffer position POS. Value is non-zero if successful. It is zero
12185 if fonts were loaded during redisplay which makes re-adjusting
12186 glyph matrices necessary. */
12187
12188 int
12189 try_window (window, pos)
12190 Lisp_Object window;
12191 struct text_pos pos;
12192 {
12193 struct window *w = XWINDOW (window);
12194 struct it it;
12195 struct glyph_row *last_text_row = NULL;
12196
12197 /* Make POS the new window start. */
12198 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12199
12200 /* Mark cursor position as unknown. No overlay arrow seen. */
12201 w->cursor.vpos = -1;
12202 overlay_arrow_seen = 0;
12203
12204 /* Initialize iterator and info to start at POS. */
12205 start_display (&it, w, pos);
12206
12207 /* Display all lines of W. */
12208 while (it.current_y < it.last_visible_y)
12209 {
12210 if (display_line (&it))
12211 last_text_row = it.glyph_row - 1;
12212 if (fonts_changed_p)
12213 return 0;
12214 }
12215
12216 /* If bottom moved off end of frame, change mode line percentage. */
12217 if (XFASTINT (w->window_end_pos) <= 0
12218 && Z != IT_CHARPOS (it))
12219 w->update_mode_line = Qt;
12220
12221 /* Set window_end_pos to the offset of the last character displayed
12222 on the window from the end of current_buffer. Set
12223 window_end_vpos to its row number. */
12224 if (last_text_row)
12225 {
12226 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12227 w->window_end_bytepos
12228 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12229 w->window_end_pos
12230 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12231 w->window_end_vpos
12232 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12233 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12234 ->displays_text_p);
12235 }
12236 else
12237 {
12238 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12239 w->window_end_pos = make_number (Z - ZV);
12240 w->window_end_vpos = make_number (0);
12241 }
12242
12243 /* But that is not valid info until redisplay finishes. */
12244 w->window_end_valid = Qnil;
12245 return 1;
12246 }
12247
12248
12249 \f
12250 /************************************************************************
12251 Window redisplay reusing current matrix when buffer has not changed
12252 ************************************************************************/
12253
12254 /* Try redisplay of window W showing an unchanged buffer with a
12255 different window start than the last time it was displayed by
12256 reusing its current matrix. Value is non-zero if successful.
12257 W->start is the new window start. */
12258
12259 static int
12260 try_window_reusing_current_matrix (w)
12261 struct window *w;
12262 {
12263 struct frame *f = XFRAME (w->frame);
12264 struct glyph_row *row, *bottom_row;
12265 struct it it;
12266 struct run run;
12267 struct text_pos start, new_start;
12268 int nrows_scrolled, i;
12269 struct glyph_row *last_text_row;
12270 struct glyph_row *last_reused_text_row;
12271 struct glyph_row *start_row;
12272 int start_vpos, min_y, max_y;
12273
12274 #if GLYPH_DEBUG
12275 if (inhibit_try_window_reusing)
12276 return 0;
12277 #endif
12278
12279 if (/* This function doesn't handle terminal frames. */
12280 !FRAME_WINDOW_P (f)
12281 /* Don't try to reuse the display if windows have been split
12282 or such. */
12283 || windows_or_buffers_changed
12284 || cursor_type_changed)
12285 return 0;
12286
12287 /* Can't do this if region may have changed. */
12288 if ((!NILP (Vtransient_mark_mode)
12289 && !NILP (current_buffer->mark_active))
12290 || !NILP (w->region_showing)
12291 || !NILP (Vshow_trailing_whitespace))
12292 return 0;
12293
12294 /* If top-line visibility has changed, give up. */
12295 if (WINDOW_WANTS_HEADER_LINE_P (w)
12296 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12297 return 0;
12298
12299 /* Give up if old or new display is scrolled vertically. We could
12300 make this function handle this, but right now it doesn't. */
12301 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12302 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12303 return 0;
12304
12305 /* The variable new_start now holds the new window start. The old
12306 start `start' can be determined from the current matrix. */
12307 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12308 start = start_row->start.pos;
12309 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12310
12311 /* Clear the desired matrix for the display below. */
12312 clear_glyph_matrix (w->desired_matrix);
12313
12314 if (CHARPOS (new_start) <= CHARPOS (start))
12315 {
12316 int first_row_y;
12317
12318 /* Don't use this method if the display starts with an ellipsis
12319 displayed for invisible text. It's not easy to handle that case
12320 below, and it's certainly not worth the effort since this is
12321 not a frequent case. */
12322 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12323 return 0;
12324
12325 IF_DEBUG (debug_method_add (w, "twu1"));
12326
12327 /* Display up to a row that can be reused. The variable
12328 last_text_row is set to the last row displayed that displays
12329 text. Note that it.vpos == 0 if or if not there is a
12330 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12331 start_display (&it, w, new_start);
12332 first_row_y = it.current_y;
12333 w->cursor.vpos = -1;
12334 last_text_row = last_reused_text_row = NULL;
12335
12336 while (it.current_y < it.last_visible_y
12337 && IT_CHARPOS (it) < CHARPOS (start)
12338 && !fonts_changed_p)
12339 if (display_line (&it))
12340 last_text_row = it.glyph_row - 1;
12341
12342 /* A value of current_y < last_visible_y means that we stopped
12343 at the previous window start, which in turn means that we
12344 have at least one reusable row. */
12345 if (it.current_y < it.last_visible_y)
12346 {
12347 /* IT.vpos always starts from 0; it counts text lines. */
12348 nrows_scrolled = it.vpos;
12349
12350 /* Find PT if not already found in the lines displayed. */
12351 if (w->cursor.vpos < 0)
12352 {
12353 int dy = it.current_y - first_row_y;
12354
12355 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12356 row = row_containing_pos (w, PT, row, NULL, dy);
12357 if (row)
12358 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12359 dy, nrows_scrolled);
12360 else
12361 {
12362 clear_glyph_matrix (w->desired_matrix);
12363 return 0;
12364 }
12365 }
12366
12367 /* Scroll the display. Do it before the current matrix is
12368 changed. The problem here is that update has not yet
12369 run, i.e. part of the current matrix is not up to date.
12370 scroll_run_hook will clear the cursor, and use the
12371 current matrix to get the height of the row the cursor is
12372 in. */
12373 run.current_y = first_row_y;
12374 run.desired_y = it.current_y;
12375 run.height = it.last_visible_y - it.current_y;
12376
12377 if (run.height > 0 && run.current_y != run.desired_y)
12378 {
12379 update_begin (f);
12380 rif->update_window_begin_hook (w);
12381 rif->clear_window_mouse_face (w);
12382 rif->scroll_run_hook (w, &run);
12383 rif->update_window_end_hook (w, 0, 0);
12384 update_end (f);
12385 }
12386
12387 /* Shift current matrix down by nrows_scrolled lines. */
12388 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12389 rotate_matrix (w->current_matrix,
12390 start_vpos,
12391 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12392 nrows_scrolled);
12393
12394 /* Disable lines that must be updated. */
12395 for (i = 0; i < it.vpos; ++i)
12396 (start_row + i)->enabled_p = 0;
12397
12398 /* Re-compute Y positions. */
12399 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12400 max_y = it.last_visible_y;
12401 for (row = start_row + nrows_scrolled;
12402 row < bottom_row;
12403 ++row)
12404 {
12405 row->y = it.current_y;
12406 row->visible_height = row->height;
12407
12408 if (row->y < min_y)
12409 row->visible_height -= min_y - row->y;
12410 if (row->y + row->height > max_y)
12411 row->visible_height -= row->y + row->height - max_y;
12412 row->redraw_fringe_bitmaps_p = 1;
12413
12414 it.current_y += row->height;
12415
12416 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12417 last_reused_text_row = row;
12418 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12419 break;
12420 }
12421
12422 /* Disable lines in the current matrix which are now
12423 below the window. */
12424 for (++row; row < bottom_row; ++row)
12425 row->enabled_p = 0;
12426 }
12427
12428 /* Update window_end_pos etc.; last_reused_text_row is the last
12429 reused row from the current matrix containing text, if any.
12430 The value of last_text_row is the last displayed line
12431 containing text. */
12432 if (last_reused_text_row)
12433 {
12434 w->window_end_bytepos
12435 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12436 w->window_end_pos
12437 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12438 w->window_end_vpos
12439 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12440 w->current_matrix));
12441 }
12442 else if (last_text_row)
12443 {
12444 w->window_end_bytepos
12445 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12446 w->window_end_pos
12447 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12448 w->window_end_vpos
12449 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12450 }
12451 else
12452 {
12453 /* This window must be completely empty. */
12454 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12455 w->window_end_pos = make_number (Z - ZV);
12456 w->window_end_vpos = make_number (0);
12457 }
12458 w->window_end_valid = Qnil;
12459
12460 /* Update hint: don't try scrolling again in update_window. */
12461 w->desired_matrix->no_scrolling_p = 1;
12462
12463 #if GLYPH_DEBUG
12464 debug_method_add (w, "try_window_reusing_current_matrix 1");
12465 #endif
12466 return 1;
12467 }
12468 else if (CHARPOS (new_start) > CHARPOS (start))
12469 {
12470 struct glyph_row *pt_row, *row;
12471 struct glyph_row *first_reusable_row;
12472 struct glyph_row *first_row_to_display;
12473 int dy;
12474 int yb = window_text_bottom_y (w);
12475
12476 /* Find the row starting at new_start, if there is one. Don't
12477 reuse a partially visible line at the end. */
12478 first_reusable_row = start_row;
12479 while (first_reusable_row->enabled_p
12480 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12481 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12482 < CHARPOS (new_start)))
12483 ++first_reusable_row;
12484
12485 /* Give up if there is no row to reuse. */
12486 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12487 || !first_reusable_row->enabled_p
12488 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12489 != CHARPOS (new_start)))
12490 return 0;
12491
12492 /* We can reuse fully visible rows beginning with
12493 first_reusable_row to the end of the window. Set
12494 first_row_to_display to the first row that cannot be reused.
12495 Set pt_row to the row containing point, if there is any. */
12496 pt_row = NULL;
12497 for (first_row_to_display = first_reusable_row;
12498 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12499 ++first_row_to_display)
12500 {
12501 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12502 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12503 pt_row = first_row_to_display;
12504 }
12505
12506 /* Start displaying at the start of first_row_to_display. */
12507 xassert (first_row_to_display->y < yb);
12508 init_to_row_start (&it, w, first_row_to_display);
12509
12510 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12511 - start_vpos);
12512 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12513 - nrows_scrolled);
12514 it.current_y = (first_row_to_display->y - first_reusable_row->y
12515 + WINDOW_HEADER_LINE_HEIGHT (w));
12516
12517 /* Display lines beginning with first_row_to_display in the
12518 desired matrix. Set last_text_row to the last row displayed
12519 that displays text. */
12520 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12521 if (pt_row == NULL)
12522 w->cursor.vpos = -1;
12523 last_text_row = NULL;
12524 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12525 if (display_line (&it))
12526 last_text_row = it.glyph_row - 1;
12527
12528 /* Give up If point isn't in a row displayed or reused. */
12529 if (w->cursor.vpos < 0)
12530 {
12531 clear_glyph_matrix (w->desired_matrix);
12532 return 0;
12533 }
12534
12535 /* If point is in a reused row, adjust y and vpos of the cursor
12536 position. */
12537 if (pt_row)
12538 {
12539 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12540 w->current_matrix);
12541 w->cursor.y -= first_reusable_row->y;
12542 }
12543
12544 /* Scroll the display. */
12545 run.current_y = first_reusable_row->y;
12546 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12547 run.height = it.last_visible_y - run.current_y;
12548 dy = run.current_y - run.desired_y;
12549
12550 if (run.height)
12551 {
12552 update_begin (f);
12553 rif->update_window_begin_hook (w);
12554 rif->clear_window_mouse_face (w);
12555 rif->scroll_run_hook (w, &run);
12556 rif->update_window_end_hook (w, 0, 0);
12557 update_end (f);
12558 }
12559
12560 /* Adjust Y positions of reused rows. */
12561 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12562 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12563 max_y = it.last_visible_y;
12564 for (row = first_reusable_row; row < first_row_to_display; ++row)
12565 {
12566 row->y -= dy;
12567 row->visible_height = row->height;
12568 if (row->y < min_y)
12569 row->visible_height -= min_y - row->y;
12570 if (row->y + row->height > max_y)
12571 row->visible_height -= row->y + row->height - max_y;
12572 row->redraw_fringe_bitmaps_p = 1;
12573 }
12574
12575 /* Scroll the current matrix. */
12576 xassert (nrows_scrolled > 0);
12577 rotate_matrix (w->current_matrix,
12578 start_vpos,
12579 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12580 -nrows_scrolled);
12581
12582 /* Disable rows not reused. */
12583 for (row -= nrows_scrolled; row < bottom_row; ++row)
12584 row->enabled_p = 0;
12585
12586 /* Adjust window end. A null value of last_text_row means that
12587 the window end is in reused rows which in turn means that
12588 only its vpos can have changed. */
12589 if (last_text_row)
12590 {
12591 w->window_end_bytepos
12592 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12593 w->window_end_pos
12594 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12595 w->window_end_vpos
12596 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12597 }
12598 else
12599 {
12600 w->window_end_vpos
12601 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12602 }
12603
12604 w->window_end_valid = Qnil;
12605 w->desired_matrix->no_scrolling_p = 1;
12606
12607 #if GLYPH_DEBUG
12608 debug_method_add (w, "try_window_reusing_current_matrix 2");
12609 #endif
12610 return 1;
12611 }
12612
12613 return 0;
12614 }
12615
12616
12617 \f
12618 /************************************************************************
12619 Window redisplay reusing current matrix when buffer has changed
12620 ************************************************************************/
12621
12622 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12623 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12624 int *, int *));
12625 static struct glyph_row *
12626 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12627 struct glyph_row *));
12628
12629
12630 /* Return the last row in MATRIX displaying text. If row START is
12631 non-null, start searching with that row. IT gives the dimensions
12632 of the display. Value is null if matrix is empty; otherwise it is
12633 a pointer to the row found. */
12634
12635 static struct glyph_row *
12636 find_last_row_displaying_text (matrix, it, start)
12637 struct glyph_matrix *matrix;
12638 struct it *it;
12639 struct glyph_row *start;
12640 {
12641 struct glyph_row *row, *row_found;
12642
12643 /* Set row_found to the last row in IT->w's current matrix
12644 displaying text. The loop looks funny but think of partially
12645 visible lines. */
12646 row_found = NULL;
12647 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12648 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12649 {
12650 xassert (row->enabled_p);
12651 row_found = row;
12652 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12653 break;
12654 ++row;
12655 }
12656
12657 return row_found;
12658 }
12659
12660
12661 /* Return the last row in the current matrix of W that is not affected
12662 by changes at the start of current_buffer that occurred since W's
12663 current matrix was built. Value is null if no such row exists.
12664
12665 BEG_UNCHANGED us the number of characters unchanged at the start of
12666 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12667 first changed character in current_buffer. Characters at positions <
12668 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12669 when the current matrix was built. */
12670
12671 static struct glyph_row *
12672 find_last_unchanged_at_beg_row (w)
12673 struct window *w;
12674 {
12675 int first_changed_pos = BEG + BEG_UNCHANGED;
12676 struct glyph_row *row;
12677 struct glyph_row *row_found = NULL;
12678 int yb = window_text_bottom_y (w);
12679
12680 /* Find the last row displaying unchanged text. */
12681 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12682 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12683 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12684 {
12685 if (/* If row ends before first_changed_pos, it is unchanged,
12686 except in some case. */
12687 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12688 /* When row ends in ZV and we write at ZV it is not
12689 unchanged. */
12690 && !row->ends_at_zv_p
12691 /* When first_changed_pos is the end of a continued line,
12692 row is not unchanged because it may be no longer
12693 continued. */
12694 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12695 && (row->continued_p
12696 || row->exact_window_width_line_p)))
12697 row_found = row;
12698
12699 /* Stop if last visible row. */
12700 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12701 break;
12702
12703 ++row;
12704 }
12705
12706 return row_found;
12707 }
12708
12709
12710 /* Find the first glyph row in the current matrix of W that is not
12711 affected by changes at the end of current_buffer since the
12712 time W's current matrix was built.
12713
12714 Return in *DELTA the number of chars by which buffer positions in
12715 unchanged text at the end of current_buffer must be adjusted.
12716
12717 Return in *DELTA_BYTES the corresponding number of bytes.
12718
12719 Value is null if no such row exists, i.e. all rows are affected by
12720 changes. */
12721
12722 static struct glyph_row *
12723 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12724 struct window *w;
12725 int *delta, *delta_bytes;
12726 {
12727 struct glyph_row *row;
12728 struct glyph_row *row_found = NULL;
12729
12730 *delta = *delta_bytes = 0;
12731
12732 /* Display must not have been paused, otherwise the current matrix
12733 is not up to date. */
12734 if (NILP (w->window_end_valid))
12735 abort ();
12736
12737 /* A value of window_end_pos >= END_UNCHANGED means that the window
12738 end is in the range of changed text. If so, there is no
12739 unchanged row at the end of W's current matrix. */
12740 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12741 return NULL;
12742
12743 /* Set row to the last row in W's current matrix displaying text. */
12744 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12745
12746 /* If matrix is entirely empty, no unchanged row exists. */
12747 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12748 {
12749 /* The value of row is the last glyph row in the matrix having a
12750 meaningful buffer position in it. The end position of row
12751 corresponds to window_end_pos. This allows us to translate
12752 buffer positions in the current matrix to current buffer
12753 positions for characters not in changed text. */
12754 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12755 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12756 int last_unchanged_pos, last_unchanged_pos_old;
12757 struct glyph_row *first_text_row
12758 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12759
12760 *delta = Z - Z_old;
12761 *delta_bytes = Z_BYTE - Z_BYTE_old;
12762
12763 /* Set last_unchanged_pos to the buffer position of the last
12764 character in the buffer that has not been changed. Z is the
12765 index + 1 of the last character in current_buffer, i.e. by
12766 subtracting END_UNCHANGED we get the index of the last
12767 unchanged character, and we have to add BEG to get its buffer
12768 position. */
12769 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12770 last_unchanged_pos_old = last_unchanged_pos - *delta;
12771
12772 /* Search backward from ROW for a row displaying a line that
12773 starts at a minimum position >= last_unchanged_pos_old. */
12774 for (; row > first_text_row; --row)
12775 {
12776 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12777 abort ();
12778
12779 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12780 row_found = row;
12781 }
12782 }
12783
12784 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12785 abort ();
12786
12787 return row_found;
12788 }
12789
12790
12791 /* Make sure that glyph rows in the current matrix of window W
12792 reference the same glyph memory as corresponding rows in the
12793 frame's frame matrix. This function is called after scrolling W's
12794 current matrix on a terminal frame in try_window_id and
12795 try_window_reusing_current_matrix. */
12796
12797 static void
12798 sync_frame_with_window_matrix_rows (w)
12799 struct window *w;
12800 {
12801 struct frame *f = XFRAME (w->frame);
12802 struct glyph_row *window_row, *window_row_end, *frame_row;
12803
12804 /* Preconditions: W must be a leaf window and full-width. Its frame
12805 must have a frame matrix. */
12806 xassert (NILP (w->hchild) && NILP (w->vchild));
12807 xassert (WINDOW_FULL_WIDTH_P (w));
12808 xassert (!FRAME_WINDOW_P (f));
12809
12810 /* If W is a full-width window, glyph pointers in W's current matrix
12811 have, by definition, to be the same as glyph pointers in the
12812 corresponding frame matrix. Note that frame matrices have no
12813 marginal areas (see build_frame_matrix). */
12814 window_row = w->current_matrix->rows;
12815 window_row_end = window_row + w->current_matrix->nrows;
12816 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12817 while (window_row < window_row_end)
12818 {
12819 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12820 struct glyph *end = window_row->glyphs[LAST_AREA];
12821
12822 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12823 frame_row->glyphs[TEXT_AREA] = start;
12824 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12825 frame_row->glyphs[LAST_AREA] = end;
12826
12827 /* Disable frame rows whose corresponding window rows have
12828 been disabled in try_window_id. */
12829 if (!window_row->enabled_p)
12830 frame_row->enabled_p = 0;
12831
12832 ++window_row, ++frame_row;
12833 }
12834 }
12835
12836
12837 /* Find the glyph row in window W containing CHARPOS. Consider all
12838 rows between START and END (not inclusive). END null means search
12839 all rows to the end of the display area of W. Value is the row
12840 containing CHARPOS or null. */
12841
12842 struct glyph_row *
12843 row_containing_pos (w, charpos, start, end, dy)
12844 struct window *w;
12845 int charpos;
12846 struct glyph_row *start, *end;
12847 int dy;
12848 {
12849 struct glyph_row *row = start;
12850 int last_y;
12851
12852 /* If we happen to start on a header-line, skip that. */
12853 if (row->mode_line_p)
12854 ++row;
12855
12856 if ((end && row >= end) || !row->enabled_p)
12857 return NULL;
12858
12859 last_y = window_text_bottom_y (w) - dy;
12860
12861 while (1)
12862 {
12863 /* Give up if we have gone too far. */
12864 if (end && row >= end)
12865 return NULL;
12866 /* This formerly returned if they were equal.
12867 I think that both quantities are of a "last plus one" type;
12868 if so, when they are equal, the row is within the screen. -- rms. */
12869 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12870 return NULL;
12871
12872 /* If it is in this row, return this row. */
12873 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12874 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12875 /* The end position of a row equals the start
12876 position of the next row. If CHARPOS is there, we
12877 would rather display it in the next line, except
12878 when this line ends in ZV. */
12879 && !row->ends_at_zv_p
12880 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12881 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12882 return row;
12883 ++row;
12884 }
12885 }
12886
12887
12888 /* Try to redisplay window W by reusing its existing display. W's
12889 current matrix must be up to date when this function is called,
12890 i.e. window_end_valid must not be nil.
12891
12892 Value is
12893
12894 1 if display has been updated
12895 0 if otherwise unsuccessful
12896 -1 if redisplay with same window start is known not to succeed
12897
12898 The following steps are performed:
12899
12900 1. Find the last row in the current matrix of W that is not
12901 affected by changes at the start of current_buffer. If no such row
12902 is found, give up.
12903
12904 2. Find the first row in W's current matrix that is not affected by
12905 changes at the end of current_buffer. Maybe there is no such row.
12906
12907 3. Display lines beginning with the row + 1 found in step 1 to the
12908 row found in step 2 or, if step 2 didn't find a row, to the end of
12909 the window.
12910
12911 4. If cursor is not known to appear on the window, give up.
12912
12913 5. If display stopped at the row found in step 2, scroll the
12914 display and current matrix as needed.
12915
12916 6. Maybe display some lines at the end of W, if we must. This can
12917 happen under various circumstances, like a partially visible line
12918 becoming fully visible, or because newly displayed lines are displayed
12919 in smaller font sizes.
12920
12921 7. Update W's window end information. */
12922
12923 static int
12924 try_window_id (w)
12925 struct window *w;
12926 {
12927 struct frame *f = XFRAME (w->frame);
12928 struct glyph_matrix *current_matrix = w->current_matrix;
12929 struct glyph_matrix *desired_matrix = w->desired_matrix;
12930 struct glyph_row *last_unchanged_at_beg_row;
12931 struct glyph_row *first_unchanged_at_end_row;
12932 struct glyph_row *row;
12933 struct glyph_row *bottom_row;
12934 int bottom_vpos;
12935 struct it it;
12936 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
12937 struct text_pos start_pos;
12938 struct run run;
12939 int first_unchanged_at_end_vpos = 0;
12940 struct glyph_row *last_text_row, *last_text_row_at_end;
12941 struct text_pos start;
12942 int first_changed_charpos, last_changed_charpos;
12943
12944 #if GLYPH_DEBUG
12945 if (inhibit_try_window_id)
12946 return 0;
12947 #endif
12948
12949 /* This is handy for debugging. */
12950 #if 0
12951 #define GIVE_UP(X) \
12952 do { \
12953 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12954 return 0; \
12955 } while (0)
12956 #else
12957 #define GIVE_UP(X) return 0
12958 #endif
12959
12960 SET_TEXT_POS_FROM_MARKER (start, w->start);
12961
12962 /* Don't use this for mini-windows because these can show
12963 messages and mini-buffers, and we don't handle that here. */
12964 if (MINI_WINDOW_P (w))
12965 GIVE_UP (1);
12966
12967 /* This flag is used to prevent redisplay optimizations. */
12968 if (windows_or_buffers_changed || cursor_type_changed)
12969 GIVE_UP (2);
12970
12971 /* Verify that narrowing has not changed.
12972 Also verify that we were not told to prevent redisplay optimizations.
12973 It would be nice to further
12974 reduce the number of cases where this prevents try_window_id. */
12975 if (current_buffer->clip_changed
12976 || current_buffer->prevent_redisplay_optimizations_p)
12977 GIVE_UP (3);
12978
12979 /* Window must either use window-based redisplay or be full width. */
12980 if (!FRAME_WINDOW_P (f)
12981 && (!line_ins_del_ok
12982 || !WINDOW_FULL_WIDTH_P (w)))
12983 GIVE_UP (4);
12984
12985 /* Give up if point is not known NOT to appear in W. */
12986 if (PT < CHARPOS (start))
12987 GIVE_UP (5);
12988
12989 /* Another way to prevent redisplay optimizations. */
12990 if (XFASTINT (w->last_modified) == 0)
12991 GIVE_UP (6);
12992
12993 /* Verify that window is not hscrolled. */
12994 if (XFASTINT (w->hscroll) != 0)
12995 GIVE_UP (7);
12996
12997 /* Verify that display wasn't paused. */
12998 if (NILP (w->window_end_valid))
12999 GIVE_UP (8);
13000
13001 /* Can't use this if highlighting a region because a cursor movement
13002 will do more than just set the cursor. */
13003 if (!NILP (Vtransient_mark_mode)
13004 && !NILP (current_buffer->mark_active))
13005 GIVE_UP (9);
13006
13007 /* Likewise if highlighting trailing whitespace. */
13008 if (!NILP (Vshow_trailing_whitespace))
13009 GIVE_UP (11);
13010
13011 /* Likewise if showing a region. */
13012 if (!NILP (w->region_showing))
13013 GIVE_UP (10);
13014
13015 /* Can use this if overlay arrow position and or string have changed. */
13016 if (overlay_arrows_changed_p ())
13017 GIVE_UP (12);
13018
13019
13020 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13021 only if buffer has really changed. The reason is that the gap is
13022 initially at Z for freshly visited files. The code below would
13023 set end_unchanged to 0 in that case. */
13024 if (MODIFF > SAVE_MODIFF
13025 /* This seems to happen sometimes after saving a buffer. */
13026 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13027 {
13028 if (GPT - BEG < BEG_UNCHANGED)
13029 BEG_UNCHANGED = GPT - BEG;
13030 if (Z - GPT < END_UNCHANGED)
13031 END_UNCHANGED = Z - GPT;
13032 }
13033
13034 /* The position of the first and last character that has been changed. */
13035 first_changed_charpos = BEG + BEG_UNCHANGED;
13036 last_changed_charpos = Z - END_UNCHANGED;
13037
13038 /* If window starts after a line end, and the last change is in
13039 front of that newline, then changes don't affect the display.
13040 This case happens with stealth-fontification. Note that although
13041 the display is unchanged, glyph positions in the matrix have to
13042 be adjusted, of course. */
13043 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13044 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13045 && ((last_changed_charpos < CHARPOS (start)
13046 && CHARPOS (start) == BEGV)
13047 || (last_changed_charpos < CHARPOS (start) - 1
13048 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13049 {
13050 int Z_old, delta, Z_BYTE_old, delta_bytes;
13051 struct glyph_row *r0;
13052
13053 /* Compute how many chars/bytes have been added to or removed
13054 from the buffer. */
13055 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13056 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13057 delta = Z - Z_old;
13058 delta_bytes = Z_BYTE - Z_BYTE_old;
13059
13060 /* Give up if PT is not in the window. Note that it already has
13061 been checked at the start of try_window_id that PT is not in
13062 front of the window start. */
13063 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13064 GIVE_UP (13);
13065
13066 /* If window start is unchanged, we can reuse the whole matrix
13067 as is, after adjusting glyph positions. No need to compute
13068 the window end again, since its offset from Z hasn't changed. */
13069 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13070 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13071 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13072 /* PT must not be in a partially visible line. */
13073 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13074 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13075 {
13076 /* Adjust positions in the glyph matrix. */
13077 if (delta || delta_bytes)
13078 {
13079 struct glyph_row *r1
13080 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13081 increment_matrix_positions (w->current_matrix,
13082 MATRIX_ROW_VPOS (r0, current_matrix),
13083 MATRIX_ROW_VPOS (r1, current_matrix),
13084 delta, delta_bytes);
13085 }
13086
13087 /* Set the cursor. */
13088 row = row_containing_pos (w, PT, r0, NULL, 0);
13089 if (row)
13090 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13091 else
13092 abort ();
13093 return 1;
13094 }
13095 }
13096
13097 /* Handle the case that changes are all below what is displayed in
13098 the window, and that PT is in the window. This shortcut cannot
13099 be taken if ZV is visible in the window, and text has been added
13100 there that is visible in the window. */
13101 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13102 /* ZV is not visible in the window, or there are no
13103 changes at ZV, actually. */
13104 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13105 || first_changed_charpos == last_changed_charpos))
13106 {
13107 struct glyph_row *r0;
13108
13109 /* Give up if PT is not in the window. Note that it already has
13110 been checked at the start of try_window_id that PT is not in
13111 front of the window start. */
13112 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13113 GIVE_UP (14);
13114
13115 /* If window start is unchanged, we can reuse the whole matrix
13116 as is, without changing glyph positions since no text has
13117 been added/removed in front of the window end. */
13118 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13119 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13120 /* PT must not be in a partially visible line. */
13121 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13122 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13123 {
13124 /* We have to compute the window end anew since text
13125 can have been added/removed after it. */
13126 w->window_end_pos
13127 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13128 w->window_end_bytepos
13129 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13130
13131 /* Set the cursor. */
13132 row = row_containing_pos (w, PT, r0, NULL, 0);
13133 if (row)
13134 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13135 else
13136 abort ();
13137 return 2;
13138 }
13139 }
13140
13141 /* Give up if window start is in the changed area.
13142
13143 The condition used to read
13144
13145 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13146
13147 but why that was tested escapes me at the moment. */
13148 if (CHARPOS (start) >= first_changed_charpos
13149 && CHARPOS (start) <= last_changed_charpos)
13150 GIVE_UP (15);
13151
13152 /* Check that window start agrees with the start of the first glyph
13153 row in its current matrix. Check this after we know the window
13154 start is not in changed text, otherwise positions would not be
13155 comparable. */
13156 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13157 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13158 GIVE_UP (16);
13159
13160 /* Give up if the window ends in strings. Overlay strings
13161 at the end are difficult to handle, so don't try. */
13162 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13163 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13164 GIVE_UP (20);
13165
13166 /* Compute the position at which we have to start displaying new
13167 lines. Some of the lines at the top of the window might be
13168 reusable because they are not displaying changed text. Find the
13169 last row in W's current matrix not affected by changes at the
13170 start of current_buffer. Value is null if changes start in the
13171 first line of window. */
13172 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13173 if (last_unchanged_at_beg_row)
13174 {
13175 /* Avoid starting to display in the moddle of a character, a TAB
13176 for instance. This is easier than to set up the iterator
13177 exactly, and it's not a frequent case, so the additional
13178 effort wouldn't really pay off. */
13179 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13180 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13181 && last_unchanged_at_beg_row > w->current_matrix->rows)
13182 --last_unchanged_at_beg_row;
13183
13184 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13185 GIVE_UP (17);
13186
13187 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13188 GIVE_UP (18);
13189 start_pos = it.current.pos;
13190
13191 /* Start displaying new lines in the desired matrix at the same
13192 vpos we would use in the current matrix, i.e. below
13193 last_unchanged_at_beg_row. */
13194 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13195 current_matrix);
13196 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13197 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13198
13199 xassert (it.hpos == 0 && it.current_x == 0);
13200 }
13201 else
13202 {
13203 /* There are no reusable lines at the start of the window.
13204 Start displaying in the first text line. */
13205 start_display (&it, w, start);
13206 it.vpos = it.first_vpos;
13207 start_pos = it.current.pos;
13208 }
13209
13210 /* Find the first row that is not affected by changes at the end of
13211 the buffer. Value will be null if there is no unchanged row, in
13212 which case we must redisplay to the end of the window. delta
13213 will be set to the value by which buffer positions beginning with
13214 first_unchanged_at_end_row have to be adjusted due to text
13215 changes. */
13216 first_unchanged_at_end_row
13217 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13218 IF_DEBUG (debug_delta = delta);
13219 IF_DEBUG (debug_delta_bytes = delta_bytes);
13220
13221 /* Set stop_pos to the buffer position up to which we will have to
13222 display new lines. If first_unchanged_at_end_row != NULL, this
13223 is the buffer position of the start of the line displayed in that
13224 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13225 that we don't stop at a buffer position. */
13226 stop_pos = 0;
13227 if (first_unchanged_at_end_row)
13228 {
13229 xassert (last_unchanged_at_beg_row == NULL
13230 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13231
13232 /* If this is a continuation line, move forward to the next one
13233 that isn't. Changes in lines above affect this line.
13234 Caution: this may move first_unchanged_at_end_row to a row
13235 not displaying text. */
13236 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13237 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13238 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13239 < it.last_visible_y))
13240 ++first_unchanged_at_end_row;
13241
13242 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13243 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13244 >= it.last_visible_y))
13245 first_unchanged_at_end_row = NULL;
13246 else
13247 {
13248 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13249 + delta);
13250 first_unchanged_at_end_vpos
13251 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13252 xassert (stop_pos >= Z - END_UNCHANGED);
13253 }
13254 }
13255 else if (last_unchanged_at_beg_row == NULL)
13256 GIVE_UP (19);
13257
13258
13259 #if GLYPH_DEBUG
13260
13261 /* Either there is no unchanged row at the end, or the one we have
13262 now displays text. This is a necessary condition for the window
13263 end pos calculation at the end of this function. */
13264 xassert (first_unchanged_at_end_row == NULL
13265 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13266
13267 debug_last_unchanged_at_beg_vpos
13268 = (last_unchanged_at_beg_row
13269 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13270 : -1);
13271 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13272
13273 #endif /* GLYPH_DEBUG != 0 */
13274
13275
13276 /* Display new lines. Set last_text_row to the last new line
13277 displayed which has text on it, i.e. might end up as being the
13278 line where the window_end_vpos is. */
13279 w->cursor.vpos = -1;
13280 last_text_row = NULL;
13281 overlay_arrow_seen = 0;
13282 while (it.current_y < it.last_visible_y
13283 && !fonts_changed_p
13284 && (first_unchanged_at_end_row == NULL
13285 || IT_CHARPOS (it) < stop_pos))
13286 {
13287 if (display_line (&it))
13288 last_text_row = it.glyph_row - 1;
13289 }
13290
13291 if (fonts_changed_p)
13292 return -1;
13293
13294
13295 /* Compute differences in buffer positions, y-positions etc. for
13296 lines reused at the bottom of the window. Compute what we can
13297 scroll. */
13298 if (first_unchanged_at_end_row
13299 /* No lines reused because we displayed everything up to the
13300 bottom of the window. */
13301 && it.current_y < it.last_visible_y)
13302 {
13303 dvpos = (it.vpos
13304 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13305 current_matrix));
13306 dy = it.current_y - first_unchanged_at_end_row->y;
13307 run.current_y = first_unchanged_at_end_row->y;
13308 run.desired_y = run.current_y + dy;
13309 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13310 }
13311 else
13312 {
13313 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13314 first_unchanged_at_end_row = NULL;
13315 }
13316 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13317
13318
13319 /* Find the cursor if not already found. We have to decide whether
13320 PT will appear on this window (it sometimes doesn't, but this is
13321 not a very frequent case.) This decision has to be made before
13322 the current matrix is altered. A value of cursor.vpos < 0 means
13323 that PT is either in one of the lines beginning at
13324 first_unchanged_at_end_row or below the window. Don't care for
13325 lines that might be displayed later at the window end; as
13326 mentioned, this is not a frequent case. */
13327 if (w->cursor.vpos < 0)
13328 {
13329 /* Cursor in unchanged rows at the top? */
13330 if (PT < CHARPOS (start_pos)
13331 && last_unchanged_at_beg_row)
13332 {
13333 row = row_containing_pos (w, PT,
13334 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13335 last_unchanged_at_beg_row + 1, 0);
13336 if (row)
13337 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13338 }
13339
13340 /* Start from first_unchanged_at_end_row looking for PT. */
13341 else if (first_unchanged_at_end_row)
13342 {
13343 row = row_containing_pos (w, PT - delta,
13344 first_unchanged_at_end_row, NULL, 0);
13345 if (row)
13346 set_cursor_from_row (w, row, w->current_matrix, delta,
13347 delta_bytes, dy, dvpos);
13348 }
13349
13350 /* Give up if cursor was not found. */
13351 if (w->cursor.vpos < 0)
13352 {
13353 clear_glyph_matrix (w->desired_matrix);
13354 return -1;
13355 }
13356 }
13357
13358 /* Don't let the cursor end in the scroll margins. */
13359 {
13360 int this_scroll_margin, cursor_height;
13361
13362 this_scroll_margin = max (0, scroll_margin);
13363 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13364 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13365 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13366
13367 if ((w->cursor.y < this_scroll_margin
13368 && CHARPOS (start) > BEGV)
13369 /* Don't take scroll margin into account at the bottom because
13370 old redisplay didn't do it either. */
13371 || w->cursor.y + cursor_height > it.last_visible_y)
13372 {
13373 w->cursor.vpos = -1;
13374 clear_glyph_matrix (w->desired_matrix);
13375 return -1;
13376 }
13377 }
13378
13379 /* Scroll the display. Do it before changing the current matrix so
13380 that xterm.c doesn't get confused about where the cursor glyph is
13381 found. */
13382 if (dy && run.height)
13383 {
13384 update_begin (f);
13385
13386 if (FRAME_WINDOW_P (f))
13387 {
13388 rif->update_window_begin_hook (w);
13389 rif->clear_window_mouse_face (w);
13390 rif->scroll_run_hook (w, &run);
13391 rif->update_window_end_hook (w, 0, 0);
13392 }
13393 else
13394 {
13395 /* Terminal frame. In this case, dvpos gives the number of
13396 lines to scroll by; dvpos < 0 means scroll up. */
13397 int first_unchanged_at_end_vpos
13398 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13399 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13400 int end = (WINDOW_TOP_EDGE_LINE (w)
13401 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13402 + window_internal_height (w));
13403
13404 /* Perform the operation on the screen. */
13405 if (dvpos > 0)
13406 {
13407 /* Scroll last_unchanged_at_beg_row to the end of the
13408 window down dvpos lines. */
13409 set_terminal_window (end);
13410
13411 /* On dumb terminals delete dvpos lines at the end
13412 before inserting dvpos empty lines. */
13413 if (!scroll_region_ok)
13414 ins_del_lines (end - dvpos, -dvpos);
13415
13416 /* Insert dvpos empty lines in front of
13417 last_unchanged_at_beg_row. */
13418 ins_del_lines (from, dvpos);
13419 }
13420 else if (dvpos < 0)
13421 {
13422 /* Scroll up last_unchanged_at_beg_vpos to the end of
13423 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13424 set_terminal_window (end);
13425
13426 /* Delete dvpos lines in front of
13427 last_unchanged_at_beg_vpos. ins_del_lines will set
13428 the cursor to the given vpos and emit |dvpos| delete
13429 line sequences. */
13430 ins_del_lines (from + dvpos, dvpos);
13431
13432 /* On a dumb terminal insert dvpos empty lines at the
13433 end. */
13434 if (!scroll_region_ok)
13435 ins_del_lines (end + dvpos, -dvpos);
13436 }
13437
13438 set_terminal_window (0);
13439 }
13440
13441 update_end (f);
13442 }
13443
13444 /* Shift reused rows of the current matrix to the right position.
13445 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13446 text. */
13447 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13448 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13449 if (dvpos < 0)
13450 {
13451 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13452 bottom_vpos, dvpos);
13453 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13454 bottom_vpos, 0);
13455 }
13456 else if (dvpos > 0)
13457 {
13458 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13459 bottom_vpos, dvpos);
13460 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13461 first_unchanged_at_end_vpos + dvpos, 0);
13462 }
13463
13464 /* For frame-based redisplay, make sure that current frame and window
13465 matrix are in sync with respect to glyph memory. */
13466 if (!FRAME_WINDOW_P (f))
13467 sync_frame_with_window_matrix_rows (w);
13468
13469 /* Adjust buffer positions in reused rows. */
13470 if (delta)
13471 increment_matrix_positions (current_matrix,
13472 first_unchanged_at_end_vpos + dvpos,
13473 bottom_vpos, delta, delta_bytes);
13474
13475 /* Adjust Y positions. */
13476 if (dy)
13477 shift_glyph_matrix (w, current_matrix,
13478 first_unchanged_at_end_vpos + dvpos,
13479 bottom_vpos, dy);
13480
13481 if (first_unchanged_at_end_row)
13482 first_unchanged_at_end_row += dvpos;
13483
13484 /* If scrolling up, there may be some lines to display at the end of
13485 the window. */
13486 last_text_row_at_end = NULL;
13487 if (dy < 0)
13488 {
13489 /* Scrolling up can leave for example a partially visible line
13490 at the end of the window to be redisplayed. */
13491 /* Set last_row to the glyph row in the current matrix where the
13492 window end line is found. It has been moved up or down in
13493 the matrix by dvpos. */
13494 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13495 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13496
13497 /* If last_row is the window end line, it should display text. */
13498 xassert (last_row->displays_text_p);
13499
13500 /* If window end line was partially visible before, begin
13501 displaying at that line. Otherwise begin displaying with the
13502 line following it. */
13503 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13504 {
13505 init_to_row_start (&it, w, last_row);
13506 it.vpos = last_vpos;
13507 it.current_y = last_row->y;
13508 }
13509 else
13510 {
13511 init_to_row_end (&it, w, last_row);
13512 it.vpos = 1 + last_vpos;
13513 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13514 ++last_row;
13515 }
13516
13517 /* We may start in a continuation line. If so, we have to
13518 get the right continuation_lines_width and current_x. */
13519 it.continuation_lines_width = last_row->continuation_lines_width;
13520 it.hpos = it.current_x = 0;
13521
13522 /* Display the rest of the lines at the window end. */
13523 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13524 while (it.current_y < it.last_visible_y
13525 && !fonts_changed_p)
13526 {
13527 /* Is it always sure that the display agrees with lines in
13528 the current matrix? I don't think so, so we mark rows
13529 displayed invalid in the current matrix by setting their
13530 enabled_p flag to zero. */
13531 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13532 if (display_line (&it))
13533 last_text_row_at_end = it.glyph_row - 1;
13534 }
13535 }
13536
13537 /* Update window_end_pos and window_end_vpos. */
13538 if (first_unchanged_at_end_row
13539 && first_unchanged_at_end_row->y < it.last_visible_y
13540 && !last_text_row_at_end)
13541 {
13542 /* Window end line if one of the preserved rows from the current
13543 matrix. Set row to the last row displaying text in current
13544 matrix starting at first_unchanged_at_end_row, after
13545 scrolling. */
13546 xassert (first_unchanged_at_end_row->displays_text_p);
13547 row = find_last_row_displaying_text (w->current_matrix, &it,
13548 first_unchanged_at_end_row);
13549 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13550
13551 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13552 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13553 w->window_end_vpos
13554 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13555 xassert (w->window_end_bytepos >= 0);
13556 IF_DEBUG (debug_method_add (w, "A"));
13557 }
13558 else if (last_text_row_at_end)
13559 {
13560 w->window_end_pos
13561 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13562 w->window_end_bytepos
13563 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13564 w->window_end_vpos
13565 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13566 xassert (w->window_end_bytepos >= 0);
13567 IF_DEBUG (debug_method_add (w, "B"));
13568 }
13569 else if (last_text_row)
13570 {
13571 /* We have displayed either to the end of the window or at the
13572 end of the window, i.e. the last row with text is to be found
13573 in the desired matrix. */
13574 w->window_end_pos
13575 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13576 w->window_end_bytepos
13577 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13578 w->window_end_vpos
13579 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13580 xassert (w->window_end_bytepos >= 0);
13581 }
13582 else if (first_unchanged_at_end_row == NULL
13583 && last_text_row == NULL
13584 && last_text_row_at_end == NULL)
13585 {
13586 /* Displayed to end of window, but no line containing text was
13587 displayed. Lines were deleted at the end of the window. */
13588 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13589 int vpos = XFASTINT (w->window_end_vpos);
13590 struct glyph_row *current_row = current_matrix->rows + vpos;
13591 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13592
13593 for (row = NULL;
13594 row == NULL && vpos >= first_vpos;
13595 --vpos, --current_row, --desired_row)
13596 {
13597 if (desired_row->enabled_p)
13598 {
13599 if (desired_row->displays_text_p)
13600 row = desired_row;
13601 }
13602 else if (current_row->displays_text_p)
13603 row = current_row;
13604 }
13605
13606 xassert (row != NULL);
13607 w->window_end_vpos = make_number (vpos + 1);
13608 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13609 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13610 xassert (w->window_end_bytepos >= 0);
13611 IF_DEBUG (debug_method_add (w, "C"));
13612 }
13613 else
13614 abort ();
13615
13616 #if 0 /* This leads to problems, for instance when the cursor is
13617 at ZV, and the cursor line displays no text. */
13618 /* Disable rows below what's displayed in the window. This makes
13619 debugging easier. */
13620 enable_glyph_matrix_rows (current_matrix,
13621 XFASTINT (w->window_end_vpos) + 1,
13622 bottom_vpos, 0);
13623 #endif
13624
13625 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13626 debug_end_vpos = XFASTINT (w->window_end_vpos));
13627
13628 /* Record that display has not been completed. */
13629 w->window_end_valid = Qnil;
13630 w->desired_matrix->no_scrolling_p = 1;
13631 return 3;
13632
13633 #undef GIVE_UP
13634 }
13635
13636
13637 \f
13638 /***********************************************************************
13639 More debugging support
13640 ***********************************************************************/
13641
13642 #if GLYPH_DEBUG
13643
13644 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13645 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13646 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13647
13648
13649 /* Dump the contents of glyph matrix MATRIX on stderr.
13650
13651 GLYPHS 0 means don't show glyph contents.
13652 GLYPHS 1 means show glyphs in short form
13653 GLYPHS > 1 means show glyphs in long form. */
13654
13655 void
13656 dump_glyph_matrix (matrix, glyphs)
13657 struct glyph_matrix *matrix;
13658 int glyphs;
13659 {
13660 int i;
13661 for (i = 0; i < matrix->nrows; ++i)
13662 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13663 }
13664
13665
13666 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13667 the glyph row and area where the glyph comes from. */
13668
13669 void
13670 dump_glyph (row, glyph, area)
13671 struct glyph_row *row;
13672 struct glyph *glyph;
13673 int area;
13674 {
13675 if (glyph->type == CHAR_GLYPH)
13676 {
13677 fprintf (stderr,
13678 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13679 glyph - row->glyphs[TEXT_AREA],
13680 'C',
13681 glyph->charpos,
13682 (BUFFERP (glyph->object)
13683 ? 'B'
13684 : (STRINGP (glyph->object)
13685 ? 'S'
13686 : '-')),
13687 glyph->pixel_width,
13688 glyph->u.ch,
13689 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13690 ? glyph->u.ch
13691 : '.'),
13692 glyph->face_id,
13693 glyph->left_box_line_p,
13694 glyph->right_box_line_p);
13695 }
13696 else if (glyph->type == STRETCH_GLYPH)
13697 {
13698 fprintf (stderr,
13699 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13700 glyph - row->glyphs[TEXT_AREA],
13701 'S',
13702 glyph->charpos,
13703 (BUFFERP (glyph->object)
13704 ? 'B'
13705 : (STRINGP (glyph->object)
13706 ? 'S'
13707 : '-')),
13708 glyph->pixel_width,
13709 0,
13710 '.',
13711 glyph->face_id,
13712 glyph->left_box_line_p,
13713 glyph->right_box_line_p);
13714 }
13715 else if (glyph->type == IMAGE_GLYPH)
13716 {
13717 fprintf (stderr,
13718 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13719 glyph - row->glyphs[TEXT_AREA],
13720 'I',
13721 glyph->charpos,
13722 (BUFFERP (glyph->object)
13723 ? 'B'
13724 : (STRINGP (glyph->object)
13725 ? 'S'
13726 : '-')),
13727 glyph->pixel_width,
13728 glyph->u.img_id,
13729 '.',
13730 glyph->face_id,
13731 glyph->left_box_line_p,
13732 glyph->right_box_line_p);
13733 }
13734 }
13735
13736
13737 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13738 GLYPHS 0 means don't show glyph contents.
13739 GLYPHS 1 means show glyphs in short form
13740 GLYPHS > 1 means show glyphs in long form. */
13741
13742 void
13743 dump_glyph_row (row, vpos, glyphs)
13744 struct glyph_row *row;
13745 int vpos, glyphs;
13746 {
13747 if (glyphs != 1)
13748 {
13749 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13750 fprintf (stderr, "=======================================================================\n");
13751
13752 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13753 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13754 vpos,
13755 MATRIX_ROW_START_CHARPOS (row),
13756 MATRIX_ROW_END_CHARPOS (row),
13757 row->used[TEXT_AREA],
13758 row->contains_overlapping_glyphs_p,
13759 row->enabled_p,
13760 row->truncated_on_left_p,
13761 row->truncated_on_right_p,
13762 row->overlay_arrow_p,
13763 row->continued_p,
13764 MATRIX_ROW_CONTINUATION_LINE_P (row),
13765 row->displays_text_p,
13766 row->ends_at_zv_p,
13767 row->fill_line_p,
13768 row->ends_in_middle_of_char_p,
13769 row->starts_in_middle_of_char_p,
13770 row->mouse_face_p,
13771 row->x,
13772 row->y,
13773 row->pixel_width,
13774 row->height,
13775 row->visible_height,
13776 row->ascent,
13777 row->phys_ascent);
13778 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13779 row->end.overlay_string_index,
13780 row->continuation_lines_width);
13781 fprintf (stderr, "%9d %5d\n",
13782 CHARPOS (row->start.string_pos),
13783 CHARPOS (row->end.string_pos));
13784 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13785 row->end.dpvec_index);
13786 }
13787
13788 if (glyphs > 1)
13789 {
13790 int area;
13791
13792 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13793 {
13794 struct glyph *glyph = row->glyphs[area];
13795 struct glyph *glyph_end = glyph + row->used[area];
13796
13797 /* Glyph for a line end in text. */
13798 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13799 ++glyph_end;
13800
13801 if (glyph < glyph_end)
13802 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13803
13804 for (; glyph < glyph_end; ++glyph)
13805 dump_glyph (row, glyph, area);
13806 }
13807 }
13808 else if (glyphs == 1)
13809 {
13810 int area;
13811
13812 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13813 {
13814 char *s = (char *) alloca (row->used[area] + 1);
13815 int i;
13816
13817 for (i = 0; i < row->used[area]; ++i)
13818 {
13819 struct glyph *glyph = row->glyphs[area] + i;
13820 if (glyph->type == CHAR_GLYPH
13821 && glyph->u.ch < 0x80
13822 && glyph->u.ch >= ' ')
13823 s[i] = glyph->u.ch;
13824 else
13825 s[i] = '.';
13826 }
13827
13828 s[i] = '\0';
13829 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13830 }
13831 }
13832 }
13833
13834
13835 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13836 Sdump_glyph_matrix, 0, 1, "p",
13837 doc: /* Dump the current matrix of the selected window to stderr.
13838 Shows contents of glyph row structures. With non-nil
13839 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13840 glyphs in short form, otherwise show glyphs in long form. */)
13841 (glyphs)
13842 Lisp_Object glyphs;
13843 {
13844 struct window *w = XWINDOW (selected_window);
13845 struct buffer *buffer = XBUFFER (w->buffer);
13846
13847 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13848 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13849 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13850 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13851 fprintf (stderr, "=============================================\n");
13852 dump_glyph_matrix (w->current_matrix,
13853 NILP (glyphs) ? 0 : XINT (glyphs));
13854 return Qnil;
13855 }
13856
13857
13858 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13859 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13860 ()
13861 {
13862 struct frame *f = XFRAME (selected_frame);
13863 dump_glyph_matrix (f->current_matrix, 1);
13864 return Qnil;
13865 }
13866
13867
13868 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13869 doc: /* Dump glyph row ROW to stderr.
13870 GLYPH 0 means don't dump glyphs.
13871 GLYPH 1 means dump glyphs in short form.
13872 GLYPH > 1 or omitted means dump glyphs in long form. */)
13873 (row, glyphs)
13874 Lisp_Object row, glyphs;
13875 {
13876 struct glyph_matrix *matrix;
13877 int vpos;
13878
13879 CHECK_NUMBER (row);
13880 matrix = XWINDOW (selected_window)->current_matrix;
13881 vpos = XINT (row);
13882 if (vpos >= 0 && vpos < matrix->nrows)
13883 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13884 vpos,
13885 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13886 return Qnil;
13887 }
13888
13889
13890 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13891 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13892 GLYPH 0 means don't dump glyphs.
13893 GLYPH 1 means dump glyphs in short form.
13894 GLYPH > 1 or omitted means dump glyphs in long form. */)
13895 (row, glyphs)
13896 Lisp_Object row, glyphs;
13897 {
13898 struct frame *sf = SELECTED_FRAME ();
13899 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13900 int vpos;
13901
13902 CHECK_NUMBER (row);
13903 vpos = XINT (row);
13904 if (vpos >= 0 && vpos < m->nrows)
13905 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13906 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13907 return Qnil;
13908 }
13909
13910
13911 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13912 doc: /* Toggle tracing of redisplay.
13913 With ARG, turn tracing on if and only if ARG is positive. */)
13914 (arg)
13915 Lisp_Object arg;
13916 {
13917 if (NILP (arg))
13918 trace_redisplay_p = !trace_redisplay_p;
13919 else
13920 {
13921 arg = Fprefix_numeric_value (arg);
13922 trace_redisplay_p = XINT (arg) > 0;
13923 }
13924
13925 return Qnil;
13926 }
13927
13928
13929 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13930 doc: /* Like `format', but print result to stderr.
13931 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13932 (nargs, args)
13933 int nargs;
13934 Lisp_Object *args;
13935 {
13936 Lisp_Object s = Fformat (nargs, args);
13937 fprintf (stderr, "%s", SDATA (s));
13938 return Qnil;
13939 }
13940
13941 #endif /* GLYPH_DEBUG */
13942
13943
13944 \f
13945 /***********************************************************************
13946 Building Desired Matrix Rows
13947 ***********************************************************************/
13948
13949 /* Return a temporary glyph row holding the glyphs of an overlay
13950 arrow. Only used for non-window-redisplay windows. */
13951
13952 static struct glyph_row *
13953 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
13954 struct window *w;
13955 Lisp_Object overlay_arrow_string;
13956 {
13957 struct frame *f = XFRAME (WINDOW_FRAME (w));
13958 struct buffer *buffer = XBUFFER (w->buffer);
13959 struct buffer *old = current_buffer;
13960 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
13961 int arrow_len = SCHARS (overlay_arrow_string);
13962 const unsigned char *arrow_end = arrow_string + arrow_len;
13963 const unsigned char *p;
13964 struct it it;
13965 int multibyte_p;
13966 int n_glyphs_before;
13967
13968 set_buffer_temp (buffer);
13969 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
13970 it.glyph_row->used[TEXT_AREA] = 0;
13971 SET_TEXT_POS (it.position, 0, 0);
13972
13973 multibyte_p = !NILP (buffer->enable_multibyte_characters);
13974 p = arrow_string;
13975 while (p < arrow_end)
13976 {
13977 Lisp_Object face, ilisp;
13978
13979 /* Get the next character. */
13980 if (multibyte_p)
13981 it.c = string_char_and_length (p, arrow_len, &it.len);
13982 else
13983 it.c = *p, it.len = 1;
13984 p += it.len;
13985
13986 /* Get its face. */
13987 ilisp = make_number (p - arrow_string);
13988 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
13989 it.face_id = compute_char_face (f, it.c, face);
13990
13991 /* Compute its width, get its glyphs. */
13992 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
13993 SET_TEXT_POS (it.position, -1, -1);
13994 PRODUCE_GLYPHS (&it);
13995
13996 /* If this character doesn't fit any more in the line, we have
13997 to remove some glyphs. */
13998 if (it.current_x > it.last_visible_x)
13999 {
14000 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14001 break;
14002 }
14003 }
14004
14005 set_buffer_temp (old);
14006 return it.glyph_row;
14007 }
14008
14009
14010 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14011 glyphs are only inserted for terminal frames since we can't really
14012 win with truncation glyphs when partially visible glyphs are
14013 involved. Which glyphs to insert is determined by
14014 produce_special_glyphs. */
14015
14016 static void
14017 insert_left_trunc_glyphs (it)
14018 struct it *it;
14019 {
14020 struct it truncate_it;
14021 struct glyph *from, *end, *to, *toend;
14022
14023 xassert (!FRAME_WINDOW_P (it->f));
14024
14025 /* Get the truncation glyphs. */
14026 truncate_it = *it;
14027 truncate_it.current_x = 0;
14028 truncate_it.face_id = DEFAULT_FACE_ID;
14029 truncate_it.glyph_row = &scratch_glyph_row;
14030 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14031 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14032 truncate_it.object = make_number (0);
14033 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14034
14035 /* Overwrite glyphs from IT with truncation glyphs. */
14036 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14037 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14038 to = it->glyph_row->glyphs[TEXT_AREA];
14039 toend = to + it->glyph_row->used[TEXT_AREA];
14040
14041 while (from < end)
14042 *to++ = *from++;
14043
14044 /* There may be padding glyphs left over. Overwrite them too. */
14045 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14046 {
14047 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14048 while (from < end)
14049 *to++ = *from++;
14050 }
14051
14052 if (to > toend)
14053 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14054 }
14055
14056
14057 /* Compute the pixel height and width of IT->glyph_row.
14058
14059 Most of the time, ascent and height of a display line will be equal
14060 to the max_ascent and max_height values of the display iterator
14061 structure. This is not the case if
14062
14063 1. We hit ZV without displaying anything. In this case, max_ascent
14064 and max_height will be zero.
14065
14066 2. We have some glyphs that don't contribute to the line height.
14067 (The glyph row flag contributes_to_line_height_p is for future
14068 pixmap extensions).
14069
14070 The first case is easily covered by using default values because in
14071 these cases, the line height does not really matter, except that it
14072 must not be zero. */
14073
14074 static void
14075 compute_line_metrics (it)
14076 struct it *it;
14077 {
14078 struct glyph_row *row = it->glyph_row;
14079 int area, i;
14080
14081 if (FRAME_WINDOW_P (it->f))
14082 {
14083 int i, min_y, max_y;
14084
14085 /* The line may consist of one space only, that was added to
14086 place the cursor on it. If so, the row's height hasn't been
14087 computed yet. */
14088 if (row->height == 0)
14089 {
14090 if (it->max_ascent + it->max_descent == 0)
14091 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14092 row->ascent = it->max_ascent;
14093 row->height = it->max_ascent + it->max_descent;
14094 row->phys_ascent = it->max_phys_ascent;
14095 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14096 }
14097
14098 /* Compute the width of this line. */
14099 row->pixel_width = row->x;
14100 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14101 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14102
14103 xassert (row->pixel_width >= 0);
14104 xassert (row->ascent >= 0 && row->height > 0);
14105
14106 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14107 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14108
14109 /* If first line's physical ascent is larger than its logical
14110 ascent, use the physical ascent, and make the row taller.
14111 This makes accented characters fully visible. */
14112 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14113 && row->phys_ascent > row->ascent)
14114 {
14115 row->height += row->phys_ascent - row->ascent;
14116 row->ascent = row->phys_ascent;
14117 }
14118
14119 /* Compute how much of the line is visible. */
14120 row->visible_height = row->height;
14121
14122 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14123 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14124
14125 if (row->y < min_y)
14126 row->visible_height -= min_y - row->y;
14127 if (row->y + row->height > max_y)
14128 row->visible_height -= row->y + row->height - max_y;
14129 }
14130 else
14131 {
14132 row->pixel_width = row->used[TEXT_AREA];
14133 if (row->continued_p)
14134 row->pixel_width -= it->continuation_pixel_width;
14135 else if (row->truncated_on_right_p)
14136 row->pixel_width -= it->truncation_pixel_width;
14137 row->ascent = row->phys_ascent = 0;
14138 row->height = row->phys_height = row->visible_height = 1;
14139 }
14140
14141 /* Compute a hash code for this row. */
14142 row->hash = 0;
14143 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14144 for (i = 0; i < row->used[area]; ++i)
14145 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14146 + row->glyphs[area][i].u.val
14147 + row->glyphs[area][i].face_id
14148 + row->glyphs[area][i].padding_p
14149 + (row->glyphs[area][i].type << 2));
14150
14151 it->max_ascent = it->max_descent = 0;
14152 it->max_phys_ascent = it->max_phys_descent = 0;
14153 }
14154
14155
14156 /* Append one space to the glyph row of iterator IT if doing a
14157 window-based redisplay. The space has the same face as
14158 IT->face_id. Value is non-zero if a space was added.
14159
14160 This function is called to make sure that there is always one glyph
14161 at the end of a glyph row that the cursor can be set on under
14162 window-systems. (If there weren't such a glyph we would not know
14163 how wide and tall a box cursor should be displayed).
14164
14165 At the same time this space let's a nicely handle clearing to the
14166 end of the line if the row ends in italic text. */
14167
14168 static int
14169 append_space_for_newline (it, default_face_p)
14170 struct it *it;
14171 int default_face_p;
14172 {
14173 if (FRAME_WINDOW_P (it->f))
14174 {
14175 int n = it->glyph_row->used[TEXT_AREA];
14176
14177 if (it->glyph_row->glyphs[TEXT_AREA] + n
14178 < it->glyph_row->glyphs[1 + TEXT_AREA])
14179 {
14180 /* Save some values that must not be changed.
14181 Must save IT->c and IT->len because otherwise
14182 ITERATOR_AT_END_P wouldn't work anymore after
14183 append_space_for_newline has been called. */
14184 enum display_element_type saved_what = it->what;
14185 int saved_c = it->c, saved_len = it->len;
14186 int saved_x = it->current_x;
14187 int saved_face_id = it->face_id;
14188 struct text_pos saved_pos;
14189 Lisp_Object saved_object;
14190 struct face *face;
14191
14192 saved_object = it->object;
14193 saved_pos = it->position;
14194
14195 it->what = IT_CHARACTER;
14196 bzero (&it->position, sizeof it->position);
14197 it->object = make_number (0);
14198 it->c = ' ';
14199 it->len = 1;
14200
14201 if (default_face_p)
14202 it->face_id = DEFAULT_FACE_ID;
14203 else if (it->face_before_selective_p)
14204 it->face_id = it->saved_face_id;
14205 face = FACE_FROM_ID (it->f, it->face_id);
14206 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14207
14208 PRODUCE_GLYPHS (it);
14209
14210 it->override_ascent = -1;
14211 it->constrain_row_ascent_descent_p = 0;
14212 it->current_x = saved_x;
14213 it->object = saved_object;
14214 it->position = saved_pos;
14215 it->what = saved_what;
14216 it->face_id = saved_face_id;
14217 it->len = saved_len;
14218 it->c = saved_c;
14219 return 1;
14220 }
14221 }
14222
14223 return 0;
14224 }
14225
14226
14227 /* Extend the face of the last glyph in the text area of IT->glyph_row
14228 to the end of the display line. Called from display_line.
14229 If the glyph row is empty, add a space glyph to it so that we
14230 know the face to draw. Set the glyph row flag fill_line_p. */
14231
14232 static void
14233 extend_face_to_end_of_line (it)
14234 struct it *it;
14235 {
14236 struct face *face;
14237 struct frame *f = it->f;
14238
14239 /* If line is already filled, do nothing. */
14240 if (it->current_x >= it->last_visible_x)
14241 return;
14242
14243 /* Face extension extends the background and box of IT->face_id
14244 to the end of the line. If the background equals the background
14245 of the frame, we don't have to do anything. */
14246 if (it->face_before_selective_p)
14247 face = FACE_FROM_ID (it->f, it->saved_face_id);
14248 else
14249 face = FACE_FROM_ID (f, it->face_id);
14250
14251 if (FRAME_WINDOW_P (f)
14252 && face->box == FACE_NO_BOX
14253 && face->background == FRAME_BACKGROUND_PIXEL (f)
14254 && !face->stipple)
14255 return;
14256
14257 /* Set the glyph row flag indicating that the face of the last glyph
14258 in the text area has to be drawn to the end of the text area. */
14259 it->glyph_row->fill_line_p = 1;
14260
14261 /* If current character of IT is not ASCII, make sure we have the
14262 ASCII face. This will be automatically undone the next time
14263 get_next_display_element returns a multibyte character. Note
14264 that the character will always be single byte in unibyte text. */
14265 if (!SINGLE_BYTE_CHAR_P (it->c))
14266 {
14267 it->face_id = FACE_FOR_CHAR (f, face, 0);
14268 }
14269
14270 if (FRAME_WINDOW_P (f))
14271 {
14272 /* If the row is empty, add a space with the current face of IT,
14273 so that we know which face to draw. */
14274 if (it->glyph_row->used[TEXT_AREA] == 0)
14275 {
14276 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14277 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14278 it->glyph_row->used[TEXT_AREA] = 1;
14279 }
14280 }
14281 else
14282 {
14283 /* Save some values that must not be changed. */
14284 int saved_x = it->current_x;
14285 struct text_pos saved_pos;
14286 Lisp_Object saved_object;
14287 enum display_element_type saved_what = it->what;
14288 int saved_face_id = it->face_id;
14289
14290 saved_object = it->object;
14291 saved_pos = it->position;
14292
14293 it->what = IT_CHARACTER;
14294 bzero (&it->position, sizeof it->position);
14295 it->object = make_number (0);
14296 it->c = ' ';
14297 it->len = 1;
14298 it->face_id = face->id;
14299
14300 PRODUCE_GLYPHS (it);
14301
14302 while (it->current_x <= it->last_visible_x)
14303 PRODUCE_GLYPHS (it);
14304
14305 /* Don't count these blanks really. It would let us insert a left
14306 truncation glyph below and make us set the cursor on them, maybe. */
14307 it->current_x = saved_x;
14308 it->object = saved_object;
14309 it->position = saved_pos;
14310 it->what = saved_what;
14311 it->face_id = saved_face_id;
14312 }
14313 }
14314
14315
14316 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14317 trailing whitespace. */
14318
14319 static int
14320 trailing_whitespace_p (charpos)
14321 int charpos;
14322 {
14323 int bytepos = CHAR_TO_BYTE (charpos);
14324 int c = 0;
14325
14326 while (bytepos < ZV_BYTE
14327 && (c = FETCH_CHAR (bytepos),
14328 c == ' ' || c == '\t'))
14329 ++bytepos;
14330
14331 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14332 {
14333 if (bytepos != PT_BYTE)
14334 return 1;
14335 }
14336 return 0;
14337 }
14338
14339
14340 /* Highlight trailing whitespace, if any, in ROW. */
14341
14342 void
14343 highlight_trailing_whitespace (f, row)
14344 struct frame *f;
14345 struct glyph_row *row;
14346 {
14347 int used = row->used[TEXT_AREA];
14348
14349 if (used)
14350 {
14351 struct glyph *start = row->glyphs[TEXT_AREA];
14352 struct glyph *glyph = start + used - 1;
14353
14354 /* Skip over glyphs inserted to display the cursor at the
14355 end of a line, for extending the face of the last glyph
14356 to the end of the line on terminals, and for truncation
14357 and continuation glyphs. */
14358 while (glyph >= start
14359 && glyph->type == CHAR_GLYPH
14360 && INTEGERP (glyph->object))
14361 --glyph;
14362
14363 /* If last glyph is a space or stretch, and it's trailing
14364 whitespace, set the face of all trailing whitespace glyphs in
14365 IT->glyph_row to `trailing-whitespace'. */
14366 if (glyph >= start
14367 && BUFFERP (glyph->object)
14368 && (glyph->type == STRETCH_GLYPH
14369 || (glyph->type == CHAR_GLYPH
14370 && glyph->u.ch == ' '))
14371 && trailing_whitespace_p (glyph->charpos))
14372 {
14373 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14374
14375 while (glyph >= start
14376 && BUFFERP (glyph->object)
14377 && (glyph->type == STRETCH_GLYPH
14378 || (glyph->type == CHAR_GLYPH
14379 && glyph->u.ch == ' ')))
14380 (glyph--)->face_id = face_id;
14381 }
14382 }
14383 }
14384
14385
14386 /* Value is non-zero if glyph row ROW in window W should be
14387 used to hold the cursor. */
14388
14389 static int
14390 cursor_row_p (w, row)
14391 struct window *w;
14392 struct glyph_row *row;
14393 {
14394 int cursor_row_p = 1;
14395
14396 if (PT == MATRIX_ROW_END_CHARPOS (row))
14397 {
14398 /* If the row ends with a newline from a string, we don't want
14399 the cursor there (if the row is continued it doesn't end in a
14400 newline). */
14401 if (CHARPOS (row->end.string_pos) >= 0
14402 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14403 cursor_row_p = row->continued_p;
14404
14405 /* If the row ends at ZV, display the cursor at the end of that
14406 row instead of at the start of the row below. */
14407 else if (row->ends_at_zv_p)
14408 cursor_row_p = 1;
14409 else
14410 cursor_row_p = 0;
14411 }
14412
14413 return cursor_row_p;
14414 }
14415
14416
14417 /* Construct the glyph row IT->glyph_row in the desired matrix of
14418 IT->w from text at the current position of IT. See dispextern.h
14419 for an overview of struct it. Value is non-zero if
14420 IT->glyph_row displays text, as opposed to a line displaying ZV
14421 only. */
14422
14423 static int
14424 display_line (it)
14425 struct it *it;
14426 {
14427 struct glyph_row *row = it->glyph_row;
14428 int overlay_arrow_bitmap;
14429 Lisp_Object overlay_arrow_string;
14430
14431 /* We always start displaying at hpos zero even if hscrolled. */
14432 xassert (it->hpos == 0 && it->current_x == 0);
14433
14434 /* We must not display in a row that's not a text row. */
14435 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14436 < it->w->desired_matrix->nrows);
14437
14438 /* Is IT->w showing the region? */
14439 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14440
14441 /* Clear the result glyph row and enable it. */
14442 prepare_desired_row (row);
14443
14444 row->y = it->current_y;
14445 row->start = it->start;
14446 row->continuation_lines_width = it->continuation_lines_width;
14447 row->displays_text_p = 1;
14448 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14449 it->starts_in_middle_of_char_p = 0;
14450
14451 /* Arrange the overlays nicely for our purposes. Usually, we call
14452 display_line on only one line at a time, in which case this
14453 can't really hurt too much, or we call it on lines which appear
14454 one after another in the buffer, in which case all calls to
14455 recenter_overlay_lists but the first will be pretty cheap. */
14456 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14457
14458 /* Move over display elements that are not visible because we are
14459 hscrolled. This may stop at an x-position < IT->first_visible_x
14460 if the first glyph is partially visible or if we hit a line end. */
14461 if (it->current_x < it->first_visible_x)
14462 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14463 MOVE_TO_POS | MOVE_TO_X);
14464
14465 /* Get the initial row height. This is either the height of the
14466 text hscrolled, if there is any, or zero. */
14467 row->ascent = it->max_ascent;
14468 row->height = it->max_ascent + it->max_descent;
14469 row->phys_ascent = it->max_phys_ascent;
14470 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14471
14472 /* Loop generating characters. The loop is left with IT on the next
14473 character to display. */
14474 while (1)
14475 {
14476 int n_glyphs_before, hpos_before, x_before;
14477 int x, i, nglyphs;
14478 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14479
14480 /* Retrieve the next thing to display. Value is zero if end of
14481 buffer reached. */
14482 if (!get_next_display_element (it))
14483 {
14484 /* Maybe add a space at the end of this line that is used to
14485 display the cursor there under X. Set the charpos of the
14486 first glyph of blank lines not corresponding to any text
14487 to -1. */
14488 #ifdef HAVE_WINDOW_SYSTEM
14489 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14490 row->exact_window_width_line_p = 1;
14491 else
14492 #endif /* HAVE_WINDOW_SYSTEM */
14493 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14494 || row->used[TEXT_AREA] == 0)
14495 {
14496 row->glyphs[TEXT_AREA]->charpos = -1;
14497 row->displays_text_p = 0;
14498
14499 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14500 && (!MINI_WINDOW_P (it->w)
14501 || (minibuf_level && EQ (it->window, minibuf_window))))
14502 row->indicate_empty_line_p = 1;
14503 }
14504
14505 it->continuation_lines_width = 0;
14506 row->ends_at_zv_p = 1;
14507 break;
14508 }
14509
14510 /* Now, get the metrics of what we want to display. This also
14511 generates glyphs in `row' (which is IT->glyph_row). */
14512 n_glyphs_before = row->used[TEXT_AREA];
14513 x = it->current_x;
14514
14515 /* Remember the line height so far in case the next element doesn't
14516 fit on the line. */
14517 if (!it->truncate_lines_p)
14518 {
14519 ascent = it->max_ascent;
14520 descent = it->max_descent;
14521 phys_ascent = it->max_phys_ascent;
14522 phys_descent = it->max_phys_descent;
14523 }
14524
14525 PRODUCE_GLYPHS (it);
14526
14527 /* If this display element was in marginal areas, continue with
14528 the next one. */
14529 if (it->area != TEXT_AREA)
14530 {
14531 row->ascent = max (row->ascent, it->max_ascent);
14532 row->height = max (row->height, it->max_ascent + it->max_descent);
14533 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14534 row->phys_height = max (row->phys_height,
14535 it->max_phys_ascent + it->max_phys_descent);
14536 set_iterator_to_next (it, 1);
14537 continue;
14538 }
14539
14540 /* Does the display element fit on the line? If we truncate
14541 lines, we should draw past the right edge of the window. If
14542 we don't truncate, we want to stop so that we can display the
14543 continuation glyph before the right margin. If lines are
14544 continued, there are two possible strategies for characters
14545 resulting in more than 1 glyph (e.g. tabs): Display as many
14546 glyphs as possible in this line and leave the rest for the
14547 continuation line, or display the whole element in the next
14548 line. Original redisplay did the former, so we do it also. */
14549 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14550 hpos_before = it->hpos;
14551 x_before = x;
14552
14553 if (/* Not a newline. */
14554 nglyphs > 0
14555 /* Glyphs produced fit entirely in the line. */
14556 && it->current_x < it->last_visible_x)
14557 {
14558 it->hpos += nglyphs;
14559 row->ascent = max (row->ascent, it->max_ascent);
14560 row->height = max (row->height, it->max_ascent + it->max_descent);
14561 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14562 row->phys_height = max (row->phys_height,
14563 it->max_phys_ascent + it->max_phys_descent);
14564 if (it->current_x - it->pixel_width < it->first_visible_x)
14565 row->x = x - it->first_visible_x;
14566 }
14567 else
14568 {
14569 int new_x;
14570 struct glyph *glyph;
14571
14572 for (i = 0; i < nglyphs; ++i, x = new_x)
14573 {
14574 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14575 new_x = x + glyph->pixel_width;
14576
14577 if (/* Lines are continued. */
14578 !it->truncate_lines_p
14579 && (/* Glyph doesn't fit on the line. */
14580 new_x > it->last_visible_x
14581 /* Or it fits exactly on a window system frame. */
14582 || (new_x == it->last_visible_x
14583 && FRAME_WINDOW_P (it->f))))
14584 {
14585 /* End of a continued line. */
14586
14587 if (it->hpos == 0
14588 || (new_x == it->last_visible_x
14589 && FRAME_WINDOW_P (it->f)))
14590 {
14591 /* Current glyph is the only one on the line or
14592 fits exactly on the line. We must continue
14593 the line because we can't draw the cursor
14594 after the glyph. */
14595 row->continued_p = 1;
14596 it->current_x = new_x;
14597 it->continuation_lines_width += new_x;
14598 ++it->hpos;
14599 if (i == nglyphs - 1)
14600 {
14601 set_iterator_to_next (it, 1);
14602 #ifdef HAVE_WINDOW_SYSTEM
14603 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14604 {
14605 if (!get_next_display_element (it))
14606 {
14607 row->exact_window_width_line_p = 1;
14608 it->continuation_lines_width = 0;
14609 row->continued_p = 0;
14610 row->ends_at_zv_p = 1;
14611 }
14612 else if (ITERATOR_AT_END_OF_LINE_P (it))
14613 {
14614 row->continued_p = 0;
14615 row->exact_window_width_line_p = 1;
14616 }
14617 }
14618 #endif /* HAVE_WINDOW_SYSTEM */
14619 }
14620 }
14621 else if (CHAR_GLYPH_PADDING_P (*glyph)
14622 && !FRAME_WINDOW_P (it->f))
14623 {
14624 /* A padding glyph that doesn't fit on this line.
14625 This means the whole character doesn't fit
14626 on the line. */
14627 row->used[TEXT_AREA] = n_glyphs_before;
14628
14629 /* Fill the rest of the row with continuation
14630 glyphs like in 20.x. */
14631 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14632 < row->glyphs[1 + TEXT_AREA])
14633 produce_special_glyphs (it, IT_CONTINUATION);
14634
14635 row->continued_p = 1;
14636 it->current_x = x_before;
14637 it->continuation_lines_width += x_before;
14638
14639 /* Restore the height to what it was before the
14640 element not fitting on the line. */
14641 it->max_ascent = ascent;
14642 it->max_descent = descent;
14643 it->max_phys_ascent = phys_ascent;
14644 it->max_phys_descent = phys_descent;
14645 }
14646 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14647 {
14648 /* A TAB that extends past the right edge of the
14649 window. This produces a single glyph on
14650 window system frames. We leave the glyph in
14651 this row and let it fill the row, but don't
14652 consume the TAB. */
14653 it->continuation_lines_width += it->last_visible_x;
14654 row->ends_in_middle_of_char_p = 1;
14655 row->continued_p = 1;
14656 glyph->pixel_width = it->last_visible_x - x;
14657 it->starts_in_middle_of_char_p = 1;
14658 }
14659 else
14660 {
14661 /* Something other than a TAB that draws past
14662 the right edge of the window. Restore
14663 positions to values before the element. */
14664 row->used[TEXT_AREA] = n_glyphs_before + i;
14665
14666 /* Display continuation glyphs. */
14667 if (!FRAME_WINDOW_P (it->f))
14668 produce_special_glyphs (it, IT_CONTINUATION);
14669 row->continued_p = 1;
14670
14671 it->continuation_lines_width += x;
14672
14673 if (nglyphs > 1 && i > 0)
14674 {
14675 row->ends_in_middle_of_char_p = 1;
14676 it->starts_in_middle_of_char_p = 1;
14677 }
14678
14679 /* Restore the height to what it was before the
14680 element not fitting on the line. */
14681 it->max_ascent = ascent;
14682 it->max_descent = descent;
14683 it->max_phys_ascent = phys_ascent;
14684 it->max_phys_descent = phys_descent;
14685 }
14686
14687 break;
14688 }
14689 else if (new_x > it->first_visible_x)
14690 {
14691 /* Increment number of glyphs actually displayed. */
14692 ++it->hpos;
14693
14694 if (x < it->first_visible_x)
14695 /* Glyph is partially visible, i.e. row starts at
14696 negative X position. */
14697 row->x = x - it->first_visible_x;
14698 }
14699 else
14700 {
14701 /* Glyph is completely off the left margin of the
14702 window. This should not happen because of the
14703 move_it_in_display_line at the start of this
14704 function, unless the text display area of the
14705 window is empty. */
14706 xassert (it->first_visible_x <= it->last_visible_x);
14707 }
14708 }
14709
14710 row->ascent = max (row->ascent, it->max_ascent);
14711 row->height = max (row->height, it->max_ascent + it->max_descent);
14712 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14713 row->phys_height = max (row->phys_height,
14714 it->max_phys_ascent + it->max_phys_descent);
14715
14716 /* End of this display line if row is continued. */
14717 if (row->continued_p || row->ends_at_zv_p)
14718 break;
14719 }
14720
14721 at_end_of_line:
14722 /* Is this a line end? If yes, we're also done, after making
14723 sure that a non-default face is extended up to the right
14724 margin of the window. */
14725 if (ITERATOR_AT_END_OF_LINE_P (it))
14726 {
14727 int used_before = row->used[TEXT_AREA];
14728
14729 row->ends_in_newline_from_string_p = STRINGP (it->object);
14730
14731 #ifdef HAVE_WINDOW_SYSTEM
14732 /* Add a space at the end of the line that is used to
14733 display the cursor there. */
14734 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14735 append_space_for_newline (it, 0);
14736 #endif /* HAVE_WINDOW_SYSTEM */
14737
14738 /* Extend the face to the end of the line. */
14739 extend_face_to_end_of_line (it);
14740
14741 /* Make sure we have the position. */
14742 if (used_before == 0)
14743 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14744
14745 /* Consume the line end. This skips over invisible lines. */
14746 set_iterator_to_next (it, 1);
14747 it->continuation_lines_width = 0;
14748 break;
14749 }
14750
14751 /* Proceed with next display element. Note that this skips
14752 over lines invisible because of selective display. */
14753 set_iterator_to_next (it, 1);
14754
14755 /* If we truncate lines, we are done when the last displayed
14756 glyphs reach past the right margin of the window. */
14757 if (it->truncate_lines_p
14758 && (FRAME_WINDOW_P (it->f)
14759 ? (it->current_x >= it->last_visible_x)
14760 : (it->current_x > it->last_visible_x)))
14761 {
14762 /* Maybe add truncation glyphs. */
14763 if (!FRAME_WINDOW_P (it->f))
14764 {
14765 int i, n;
14766
14767 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14768 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14769 break;
14770
14771 for (n = row->used[TEXT_AREA]; i < n; ++i)
14772 {
14773 row->used[TEXT_AREA] = i;
14774 produce_special_glyphs (it, IT_TRUNCATION);
14775 }
14776 }
14777 #ifdef HAVE_WINDOW_SYSTEM
14778 else
14779 {
14780 /* Don't truncate if we can overflow newline into fringe. */
14781 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14782 {
14783 if (!get_next_display_element (it))
14784 {
14785 #ifdef HAVE_WINDOW_SYSTEM
14786 it->continuation_lines_width = 0;
14787 row->ends_at_zv_p = 1;
14788 row->exact_window_width_line_p = 1;
14789 break;
14790 #endif /* HAVE_WINDOW_SYSTEM */
14791 }
14792 if (ITERATOR_AT_END_OF_LINE_P (it))
14793 {
14794 row->exact_window_width_line_p = 1;
14795 goto at_end_of_line;
14796 }
14797 }
14798 }
14799 #endif /* HAVE_WINDOW_SYSTEM */
14800
14801 row->truncated_on_right_p = 1;
14802 it->continuation_lines_width = 0;
14803 reseat_at_next_visible_line_start (it, 0);
14804 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14805 it->hpos = hpos_before;
14806 it->current_x = x_before;
14807 break;
14808 }
14809 }
14810
14811 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14812 at the left window margin. */
14813 if (it->first_visible_x
14814 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14815 {
14816 if (!FRAME_WINDOW_P (it->f))
14817 insert_left_trunc_glyphs (it);
14818 row->truncated_on_left_p = 1;
14819 }
14820
14821 /* If the start of this line is the overlay arrow-position, then
14822 mark this glyph row as the one containing the overlay arrow.
14823 This is clearly a mess with variable size fonts. It would be
14824 better to let it be displayed like cursors under X. */
14825 if (! overlay_arrow_seen
14826 && (overlay_arrow_string
14827 = overlay_arrow_at_row (it->f, row, &overlay_arrow_bitmap),
14828 !NILP (overlay_arrow_string)))
14829 {
14830 /* Overlay arrow in window redisplay is a fringe bitmap. */
14831 if (!FRAME_WINDOW_P (it->f))
14832 {
14833 struct glyph_row *arrow_row
14834 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
14835 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14836 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14837 struct glyph *p = row->glyphs[TEXT_AREA];
14838 struct glyph *p2, *end;
14839
14840 /* Copy the arrow glyphs. */
14841 while (glyph < arrow_end)
14842 *p++ = *glyph++;
14843
14844 /* Throw away padding glyphs. */
14845 p2 = p;
14846 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14847 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14848 ++p2;
14849 if (p2 > p)
14850 {
14851 while (p2 < end)
14852 *p++ = *p2++;
14853 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14854 }
14855 }
14856
14857 overlay_arrow_seen = 1;
14858 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
14859 row->overlay_arrow_p = 1;
14860 }
14861
14862 /* Compute pixel dimensions of this line. */
14863 compute_line_metrics (it);
14864
14865 /* Remember the position at which this line ends. */
14866 row->end = it->current;
14867
14868 /* Save fringe bitmaps in this row. */
14869 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14870 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14871 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14872 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14873
14874 it->left_user_fringe_bitmap = 0;
14875 it->left_user_fringe_face_id = 0;
14876 it->right_user_fringe_bitmap = 0;
14877 it->right_user_fringe_face_id = 0;
14878
14879 /* Maybe set the cursor. */
14880 if (it->w->cursor.vpos < 0
14881 && PT >= MATRIX_ROW_START_CHARPOS (row)
14882 && PT <= MATRIX_ROW_END_CHARPOS (row)
14883 && cursor_row_p (it->w, row))
14884 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14885
14886 /* Highlight trailing whitespace. */
14887 if (!NILP (Vshow_trailing_whitespace))
14888 highlight_trailing_whitespace (it->f, it->glyph_row);
14889
14890 /* Prepare for the next line. This line starts horizontally at (X
14891 HPOS) = (0 0). Vertical positions are incremented. As a
14892 convenience for the caller, IT->glyph_row is set to the next
14893 row to be used. */
14894 it->current_x = it->hpos = 0;
14895 it->current_y += row->height;
14896 ++it->vpos;
14897 ++it->glyph_row;
14898 it->start = it->current;
14899 return row->displays_text_p;
14900 }
14901
14902
14903 \f
14904 /***********************************************************************
14905 Menu Bar
14906 ***********************************************************************/
14907
14908 /* Redisplay the menu bar in the frame for window W.
14909
14910 The menu bar of X frames that don't have X toolkit support is
14911 displayed in a special window W->frame->menu_bar_window.
14912
14913 The menu bar of terminal frames is treated specially as far as
14914 glyph matrices are concerned. Menu bar lines are not part of
14915 windows, so the update is done directly on the frame matrix rows
14916 for the menu bar. */
14917
14918 static void
14919 display_menu_bar (w)
14920 struct window *w;
14921 {
14922 struct frame *f = XFRAME (WINDOW_FRAME (w));
14923 struct it it;
14924 Lisp_Object items;
14925 int i;
14926
14927 /* Don't do all this for graphical frames. */
14928 #ifdef HAVE_NTGUI
14929 if (!NILP (Vwindow_system))
14930 return;
14931 #endif
14932 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14933 if (FRAME_X_P (f))
14934 return;
14935 #endif
14936 #ifdef MAC_OS
14937 if (FRAME_MAC_P (f))
14938 return;
14939 #endif
14940
14941 #ifdef USE_X_TOOLKIT
14942 xassert (!FRAME_WINDOW_P (f));
14943 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
14944 it.first_visible_x = 0;
14945 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14946 #else /* not USE_X_TOOLKIT */
14947 if (FRAME_WINDOW_P (f))
14948 {
14949 /* Menu bar lines are displayed in the desired matrix of the
14950 dummy window menu_bar_window. */
14951 struct window *menu_w;
14952 xassert (WINDOWP (f->menu_bar_window));
14953 menu_w = XWINDOW (f->menu_bar_window);
14954 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
14955 MENU_FACE_ID);
14956 it.first_visible_x = 0;
14957 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14958 }
14959 else
14960 {
14961 /* This is a TTY frame, i.e. character hpos/vpos are used as
14962 pixel x/y. */
14963 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
14964 MENU_FACE_ID);
14965 it.first_visible_x = 0;
14966 it.last_visible_x = FRAME_COLS (f);
14967 }
14968 #endif /* not USE_X_TOOLKIT */
14969
14970 if (! mode_line_inverse_video)
14971 /* Force the menu-bar to be displayed in the default face. */
14972 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14973
14974 /* Clear all rows of the menu bar. */
14975 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
14976 {
14977 struct glyph_row *row = it.glyph_row + i;
14978 clear_glyph_row (row);
14979 row->enabled_p = 1;
14980 row->full_width_p = 1;
14981 }
14982
14983 /* Display all items of the menu bar. */
14984 items = FRAME_MENU_BAR_ITEMS (it.f);
14985 for (i = 0; i < XVECTOR (items)->size; i += 4)
14986 {
14987 Lisp_Object string;
14988
14989 /* Stop at nil string. */
14990 string = AREF (items, i + 1);
14991 if (NILP (string))
14992 break;
14993
14994 /* Remember where item was displayed. */
14995 AREF (items, i + 3) = make_number (it.hpos);
14996
14997 /* Display the item, pad with one space. */
14998 if (it.current_x < it.last_visible_x)
14999 display_string (NULL, string, Qnil, 0, 0, &it,
15000 SCHARS (string) + 1, 0, 0, -1);
15001 }
15002
15003 /* Fill out the line with spaces. */
15004 if (it.current_x < it.last_visible_x)
15005 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15006
15007 /* Compute the total height of the lines. */
15008 compute_line_metrics (&it);
15009 }
15010
15011
15012 \f
15013 /***********************************************************************
15014 Mode Line
15015 ***********************************************************************/
15016
15017 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15018 FORCE is non-zero, redisplay mode lines unconditionally.
15019 Otherwise, redisplay only mode lines that are garbaged. Value is
15020 the number of windows whose mode lines were redisplayed. */
15021
15022 static int
15023 redisplay_mode_lines (window, force)
15024 Lisp_Object window;
15025 int force;
15026 {
15027 int nwindows = 0;
15028
15029 while (!NILP (window))
15030 {
15031 struct window *w = XWINDOW (window);
15032
15033 if (WINDOWP (w->hchild))
15034 nwindows += redisplay_mode_lines (w->hchild, force);
15035 else if (WINDOWP (w->vchild))
15036 nwindows += redisplay_mode_lines (w->vchild, force);
15037 else if (force
15038 || FRAME_GARBAGED_P (XFRAME (w->frame))
15039 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15040 {
15041 struct text_pos lpoint;
15042 struct buffer *old = current_buffer;
15043
15044 /* Set the window's buffer for the mode line display. */
15045 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15046 set_buffer_internal_1 (XBUFFER (w->buffer));
15047
15048 /* Point refers normally to the selected window. For any
15049 other window, set up appropriate value. */
15050 if (!EQ (window, selected_window))
15051 {
15052 struct text_pos pt;
15053
15054 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15055 if (CHARPOS (pt) < BEGV)
15056 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15057 else if (CHARPOS (pt) > (ZV - 1))
15058 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15059 else
15060 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15061 }
15062
15063 /* Display mode lines. */
15064 clear_glyph_matrix (w->desired_matrix);
15065 if (display_mode_lines (w))
15066 {
15067 ++nwindows;
15068 w->must_be_updated_p = 1;
15069 }
15070
15071 /* Restore old settings. */
15072 set_buffer_internal_1 (old);
15073 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15074 }
15075
15076 window = w->next;
15077 }
15078
15079 return nwindows;
15080 }
15081
15082
15083 /* Display the mode and/or top line of window W. Value is the number
15084 of mode lines displayed. */
15085
15086 static int
15087 display_mode_lines (w)
15088 struct window *w;
15089 {
15090 Lisp_Object old_selected_window, old_selected_frame;
15091 int n = 0;
15092
15093 old_selected_frame = selected_frame;
15094 selected_frame = w->frame;
15095 old_selected_window = selected_window;
15096 XSETWINDOW (selected_window, w);
15097
15098 /* These will be set while the mode line specs are processed. */
15099 line_number_displayed = 0;
15100 w->column_number_displayed = Qnil;
15101
15102 if (WINDOW_WANTS_MODELINE_P (w))
15103 {
15104 struct window *sel_w = XWINDOW (old_selected_window);
15105
15106 /* Select mode line face based on the real selected window. */
15107 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15108 current_buffer->mode_line_format);
15109 ++n;
15110 }
15111
15112 if (WINDOW_WANTS_HEADER_LINE_P (w))
15113 {
15114 display_mode_line (w, HEADER_LINE_FACE_ID,
15115 current_buffer->header_line_format);
15116 ++n;
15117 }
15118
15119 selected_frame = old_selected_frame;
15120 selected_window = old_selected_window;
15121 return n;
15122 }
15123
15124
15125 /* Display mode or top line of window W. FACE_ID specifies which line
15126 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15127 FORMAT is the mode line format to display. Value is the pixel
15128 height of the mode line displayed. */
15129
15130 static int
15131 display_mode_line (w, face_id, format)
15132 struct window *w;
15133 enum face_id face_id;
15134 Lisp_Object format;
15135 {
15136 struct it it;
15137 struct face *face;
15138
15139 init_iterator (&it, w, -1, -1, NULL, face_id);
15140 prepare_desired_row (it.glyph_row);
15141
15142 it.glyph_row->mode_line_p = 1;
15143
15144 if (! mode_line_inverse_video)
15145 /* Force the mode-line to be displayed in the default face. */
15146 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15147
15148 /* Temporarily make frame's keyboard the current kboard so that
15149 kboard-local variables in the mode_line_format will get the right
15150 values. */
15151 push_frame_kboard (it.f);
15152 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15153 pop_frame_kboard ();
15154
15155 /* Fill up with spaces. */
15156 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15157
15158 compute_line_metrics (&it);
15159 it.glyph_row->full_width_p = 1;
15160 it.glyph_row->continued_p = 0;
15161 it.glyph_row->truncated_on_left_p = 0;
15162 it.glyph_row->truncated_on_right_p = 0;
15163
15164 /* Make a 3D mode-line have a shadow at its right end. */
15165 face = FACE_FROM_ID (it.f, face_id);
15166 extend_face_to_end_of_line (&it);
15167 if (face->box != FACE_NO_BOX)
15168 {
15169 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15170 + it.glyph_row->used[TEXT_AREA] - 1);
15171 last->right_box_line_p = 1;
15172 }
15173
15174 return it.glyph_row->height;
15175 }
15176
15177 /* Alist that caches the results of :propertize.
15178 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15179 Lisp_Object mode_line_proptrans_alist;
15180
15181 /* List of strings making up the mode-line. */
15182 Lisp_Object mode_line_string_list;
15183
15184 /* Base face property when building propertized mode line string. */
15185 static Lisp_Object mode_line_string_face;
15186 static Lisp_Object mode_line_string_face_prop;
15187
15188
15189 /* Contribute ELT to the mode line for window IT->w. How it
15190 translates into text depends on its data type.
15191
15192 IT describes the display environment in which we display, as usual.
15193
15194 DEPTH is the depth in recursion. It is used to prevent
15195 infinite recursion here.
15196
15197 FIELD_WIDTH is the number of characters the display of ELT should
15198 occupy in the mode line, and PRECISION is the maximum number of
15199 characters to display from ELT's representation. See
15200 display_string for details.
15201
15202 Returns the hpos of the end of the text generated by ELT.
15203
15204 PROPS is a property list to add to any string we encounter.
15205
15206 If RISKY is nonzero, remove (disregard) any properties in any string
15207 we encounter, and ignore :eval and :propertize.
15208
15209 If the global variable `frame_title_ptr' is non-NULL, then the output
15210 is passed to `store_frame_title' instead of `display_string'. */
15211
15212 static int
15213 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15214 struct it *it;
15215 int depth;
15216 int field_width, precision;
15217 Lisp_Object elt, props;
15218 int risky;
15219 {
15220 int n = 0, field, prec;
15221 int literal = 0;
15222
15223 tail_recurse:
15224 if (depth > 100)
15225 elt = build_string ("*too-deep*");
15226
15227 depth++;
15228
15229 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15230 {
15231 case Lisp_String:
15232 {
15233 /* A string: output it and check for %-constructs within it. */
15234 unsigned char c;
15235 const unsigned char *this, *lisp_string;
15236
15237 if (!NILP (props) || risky)
15238 {
15239 Lisp_Object oprops, aelt;
15240 oprops = Ftext_properties_at (make_number (0), elt);
15241
15242 if (NILP (Fequal (props, oprops)) || risky)
15243 {
15244 /* If the starting string has properties,
15245 merge the specified ones onto the existing ones. */
15246 if (! NILP (oprops) && !risky)
15247 {
15248 Lisp_Object tem;
15249
15250 oprops = Fcopy_sequence (oprops);
15251 tem = props;
15252 while (CONSP (tem))
15253 {
15254 oprops = Fplist_put (oprops, XCAR (tem),
15255 XCAR (XCDR (tem)));
15256 tem = XCDR (XCDR (tem));
15257 }
15258 props = oprops;
15259 }
15260
15261 aelt = Fassoc (elt, mode_line_proptrans_alist);
15262 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15263 {
15264 mode_line_proptrans_alist
15265 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15266 elt = XCAR (aelt);
15267 }
15268 else
15269 {
15270 Lisp_Object tem;
15271
15272 elt = Fcopy_sequence (elt);
15273 Fset_text_properties (make_number (0), Flength (elt),
15274 props, elt);
15275 /* Add this item to mode_line_proptrans_alist. */
15276 mode_line_proptrans_alist
15277 = Fcons (Fcons (elt, props),
15278 mode_line_proptrans_alist);
15279 /* Truncate mode_line_proptrans_alist
15280 to at most 50 elements. */
15281 tem = Fnthcdr (make_number (50),
15282 mode_line_proptrans_alist);
15283 if (! NILP (tem))
15284 XSETCDR (tem, Qnil);
15285 }
15286 }
15287 }
15288
15289 this = SDATA (elt);
15290 lisp_string = this;
15291
15292 if (literal)
15293 {
15294 prec = precision - n;
15295 if (frame_title_ptr)
15296 n += store_frame_title (SDATA (elt), -1, prec);
15297 else if (!NILP (mode_line_string_list))
15298 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15299 else
15300 n += display_string (NULL, elt, Qnil, 0, 0, it,
15301 0, prec, 0, STRING_MULTIBYTE (elt));
15302
15303 break;
15304 }
15305
15306 while ((precision <= 0 || n < precision)
15307 && *this
15308 && (frame_title_ptr
15309 || !NILP (mode_line_string_list)
15310 || it->current_x < it->last_visible_x))
15311 {
15312 const unsigned char *last = this;
15313
15314 /* Advance to end of string or next format specifier. */
15315 while ((c = *this++) != '\0' && c != '%')
15316 ;
15317
15318 if (this - 1 != last)
15319 {
15320 /* Output to end of string or up to '%'. Field width
15321 is length of string. Don't output more than
15322 PRECISION allows us. */
15323 --this;
15324
15325 prec = chars_in_text (last, this - last);
15326 if (precision > 0 && prec > precision - n)
15327 prec = precision - n;
15328
15329 if (frame_title_ptr)
15330 n += store_frame_title (last, 0, prec);
15331 else if (!NILP (mode_line_string_list))
15332 {
15333 int bytepos = last - lisp_string;
15334 int charpos = string_byte_to_char (elt, bytepos);
15335 n += store_mode_line_string (NULL,
15336 Fsubstring (elt, make_number (charpos),
15337 make_number (charpos + prec)),
15338 0, 0, 0, Qnil);
15339 }
15340 else
15341 {
15342 int bytepos = last - lisp_string;
15343 int charpos = string_byte_to_char (elt, bytepos);
15344 n += display_string (NULL, elt, Qnil, 0, charpos,
15345 it, 0, prec, 0,
15346 STRING_MULTIBYTE (elt));
15347 }
15348 }
15349 else /* c == '%' */
15350 {
15351 const unsigned char *percent_position = this;
15352
15353 /* Get the specified minimum width. Zero means
15354 don't pad. */
15355 field = 0;
15356 while ((c = *this++) >= '0' && c <= '9')
15357 field = field * 10 + c - '0';
15358
15359 /* Don't pad beyond the total padding allowed. */
15360 if (field_width - n > 0 && field > field_width - n)
15361 field = field_width - n;
15362
15363 /* Note that either PRECISION <= 0 or N < PRECISION. */
15364 prec = precision - n;
15365
15366 if (c == 'M')
15367 n += display_mode_element (it, depth, field, prec,
15368 Vglobal_mode_string, props,
15369 risky);
15370 else if (c != 0)
15371 {
15372 int multibyte;
15373 int bytepos, charpos;
15374 unsigned char *spec;
15375
15376 bytepos = percent_position - lisp_string;
15377 charpos = (STRING_MULTIBYTE (elt)
15378 ? string_byte_to_char (elt, bytepos)
15379 : bytepos);
15380
15381 spec
15382 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15383
15384 if (frame_title_ptr)
15385 n += store_frame_title (spec, field, prec);
15386 else if (!NILP (mode_line_string_list))
15387 {
15388 int len = strlen (spec);
15389 Lisp_Object tem = make_string (spec, len);
15390 props = Ftext_properties_at (make_number (charpos), elt);
15391 /* Should only keep face property in props */
15392 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15393 }
15394 else
15395 {
15396 int nglyphs_before, nwritten;
15397
15398 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15399 nwritten = display_string (spec, Qnil, elt,
15400 charpos, 0, it,
15401 field, prec, 0,
15402 multibyte);
15403
15404 /* Assign to the glyphs written above the
15405 string where the `%x' came from, position
15406 of the `%'. */
15407 if (nwritten > 0)
15408 {
15409 struct glyph *glyph
15410 = (it->glyph_row->glyphs[TEXT_AREA]
15411 + nglyphs_before);
15412 int i;
15413
15414 for (i = 0; i < nwritten; ++i)
15415 {
15416 glyph[i].object = elt;
15417 glyph[i].charpos = charpos;
15418 }
15419
15420 n += nwritten;
15421 }
15422 }
15423 }
15424 else /* c == 0 */
15425 break;
15426 }
15427 }
15428 }
15429 break;
15430
15431 case Lisp_Symbol:
15432 /* A symbol: process the value of the symbol recursively
15433 as if it appeared here directly. Avoid error if symbol void.
15434 Special case: if value of symbol is a string, output the string
15435 literally. */
15436 {
15437 register Lisp_Object tem;
15438
15439 /* If the variable is not marked as risky to set
15440 then its contents are risky to use. */
15441 if (NILP (Fget (elt, Qrisky_local_variable)))
15442 risky = 1;
15443
15444 tem = Fboundp (elt);
15445 if (!NILP (tem))
15446 {
15447 tem = Fsymbol_value (elt);
15448 /* If value is a string, output that string literally:
15449 don't check for % within it. */
15450 if (STRINGP (tem))
15451 literal = 1;
15452
15453 if (!EQ (tem, elt))
15454 {
15455 /* Give up right away for nil or t. */
15456 elt = tem;
15457 goto tail_recurse;
15458 }
15459 }
15460 }
15461 break;
15462
15463 case Lisp_Cons:
15464 {
15465 register Lisp_Object car, tem;
15466
15467 /* A cons cell: five distinct cases.
15468 If first element is :eval or :propertize, do something special.
15469 If first element is a string or a cons, process all the elements
15470 and effectively concatenate them.
15471 If first element is a negative number, truncate displaying cdr to
15472 at most that many characters. If positive, pad (with spaces)
15473 to at least that many characters.
15474 If first element is a symbol, process the cadr or caddr recursively
15475 according to whether the symbol's value is non-nil or nil. */
15476 car = XCAR (elt);
15477 if (EQ (car, QCeval))
15478 {
15479 /* An element of the form (:eval FORM) means evaluate FORM
15480 and use the result as mode line elements. */
15481
15482 if (risky)
15483 break;
15484
15485 if (CONSP (XCDR (elt)))
15486 {
15487 Lisp_Object spec;
15488 spec = safe_eval (XCAR (XCDR (elt)));
15489 n += display_mode_element (it, depth, field_width - n,
15490 precision - n, spec, props,
15491 risky);
15492 }
15493 }
15494 else if (EQ (car, QCpropertize))
15495 {
15496 /* An element of the form (:propertize ELT PROPS...)
15497 means display ELT but applying properties PROPS. */
15498
15499 if (risky)
15500 break;
15501
15502 if (CONSP (XCDR (elt)))
15503 n += display_mode_element (it, depth, field_width - n,
15504 precision - n, XCAR (XCDR (elt)),
15505 XCDR (XCDR (elt)), risky);
15506 }
15507 else if (SYMBOLP (car))
15508 {
15509 tem = Fboundp (car);
15510 elt = XCDR (elt);
15511 if (!CONSP (elt))
15512 goto invalid;
15513 /* elt is now the cdr, and we know it is a cons cell.
15514 Use its car if CAR has a non-nil value. */
15515 if (!NILP (tem))
15516 {
15517 tem = Fsymbol_value (car);
15518 if (!NILP (tem))
15519 {
15520 elt = XCAR (elt);
15521 goto tail_recurse;
15522 }
15523 }
15524 /* Symbol's value is nil (or symbol is unbound)
15525 Get the cddr of the original list
15526 and if possible find the caddr and use that. */
15527 elt = XCDR (elt);
15528 if (NILP (elt))
15529 break;
15530 else if (!CONSP (elt))
15531 goto invalid;
15532 elt = XCAR (elt);
15533 goto tail_recurse;
15534 }
15535 else if (INTEGERP (car))
15536 {
15537 register int lim = XINT (car);
15538 elt = XCDR (elt);
15539 if (lim < 0)
15540 {
15541 /* Negative int means reduce maximum width. */
15542 if (precision <= 0)
15543 precision = -lim;
15544 else
15545 precision = min (precision, -lim);
15546 }
15547 else if (lim > 0)
15548 {
15549 /* Padding specified. Don't let it be more than
15550 current maximum. */
15551 if (precision > 0)
15552 lim = min (precision, lim);
15553
15554 /* If that's more padding than already wanted, queue it.
15555 But don't reduce padding already specified even if
15556 that is beyond the current truncation point. */
15557 field_width = max (lim, field_width);
15558 }
15559 goto tail_recurse;
15560 }
15561 else if (STRINGP (car) || CONSP (car))
15562 {
15563 register int limit = 50;
15564 /* Limit is to protect against circular lists. */
15565 while (CONSP (elt)
15566 && --limit > 0
15567 && (precision <= 0 || n < precision))
15568 {
15569 n += display_mode_element (it, depth, field_width - n,
15570 precision - n, XCAR (elt),
15571 props, risky);
15572 elt = XCDR (elt);
15573 }
15574 }
15575 }
15576 break;
15577
15578 default:
15579 invalid:
15580 elt = build_string ("*invalid*");
15581 goto tail_recurse;
15582 }
15583
15584 /* Pad to FIELD_WIDTH. */
15585 if (field_width > 0 && n < field_width)
15586 {
15587 if (frame_title_ptr)
15588 n += store_frame_title ("", field_width - n, 0);
15589 else if (!NILP (mode_line_string_list))
15590 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15591 else
15592 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15593 0, 0, 0);
15594 }
15595
15596 return n;
15597 }
15598
15599 /* Store a mode-line string element in mode_line_string_list.
15600
15601 If STRING is non-null, display that C string. Otherwise, the Lisp
15602 string LISP_STRING is displayed.
15603
15604 FIELD_WIDTH is the minimum number of output glyphs to produce.
15605 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15606 with spaces. FIELD_WIDTH <= 0 means don't pad.
15607
15608 PRECISION is the maximum number of characters to output from
15609 STRING. PRECISION <= 0 means don't truncate the string.
15610
15611 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15612 properties to the string.
15613
15614 PROPS are the properties to add to the string.
15615 The mode_line_string_face face property is always added to the string.
15616 */
15617
15618 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15619 char *string;
15620 Lisp_Object lisp_string;
15621 int copy_string;
15622 int field_width;
15623 int precision;
15624 Lisp_Object props;
15625 {
15626 int len;
15627 int n = 0;
15628
15629 if (string != NULL)
15630 {
15631 len = strlen (string);
15632 if (precision > 0 && len > precision)
15633 len = precision;
15634 lisp_string = make_string (string, len);
15635 if (NILP (props))
15636 props = mode_line_string_face_prop;
15637 else if (!NILP (mode_line_string_face))
15638 {
15639 Lisp_Object face = Fplist_get (props, Qface);
15640 props = Fcopy_sequence (props);
15641 if (NILP (face))
15642 face = mode_line_string_face;
15643 else
15644 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15645 props = Fplist_put (props, Qface, face);
15646 }
15647 Fadd_text_properties (make_number (0), make_number (len),
15648 props, lisp_string);
15649 }
15650 else
15651 {
15652 len = XFASTINT (Flength (lisp_string));
15653 if (precision > 0 && len > precision)
15654 {
15655 len = precision;
15656 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15657 precision = -1;
15658 }
15659 if (!NILP (mode_line_string_face))
15660 {
15661 Lisp_Object face;
15662 if (NILP (props))
15663 props = Ftext_properties_at (make_number (0), lisp_string);
15664 face = Fplist_get (props, Qface);
15665 if (NILP (face))
15666 face = mode_line_string_face;
15667 else
15668 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15669 props = Fcons (Qface, Fcons (face, Qnil));
15670 if (copy_string)
15671 lisp_string = Fcopy_sequence (lisp_string);
15672 }
15673 if (!NILP (props))
15674 Fadd_text_properties (make_number (0), make_number (len),
15675 props, lisp_string);
15676 }
15677
15678 if (len > 0)
15679 {
15680 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15681 n += len;
15682 }
15683
15684 if (field_width > len)
15685 {
15686 field_width -= len;
15687 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15688 if (!NILP (props))
15689 Fadd_text_properties (make_number (0), make_number (field_width),
15690 props, lisp_string);
15691 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15692 n += field_width;
15693 }
15694
15695 return n;
15696 }
15697
15698
15699 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15700 0, 3, 0,
15701 doc: /* Return the mode-line of selected window as a string.
15702 First optional arg FORMAT specifies a different format string (see
15703 `mode-line-format' for details) to use. If FORMAT is t, return
15704 the buffer's header-line. Second optional arg WINDOW specifies a
15705 different window to use as the context for the formatting.
15706 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15707 (format, window, no_props)
15708 Lisp_Object format, window, no_props;
15709 {
15710 struct it it;
15711 int len;
15712 struct window *w;
15713 struct buffer *old_buffer = NULL;
15714 enum face_id face_id = DEFAULT_FACE_ID;
15715
15716 if (NILP (window))
15717 window = selected_window;
15718 CHECK_WINDOW (window);
15719 w = XWINDOW (window);
15720 CHECK_BUFFER (w->buffer);
15721
15722 if (XBUFFER (w->buffer) != current_buffer)
15723 {
15724 old_buffer = current_buffer;
15725 set_buffer_internal_1 (XBUFFER (w->buffer));
15726 }
15727
15728 if (NILP (format) || EQ (format, Qt))
15729 {
15730 face_id = NILP (format)
15731 ? CURRENT_MODE_LINE_FACE_ID (w) :
15732 HEADER_LINE_FACE_ID;
15733 format = NILP (format)
15734 ? current_buffer->mode_line_format
15735 : current_buffer->header_line_format;
15736 }
15737
15738 init_iterator (&it, w, -1, -1, NULL, face_id);
15739
15740 if (NILP (no_props))
15741 {
15742 mode_line_string_face =
15743 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15744 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15745 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15746
15747 mode_line_string_face_prop =
15748 NILP (mode_line_string_face) ? Qnil :
15749 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15750
15751 /* We need a dummy last element in mode_line_string_list to
15752 indicate we are building the propertized mode-line string.
15753 Using mode_line_string_face_prop here GC protects it. */
15754 mode_line_string_list =
15755 Fcons (mode_line_string_face_prop, Qnil);
15756 frame_title_ptr = NULL;
15757 }
15758 else
15759 {
15760 mode_line_string_face_prop = Qnil;
15761 mode_line_string_list = Qnil;
15762 frame_title_ptr = frame_title_buf;
15763 }
15764
15765 push_frame_kboard (it.f);
15766 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15767 pop_frame_kboard ();
15768
15769 if (old_buffer)
15770 set_buffer_internal_1 (old_buffer);
15771
15772 if (NILP (no_props))
15773 {
15774 Lisp_Object str;
15775 mode_line_string_list = Fnreverse (mode_line_string_list);
15776 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15777 make_string ("", 0));
15778 mode_line_string_face_prop = Qnil;
15779 mode_line_string_list = Qnil;
15780 return str;
15781 }
15782
15783 len = frame_title_ptr - frame_title_buf;
15784 if (len > 0 && frame_title_ptr[-1] == '-')
15785 {
15786 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15787 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15788 ;
15789 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15790 if (len > frame_title_ptr - frame_title_buf)
15791 len = frame_title_ptr - frame_title_buf;
15792 }
15793
15794 frame_title_ptr = NULL;
15795 return make_string (frame_title_buf, len);
15796 }
15797
15798 /* Write a null-terminated, right justified decimal representation of
15799 the positive integer D to BUF using a minimal field width WIDTH. */
15800
15801 static void
15802 pint2str (buf, width, d)
15803 register char *buf;
15804 register int width;
15805 register int d;
15806 {
15807 register char *p = buf;
15808
15809 if (d <= 0)
15810 *p++ = '0';
15811 else
15812 {
15813 while (d > 0)
15814 {
15815 *p++ = d % 10 + '0';
15816 d /= 10;
15817 }
15818 }
15819
15820 for (width -= (int) (p - buf); width > 0; --width)
15821 *p++ = ' ';
15822 *p-- = '\0';
15823 while (p > buf)
15824 {
15825 d = *buf;
15826 *buf++ = *p;
15827 *p-- = d;
15828 }
15829 }
15830
15831 /* Write a null-terminated, right justified decimal and "human
15832 readable" representation of the nonnegative integer D to BUF using
15833 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15834
15835 static const char power_letter[] =
15836 {
15837 0, /* not used */
15838 'k', /* kilo */
15839 'M', /* mega */
15840 'G', /* giga */
15841 'T', /* tera */
15842 'P', /* peta */
15843 'E', /* exa */
15844 'Z', /* zetta */
15845 'Y' /* yotta */
15846 };
15847
15848 static void
15849 pint2hrstr (buf, width, d)
15850 char *buf;
15851 int width;
15852 int d;
15853 {
15854 /* We aim to represent the nonnegative integer D as
15855 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15856 int quotient = d;
15857 int remainder = 0;
15858 /* -1 means: do not use TENTHS. */
15859 int tenths = -1;
15860 int exponent = 0;
15861
15862 /* Length of QUOTIENT.TENTHS as a string. */
15863 int length;
15864
15865 char * psuffix;
15866 char * p;
15867
15868 if (1000 <= quotient)
15869 {
15870 /* Scale to the appropriate EXPONENT. */
15871 do
15872 {
15873 remainder = quotient % 1000;
15874 quotient /= 1000;
15875 exponent++;
15876 }
15877 while (1000 <= quotient);
15878
15879 /* Round to nearest and decide whether to use TENTHS or not. */
15880 if (quotient <= 9)
15881 {
15882 tenths = remainder / 100;
15883 if (50 <= remainder % 100)
15884 if (tenths < 9)
15885 tenths++;
15886 else
15887 {
15888 quotient++;
15889 if (quotient == 10)
15890 tenths = -1;
15891 else
15892 tenths = 0;
15893 }
15894 }
15895 else
15896 if (500 <= remainder)
15897 if (quotient < 999)
15898 quotient++;
15899 else
15900 {
15901 quotient = 1;
15902 exponent++;
15903 tenths = 0;
15904 }
15905 }
15906
15907 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15908 if (tenths == -1 && quotient <= 99)
15909 if (quotient <= 9)
15910 length = 1;
15911 else
15912 length = 2;
15913 else
15914 length = 3;
15915 p = psuffix = buf + max (width, length);
15916
15917 /* Print EXPONENT. */
15918 if (exponent)
15919 *psuffix++ = power_letter[exponent];
15920 *psuffix = '\0';
15921
15922 /* Print TENTHS. */
15923 if (tenths >= 0)
15924 {
15925 *--p = '0' + tenths;
15926 *--p = '.';
15927 }
15928
15929 /* Print QUOTIENT. */
15930 do
15931 {
15932 int digit = quotient % 10;
15933 *--p = '0' + digit;
15934 }
15935 while ((quotient /= 10) != 0);
15936
15937 /* Print leading spaces. */
15938 while (buf < p)
15939 *--p = ' ';
15940 }
15941
15942 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15943 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15944 type of CODING_SYSTEM. Return updated pointer into BUF. */
15945
15946 static unsigned char invalid_eol_type[] = "(*invalid*)";
15947
15948 static char *
15949 decode_mode_spec_coding (coding_system, buf, eol_flag)
15950 Lisp_Object coding_system;
15951 register char *buf;
15952 int eol_flag;
15953 {
15954 Lisp_Object val;
15955 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15956 const unsigned char *eol_str;
15957 int eol_str_len;
15958 /* The EOL conversion we are using. */
15959 Lisp_Object eoltype;
15960
15961 val = Fget (coding_system, Qcoding_system);
15962 eoltype = Qnil;
15963
15964 if (!VECTORP (val)) /* Not yet decided. */
15965 {
15966 if (multibyte)
15967 *buf++ = '-';
15968 if (eol_flag)
15969 eoltype = eol_mnemonic_undecided;
15970 /* Don't mention EOL conversion if it isn't decided. */
15971 }
15972 else
15973 {
15974 Lisp_Object eolvalue;
15975
15976 eolvalue = Fget (coding_system, Qeol_type);
15977
15978 if (multibyte)
15979 *buf++ = XFASTINT (AREF (val, 1));
15980
15981 if (eol_flag)
15982 {
15983 /* The EOL conversion that is normal on this system. */
15984
15985 if (NILP (eolvalue)) /* Not yet decided. */
15986 eoltype = eol_mnemonic_undecided;
15987 else if (VECTORP (eolvalue)) /* Not yet decided. */
15988 eoltype = eol_mnemonic_undecided;
15989 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15990 eoltype = (XFASTINT (eolvalue) == 0
15991 ? eol_mnemonic_unix
15992 : (XFASTINT (eolvalue) == 1
15993 ? eol_mnemonic_dos : eol_mnemonic_mac));
15994 }
15995 }
15996
15997 if (eol_flag)
15998 {
15999 /* Mention the EOL conversion if it is not the usual one. */
16000 if (STRINGP (eoltype))
16001 {
16002 eol_str = SDATA (eoltype);
16003 eol_str_len = SBYTES (eoltype);
16004 }
16005 else if (INTEGERP (eoltype)
16006 && CHAR_VALID_P (XINT (eoltype), 0))
16007 {
16008 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16009 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16010 eol_str = tmp;
16011 }
16012 else
16013 {
16014 eol_str = invalid_eol_type;
16015 eol_str_len = sizeof (invalid_eol_type) - 1;
16016 }
16017 bcopy (eol_str, buf, eol_str_len);
16018 buf += eol_str_len;
16019 }
16020
16021 return buf;
16022 }
16023
16024 /* Return a string for the output of a mode line %-spec for window W,
16025 generated by character C. PRECISION >= 0 means don't return a
16026 string longer than that value. FIELD_WIDTH > 0 means pad the
16027 string returned with spaces to that value. Return 1 in *MULTIBYTE
16028 if the result is multibyte text. */
16029
16030 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16031
16032 static char *
16033 decode_mode_spec (w, c, field_width, precision, multibyte)
16034 struct window *w;
16035 register int c;
16036 int field_width, precision;
16037 int *multibyte;
16038 {
16039 Lisp_Object obj;
16040 struct frame *f = XFRAME (WINDOW_FRAME (w));
16041 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16042 struct buffer *b = XBUFFER (w->buffer);
16043
16044 obj = Qnil;
16045 *multibyte = 0;
16046
16047 switch (c)
16048 {
16049 case '*':
16050 if (!NILP (b->read_only))
16051 return "%";
16052 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16053 return "*";
16054 return "-";
16055
16056 case '+':
16057 /* This differs from %* only for a modified read-only buffer. */
16058 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16059 return "*";
16060 if (!NILP (b->read_only))
16061 return "%";
16062 return "-";
16063
16064 case '&':
16065 /* This differs from %* in ignoring read-only-ness. */
16066 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16067 return "*";
16068 return "-";
16069
16070 case '%':
16071 return "%";
16072
16073 case '[':
16074 {
16075 int i;
16076 char *p;
16077
16078 if (command_loop_level > 5)
16079 return "[[[... ";
16080 p = decode_mode_spec_buf;
16081 for (i = 0; i < command_loop_level; i++)
16082 *p++ = '[';
16083 *p = 0;
16084 return decode_mode_spec_buf;
16085 }
16086
16087 case ']':
16088 {
16089 int i;
16090 char *p;
16091
16092 if (command_loop_level > 5)
16093 return " ...]]]";
16094 p = decode_mode_spec_buf;
16095 for (i = 0; i < command_loop_level; i++)
16096 *p++ = ']';
16097 *p = 0;
16098 return decode_mode_spec_buf;
16099 }
16100
16101 case '-':
16102 {
16103 register int i;
16104
16105 /* Let lots_of_dashes be a string of infinite length. */
16106 if (!NILP (mode_line_string_list))
16107 return "--";
16108 if (field_width <= 0
16109 || field_width > sizeof (lots_of_dashes))
16110 {
16111 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16112 decode_mode_spec_buf[i] = '-';
16113 decode_mode_spec_buf[i] = '\0';
16114 return decode_mode_spec_buf;
16115 }
16116 else
16117 return lots_of_dashes;
16118 }
16119
16120 case 'b':
16121 obj = b->name;
16122 break;
16123
16124 case 'c':
16125 {
16126 int col = (int) current_column (); /* iftc */
16127 w->column_number_displayed = make_number (col);
16128 pint2str (decode_mode_spec_buf, field_width, col);
16129 return decode_mode_spec_buf;
16130 }
16131
16132 case 'F':
16133 /* %F displays the frame name. */
16134 if (!NILP (f->title))
16135 return (char *) SDATA (f->title);
16136 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16137 return (char *) SDATA (f->name);
16138 return "Emacs";
16139
16140 case 'f':
16141 obj = b->filename;
16142 break;
16143
16144 case 'i':
16145 {
16146 int size = ZV - BEGV;
16147 pint2str (decode_mode_spec_buf, field_width, size);
16148 return decode_mode_spec_buf;
16149 }
16150
16151 case 'I':
16152 {
16153 int size = ZV - BEGV;
16154 pint2hrstr (decode_mode_spec_buf, field_width, size);
16155 return decode_mode_spec_buf;
16156 }
16157
16158 case 'l':
16159 {
16160 int startpos = XMARKER (w->start)->charpos;
16161 int startpos_byte = marker_byte_position (w->start);
16162 int line, linepos, linepos_byte, topline;
16163 int nlines, junk;
16164 int height = WINDOW_TOTAL_LINES (w);
16165
16166 /* If we decided that this buffer isn't suitable for line numbers,
16167 don't forget that too fast. */
16168 if (EQ (w->base_line_pos, w->buffer))
16169 goto no_value;
16170 /* But do forget it, if the window shows a different buffer now. */
16171 else if (BUFFERP (w->base_line_pos))
16172 w->base_line_pos = Qnil;
16173
16174 /* If the buffer is very big, don't waste time. */
16175 if (INTEGERP (Vline_number_display_limit)
16176 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16177 {
16178 w->base_line_pos = Qnil;
16179 w->base_line_number = Qnil;
16180 goto no_value;
16181 }
16182
16183 if (!NILP (w->base_line_number)
16184 && !NILP (w->base_line_pos)
16185 && XFASTINT (w->base_line_pos) <= startpos)
16186 {
16187 line = XFASTINT (w->base_line_number);
16188 linepos = XFASTINT (w->base_line_pos);
16189 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16190 }
16191 else
16192 {
16193 line = 1;
16194 linepos = BUF_BEGV (b);
16195 linepos_byte = BUF_BEGV_BYTE (b);
16196 }
16197
16198 /* Count lines from base line to window start position. */
16199 nlines = display_count_lines (linepos, linepos_byte,
16200 startpos_byte,
16201 startpos, &junk);
16202
16203 topline = nlines + line;
16204
16205 /* Determine a new base line, if the old one is too close
16206 or too far away, or if we did not have one.
16207 "Too close" means it's plausible a scroll-down would
16208 go back past it. */
16209 if (startpos == BUF_BEGV (b))
16210 {
16211 w->base_line_number = make_number (topline);
16212 w->base_line_pos = make_number (BUF_BEGV (b));
16213 }
16214 else if (nlines < height + 25 || nlines > height * 3 + 50
16215 || linepos == BUF_BEGV (b))
16216 {
16217 int limit = BUF_BEGV (b);
16218 int limit_byte = BUF_BEGV_BYTE (b);
16219 int position;
16220 int distance = (height * 2 + 30) * line_number_display_limit_width;
16221
16222 if (startpos - distance > limit)
16223 {
16224 limit = startpos - distance;
16225 limit_byte = CHAR_TO_BYTE (limit);
16226 }
16227
16228 nlines = display_count_lines (startpos, startpos_byte,
16229 limit_byte,
16230 - (height * 2 + 30),
16231 &position);
16232 /* If we couldn't find the lines we wanted within
16233 line_number_display_limit_width chars per line,
16234 give up on line numbers for this window. */
16235 if (position == limit_byte && limit == startpos - distance)
16236 {
16237 w->base_line_pos = w->buffer;
16238 w->base_line_number = Qnil;
16239 goto no_value;
16240 }
16241
16242 w->base_line_number = make_number (topline - nlines);
16243 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16244 }
16245
16246 /* Now count lines from the start pos to point. */
16247 nlines = display_count_lines (startpos, startpos_byte,
16248 PT_BYTE, PT, &junk);
16249
16250 /* Record that we did display the line number. */
16251 line_number_displayed = 1;
16252
16253 /* Make the string to show. */
16254 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16255 return decode_mode_spec_buf;
16256 no_value:
16257 {
16258 char* p = decode_mode_spec_buf;
16259 int pad = field_width - 2;
16260 while (pad-- > 0)
16261 *p++ = ' ';
16262 *p++ = '?';
16263 *p++ = '?';
16264 *p = '\0';
16265 return decode_mode_spec_buf;
16266 }
16267 }
16268 break;
16269
16270 case 'm':
16271 obj = b->mode_name;
16272 break;
16273
16274 case 'n':
16275 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16276 return " Narrow";
16277 break;
16278
16279 case 'p':
16280 {
16281 int pos = marker_position (w->start);
16282 int total = BUF_ZV (b) - BUF_BEGV (b);
16283
16284 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16285 {
16286 if (pos <= BUF_BEGV (b))
16287 return "All";
16288 else
16289 return "Bottom";
16290 }
16291 else if (pos <= BUF_BEGV (b))
16292 return "Top";
16293 else
16294 {
16295 if (total > 1000000)
16296 /* Do it differently for a large value, to avoid overflow. */
16297 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16298 else
16299 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16300 /* We can't normally display a 3-digit number,
16301 so get us a 2-digit number that is close. */
16302 if (total == 100)
16303 total = 99;
16304 sprintf (decode_mode_spec_buf, "%2d%%", total);
16305 return decode_mode_spec_buf;
16306 }
16307 }
16308
16309 /* Display percentage of size above the bottom of the screen. */
16310 case 'P':
16311 {
16312 int toppos = marker_position (w->start);
16313 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16314 int total = BUF_ZV (b) - BUF_BEGV (b);
16315
16316 if (botpos >= BUF_ZV (b))
16317 {
16318 if (toppos <= BUF_BEGV (b))
16319 return "All";
16320 else
16321 return "Bottom";
16322 }
16323 else
16324 {
16325 if (total > 1000000)
16326 /* Do it differently for a large value, to avoid overflow. */
16327 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16328 else
16329 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16330 /* We can't normally display a 3-digit number,
16331 so get us a 2-digit number that is close. */
16332 if (total == 100)
16333 total = 99;
16334 if (toppos <= BUF_BEGV (b))
16335 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16336 else
16337 sprintf (decode_mode_spec_buf, "%2d%%", total);
16338 return decode_mode_spec_buf;
16339 }
16340 }
16341
16342 case 's':
16343 /* status of process */
16344 obj = Fget_buffer_process (w->buffer);
16345 if (NILP (obj))
16346 return "no process";
16347 #ifdef subprocesses
16348 obj = Fsymbol_name (Fprocess_status (obj));
16349 #endif
16350 break;
16351
16352 case 't': /* indicate TEXT or BINARY */
16353 #ifdef MODE_LINE_BINARY_TEXT
16354 return MODE_LINE_BINARY_TEXT (b);
16355 #else
16356 return "T";
16357 #endif
16358
16359 case 'z':
16360 /* coding-system (not including end-of-line format) */
16361 case 'Z':
16362 /* coding-system (including end-of-line type) */
16363 {
16364 int eol_flag = (c == 'Z');
16365 char *p = decode_mode_spec_buf;
16366
16367 if (! FRAME_WINDOW_P (f))
16368 {
16369 /* No need to mention EOL here--the terminal never needs
16370 to do EOL conversion. */
16371 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16372 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16373 }
16374 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16375 p, eol_flag);
16376
16377 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16378 #ifdef subprocesses
16379 obj = Fget_buffer_process (Fcurrent_buffer ());
16380 if (PROCESSP (obj))
16381 {
16382 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16383 p, eol_flag);
16384 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16385 p, eol_flag);
16386 }
16387 #endif /* subprocesses */
16388 #endif /* 0 */
16389 *p = 0;
16390 return decode_mode_spec_buf;
16391 }
16392 }
16393
16394 if (STRINGP (obj))
16395 {
16396 *multibyte = STRING_MULTIBYTE (obj);
16397 return (char *) SDATA (obj);
16398 }
16399 else
16400 return "";
16401 }
16402
16403
16404 /* Count up to COUNT lines starting from START / START_BYTE.
16405 But don't go beyond LIMIT_BYTE.
16406 Return the number of lines thus found (always nonnegative).
16407
16408 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16409
16410 static int
16411 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16412 int start, start_byte, limit_byte, count;
16413 int *byte_pos_ptr;
16414 {
16415 register unsigned char *cursor;
16416 unsigned char *base;
16417
16418 register int ceiling;
16419 register unsigned char *ceiling_addr;
16420 int orig_count = count;
16421
16422 /* If we are not in selective display mode,
16423 check only for newlines. */
16424 int selective_display = (!NILP (current_buffer->selective_display)
16425 && !INTEGERP (current_buffer->selective_display));
16426
16427 if (count > 0)
16428 {
16429 while (start_byte < limit_byte)
16430 {
16431 ceiling = BUFFER_CEILING_OF (start_byte);
16432 ceiling = min (limit_byte - 1, ceiling);
16433 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16434 base = (cursor = BYTE_POS_ADDR (start_byte));
16435 while (1)
16436 {
16437 if (selective_display)
16438 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16439 ;
16440 else
16441 while (*cursor != '\n' && ++cursor != ceiling_addr)
16442 ;
16443
16444 if (cursor != ceiling_addr)
16445 {
16446 if (--count == 0)
16447 {
16448 start_byte += cursor - base + 1;
16449 *byte_pos_ptr = start_byte;
16450 return orig_count;
16451 }
16452 else
16453 if (++cursor == ceiling_addr)
16454 break;
16455 }
16456 else
16457 break;
16458 }
16459 start_byte += cursor - base;
16460 }
16461 }
16462 else
16463 {
16464 while (start_byte > limit_byte)
16465 {
16466 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16467 ceiling = max (limit_byte, ceiling);
16468 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16469 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16470 while (1)
16471 {
16472 if (selective_display)
16473 while (--cursor != ceiling_addr
16474 && *cursor != '\n' && *cursor != 015)
16475 ;
16476 else
16477 while (--cursor != ceiling_addr && *cursor != '\n')
16478 ;
16479
16480 if (cursor != ceiling_addr)
16481 {
16482 if (++count == 0)
16483 {
16484 start_byte += cursor - base + 1;
16485 *byte_pos_ptr = start_byte;
16486 /* When scanning backwards, we should
16487 not count the newline posterior to which we stop. */
16488 return - orig_count - 1;
16489 }
16490 }
16491 else
16492 break;
16493 }
16494 /* Here we add 1 to compensate for the last decrement
16495 of CURSOR, which took it past the valid range. */
16496 start_byte += cursor - base + 1;
16497 }
16498 }
16499
16500 *byte_pos_ptr = limit_byte;
16501
16502 if (count < 0)
16503 return - orig_count + count;
16504 return orig_count - count;
16505
16506 }
16507
16508
16509 \f
16510 /***********************************************************************
16511 Displaying strings
16512 ***********************************************************************/
16513
16514 /* Display a NUL-terminated string, starting with index START.
16515
16516 If STRING is non-null, display that C string. Otherwise, the Lisp
16517 string LISP_STRING is displayed.
16518
16519 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16520 FACE_STRING. Display STRING or LISP_STRING with the face at
16521 FACE_STRING_POS in FACE_STRING:
16522
16523 Display the string in the environment given by IT, but use the
16524 standard display table, temporarily.
16525
16526 FIELD_WIDTH is the minimum number of output glyphs to produce.
16527 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16528 with spaces. If STRING has more characters, more than FIELD_WIDTH
16529 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16530
16531 PRECISION is the maximum number of characters to output from
16532 STRING. PRECISION < 0 means don't truncate the string.
16533
16534 This is roughly equivalent to printf format specifiers:
16535
16536 FIELD_WIDTH PRECISION PRINTF
16537 ----------------------------------------
16538 -1 -1 %s
16539 -1 10 %.10s
16540 10 -1 %10s
16541 20 10 %20.10s
16542
16543 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16544 display them, and < 0 means obey the current buffer's value of
16545 enable_multibyte_characters.
16546
16547 Value is the number of glyphs produced. */
16548
16549 static int
16550 display_string (string, lisp_string, face_string, face_string_pos,
16551 start, it, field_width, precision, max_x, multibyte)
16552 unsigned char *string;
16553 Lisp_Object lisp_string;
16554 Lisp_Object face_string;
16555 int face_string_pos;
16556 int start;
16557 struct it *it;
16558 int field_width, precision, max_x;
16559 int multibyte;
16560 {
16561 int hpos_at_start = it->hpos;
16562 int saved_face_id = it->face_id;
16563 struct glyph_row *row = it->glyph_row;
16564
16565 /* Initialize the iterator IT for iteration over STRING beginning
16566 with index START. */
16567 reseat_to_string (it, string, lisp_string, start,
16568 precision, field_width, multibyte);
16569
16570 /* If displaying STRING, set up the face of the iterator
16571 from LISP_STRING, if that's given. */
16572 if (STRINGP (face_string))
16573 {
16574 int endptr;
16575 struct face *face;
16576
16577 it->face_id
16578 = face_at_string_position (it->w, face_string, face_string_pos,
16579 0, it->region_beg_charpos,
16580 it->region_end_charpos,
16581 &endptr, it->base_face_id, 0);
16582 face = FACE_FROM_ID (it->f, it->face_id);
16583 it->face_box_p = face->box != FACE_NO_BOX;
16584 }
16585
16586 /* Set max_x to the maximum allowed X position. Don't let it go
16587 beyond the right edge of the window. */
16588 if (max_x <= 0)
16589 max_x = it->last_visible_x;
16590 else
16591 max_x = min (max_x, it->last_visible_x);
16592
16593 /* Skip over display elements that are not visible. because IT->w is
16594 hscrolled. */
16595 if (it->current_x < it->first_visible_x)
16596 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16597 MOVE_TO_POS | MOVE_TO_X);
16598
16599 row->ascent = it->max_ascent;
16600 row->height = it->max_ascent + it->max_descent;
16601 row->phys_ascent = it->max_phys_ascent;
16602 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16603
16604 /* This condition is for the case that we are called with current_x
16605 past last_visible_x. */
16606 while (it->current_x < max_x)
16607 {
16608 int x_before, x, n_glyphs_before, i, nglyphs;
16609
16610 /* Get the next display element. */
16611 if (!get_next_display_element (it))
16612 break;
16613
16614 /* Produce glyphs. */
16615 x_before = it->current_x;
16616 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16617 PRODUCE_GLYPHS (it);
16618
16619 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16620 i = 0;
16621 x = x_before;
16622 while (i < nglyphs)
16623 {
16624 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16625
16626 if (!it->truncate_lines_p
16627 && x + glyph->pixel_width > max_x)
16628 {
16629 /* End of continued line or max_x reached. */
16630 if (CHAR_GLYPH_PADDING_P (*glyph))
16631 {
16632 /* A wide character is unbreakable. */
16633 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16634 it->current_x = x_before;
16635 }
16636 else
16637 {
16638 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16639 it->current_x = x;
16640 }
16641 break;
16642 }
16643 else if (x + glyph->pixel_width > it->first_visible_x)
16644 {
16645 /* Glyph is at least partially visible. */
16646 ++it->hpos;
16647 if (x < it->first_visible_x)
16648 it->glyph_row->x = x - it->first_visible_x;
16649 }
16650 else
16651 {
16652 /* Glyph is off the left margin of the display area.
16653 Should not happen. */
16654 abort ();
16655 }
16656
16657 row->ascent = max (row->ascent, it->max_ascent);
16658 row->height = max (row->height, it->max_ascent + it->max_descent);
16659 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16660 row->phys_height = max (row->phys_height,
16661 it->max_phys_ascent + it->max_phys_descent);
16662 x += glyph->pixel_width;
16663 ++i;
16664 }
16665
16666 /* Stop if max_x reached. */
16667 if (i < nglyphs)
16668 break;
16669
16670 /* Stop at line ends. */
16671 if (ITERATOR_AT_END_OF_LINE_P (it))
16672 {
16673 it->continuation_lines_width = 0;
16674 break;
16675 }
16676
16677 set_iterator_to_next (it, 1);
16678
16679 /* Stop if truncating at the right edge. */
16680 if (it->truncate_lines_p
16681 && it->current_x >= it->last_visible_x)
16682 {
16683 /* Add truncation mark, but don't do it if the line is
16684 truncated at a padding space. */
16685 if (IT_CHARPOS (*it) < it->string_nchars)
16686 {
16687 if (!FRAME_WINDOW_P (it->f))
16688 {
16689 int i, n;
16690
16691 if (it->current_x > it->last_visible_x)
16692 {
16693 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16694 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16695 break;
16696 for (n = row->used[TEXT_AREA]; i < n; ++i)
16697 {
16698 row->used[TEXT_AREA] = i;
16699 produce_special_glyphs (it, IT_TRUNCATION);
16700 }
16701 }
16702 produce_special_glyphs (it, IT_TRUNCATION);
16703 }
16704 it->glyph_row->truncated_on_right_p = 1;
16705 }
16706 break;
16707 }
16708 }
16709
16710 /* Maybe insert a truncation at the left. */
16711 if (it->first_visible_x
16712 && IT_CHARPOS (*it) > 0)
16713 {
16714 if (!FRAME_WINDOW_P (it->f))
16715 insert_left_trunc_glyphs (it);
16716 it->glyph_row->truncated_on_left_p = 1;
16717 }
16718
16719 it->face_id = saved_face_id;
16720
16721 /* Value is number of columns displayed. */
16722 return it->hpos - hpos_at_start;
16723 }
16724
16725
16726 \f
16727 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16728 appears as an element of LIST or as the car of an element of LIST.
16729 If PROPVAL is a list, compare each element against LIST in that
16730 way, and return 1/2 if any element of PROPVAL is found in LIST.
16731 Otherwise return 0. This function cannot quit.
16732 The return value is 2 if the text is invisible but with an ellipsis
16733 and 1 if it's invisible and without an ellipsis. */
16734
16735 int
16736 invisible_p (propval, list)
16737 register Lisp_Object propval;
16738 Lisp_Object list;
16739 {
16740 register Lisp_Object tail, proptail;
16741
16742 for (tail = list; CONSP (tail); tail = XCDR (tail))
16743 {
16744 register Lisp_Object tem;
16745 tem = XCAR (tail);
16746 if (EQ (propval, tem))
16747 return 1;
16748 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16749 return NILP (XCDR (tem)) ? 1 : 2;
16750 }
16751
16752 if (CONSP (propval))
16753 {
16754 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16755 {
16756 Lisp_Object propelt;
16757 propelt = XCAR (proptail);
16758 for (tail = list; CONSP (tail); tail = XCDR (tail))
16759 {
16760 register Lisp_Object tem;
16761 tem = XCAR (tail);
16762 if (EQ (propelt, tem))
16763 return 1;
16764 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16765 return NILP (XCDR (tem)) ? 1 : 2;
16766 }
16767 }
16768 }
16769
16770 return 0;
16771 }
16772
16773 /* Calculate a width or height in pixels from a specification using
16774 the following elements:
16775
16776 SPEC ::=
16777 NUM - a (fractional) multiple of the default font width/height
16778 (NUM) - specifies exactly NUM pixels
16779 UNIT - a fixed number of pixels, see below.
16780 ELEMENT - size of a display element in pixels, see below.
16781 (NUM . SPEC) - equals NUM * SPEC
16782 (+ SPEC SPEC ...) - add pixel values
16783 (- SPEC SPEC ...) - subtract pixel values
16784 (- SPEC) - negate pixel value
16785
16786 NUM ::=
16787 INT or FLOAT - a number constant
16788 SYMBOL - use symbol's (buffer local) variable binding.
16789
16790 UNIT ::=
16791 in - pixels per inch *)
16792 mm - pixels per 1/1000 meter *)
16793 cm - pixels per 1/100 meter *)
16794 width - width of current font in pixels.
16795 height - height of current font in pixels.
16796
16797 *) using the ratio(s) defined in display-pixels-per-inch.
16798
16799 ELEMENT ::=
16800
16801 left-fringe - left fringe width in pixels
16802 right-fringe - right fringe width in pixels
16803
16804 left-margin - left margin width in pixels
16805 right-margin - right margin width in pixels
16806
16807 scroll-bar - scroll-bar area width in pixels
16808
16809 Examples:
16810
16811 Pixels corresponding to 5 inches:
16812 (5 . in)
16813
16814 Total width of non-text areas on left side of window (if scroll-bar is on left):
16815 '(space :width (+ left-fringe left-margin scroll-bar))
16816
16817 Align to first text column (in header line):
16818 '(space :align-to 0)
16819
16820 Align to middle of text area minus half the width of variable `my-image'
16821 containing a loaded image:
16822 '(space :align-to (0.5 . (- text my-image)))
16823
16824 Width of left margin minus width of 1 character in the default font:
16825 '(space :width (- left-margin 1))
16826
16827 Width of left margin minus width of 2 characters in the current font:
16828 '(space :width (- left-margin (2 . width)))
16829
16830 Center 1 character over left-margin (in header line):
16831 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16832
16833 Different ways to express width of left fringe plus left margin minus one pixel:
16834 '(space :width (- (+ left-fringe left-margin) (1)))
16835 '(space :width (+ left-fringe left-margin (- (1))))
16836 '(space :width (+ left-fringe left-margin (-1)))
16837
16838 */
16839
16840 #define NUMVAL(X) \
16841 ((INTEGERP (X) || FLOATP (X)) \
16842 ? XFLOATINT (X) \
16843 : - 1)
16844
16845 int
16846 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
16847 double *res;
16848 struct it *it;
16849 Lisp_Object prop;
16850 void *font;
16851 int width_p, *align_to;
16852 {
16853 double pixels;
16854
16855 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
16856 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
16857
16858 if (NILP (prop))
16859 return OK_PIXELS (0);
16860
16861 if (SYMBOLP (prop))
16862 {
16863 if (SCHARS (SYMBOL_NAME (prop)) == 2)
16864 {
16865 char *unit = SDATA (SYMBOL_NAME (prop));
16866
16867 if (unit[0] == 'i' && unit[1] == 'n')
16868 pixels = 1.0;
16869 else if (unit[0] == 'm' && unit[1] == 'm')
16870 pixels = 25.4;
16871 else if (unit[0] == 'c' && unit[1] == 'm')
16872 pixels = 2.54;
16873 else
16874 pixels = 0;
16875 if (pixels > 0)
16876 {
16877 double ppi;
16878 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
16879 || (CONSP (Vdisplay_pixels_per_inch)
16880 && (ppi = (width_p
16881 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
16882 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
16883 ppi > 0)))
16884 return OK_PIXELS (ppi / pixels);
16885
16886 return 0;
16887 }
16888 }
16889
16890 #ifdef HAVE_WINDOW_SYSTEM
16891 if (EQ (prop, Qheight))
16892 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
16893 if (EQ (prop, Qwidth))
16894 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
16895 #else
16896 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
16897 return OK_PIXELS (1);
16898 #endif
16899
16900 if (EQ (prop, Qtext))
16901 return OK_PIXELS (width_p
16902 ? window_box_width (it->w, TEXT_AREA)
16903 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
16904
16905 if (align_to && *align_to < 0)
16906 {
16907 *res = 0;
16908 if (EQ (prop, Qleft))
16909 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
16910 if (EQ (prop, Qright))
16911 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
16912 if (EQ (prop, Qcenter))
16913 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
16914 + window_box_width (it->w, TEXT_AREA) / 2);
16915 if (EQ (prop, Qleft_fringe))
16916 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
16917 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
16918 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
16919 if (EQ (prop, Qright_fringe))
16920 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
16921 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
16922 : window_box_right_offset (it->w, TEXT_AREA));
16923 if (EQ (prop, Qleft_margin))
16924 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
16925 if (EQ (prop, Qright_margin))
16926 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
16927 if (EQ (prop, Qscroll_bar))
16928 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
16929 ? 0
16930 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
16931 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
16932 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
16933 : 0)));
16934 }
16935 else
16936 {
16937 if (EQ (prop, Qleft_fringe))
16938 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
16939 if (EQ (prop, Qright_fringe))
16940 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
16941 if (EQ (prop, Qleft_margin))
16942 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
16943 if (EQ (prop, Qright_margin))
16944 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
16945 if (EQ (prop, Qscroll_bar))
16946 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
16947 }
16948
16949 prop = Fbuffer_local_value (prop, it->w->buffer);
16950 }
16951
16952 if (INTEGERP (prop) || FLOATP (prop))
16953 {
16954 int base_unit = (width_p
16955 ? FRAME_COLUMN_WIDTH (it->f)
16956 : FRAME_LINE_HEIGHT (it->f));
16957 return OK_PIXELS (XFLOATINT (prop) * base_unit);
16958 }
16959
16960 if (CONSP (prop))
16961 {
16962 Lisp_Object car = XCAR (prop);
16963 Lisp_Object cdr = XCDR (prop);
16964
16965 if (SYMBOLP (car))
16966 {
16967 #ifdef HAVE_WINDOW_SYSTEM
16968 if (valid_image_p (prop))
16969 {
16970 int id = lookup_image (it->f, prop);
16971 struct image *img = IMAGE_FROM_ID (it->f, id);
16972
16973 return OK_PIXELS (width_p ? img->width : img->height);
16974 }
16975 #endif
16976 if (EQ (car, Qplus) || EQ (car, Qminus))
16977 {
16978 int first = 1;
16979 double px;
16980
16981 pixels = 0;
16982 while (CONSP (cdr))
16983 {
16984 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
16985 font, width_p, align_to))
16986 return 0;
16987 if (first)
16988 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
16989 else
16990 pixels += px;
16991 cdr = XCDR (cdr);
16992 }
16993 if (EQ (car, Qminus))
16994 pixels = -pixels;
16995 return OK_PIXELS (pixels);
16996 }
16997
16998 car = Fbuffer_local_value (car, it->w->buffer);
16999 }
17000
17001 if (INTEGERP (car) || FLOATP (car))
17002 {
17003 double fact;
17004 pixels = XFLOATINT (car);
17005 if (NILP (cdr))
17006 return OK_PIXELS (pixels);
17007 if (calc_pixel_width_or_height (&fact, it, cdr,
17008 font, width_p, align_to))
17009 return OK_PIXELS (pixels * fact);
17010 return 0;
17011 }
17012
17013 return 0;
17014 }
17015
17016 return 0;
17017 }
17018
17019 \f
17020 /***********************************************************************
17021 Glyph Display
17022 ***********************************************************************/
17023
17024 #ifdef HAVE_WINDOW_SYSTEM
17025
17026 #if GLYPH_DEBUG
17027
17028 void
17029 dump_glyph_string (s)
17030 struct glyph_string *s;
17031 {
17032 fprintf (stderr, "glyph string\n");
17033 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17034 s->x, s->y, s->width, s->height);
17035 fprintf (stderr, " ybase = %d\n", s->ybase);
17036 fprintf (stderr, " hl = %d\n", s->hl);
17037 fprintf (stderr, " left overhang = %d, right = %d\n",
17038 s->left_overhang, s->right_overhang);
17039 fprintf (stderr, " nchars = %d\n", s->nchars);
17040 fprintf (stderr, " extends to end of line = %d\n",
17041 s->extends_to_end_of_line_p);
17042 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17043 fprintf (stderr, " bg width = %d\n", s->background_width);
17044 }
17045
17046 #endif /* GLYPH_DEBUG */
17047
17048 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17049 of XChar2b structures for S; it can't be allocated in
17050 init_glyph_string because it must be allocated via `alloca'. W
17051 is the window on which S is drawn. ROW and AREA are the glyph row
17052 and area within the row from which S is constructed. START is the
17053 index of the first glyph structure covered by S. HL is a
17054 face-override for drawing S. */
17055
17056 #ifdef HAVE_NTGUI
17057 #define OPTIONAL_HDC(hdc) hdc,
17058 #define DECLARE_HDC(hdc) HDC hdc;
17059 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17060 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17061 #endif
17062
17063 #ifndef OPTIONAL_HDC
17064 #define OPTIONAL_HDC(hdc)
17065 #define DECLARE_HDC(hdc)
17066 #define ALLOCATE_HDC(hdc, f)
17067 #define RELEASE_HDC(hdc, f)
17068 #endif
17069
17070 static void
17071 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17072 struct glyph_string *s;
17073 DECLARE_HDC (hdc)
17074 XChar2b *char2b;
17075 struct window *w;
17076 struct glyph_row *row;
17077 enum glyph_row_area area;
17078 int start;
17079 enum draw_glyphs_face hl;
17080 {
17081 bzero (s, sizeof *s);
17082 s->w = w;
17083 s->f = XFRAME (w->frame);
17084 #ifdef HAVE_NTGUI
17085 s->hdc = hdc;
17086 #endif
17087 s->display = FRAME_X_DISPLAY (s->f);
17088 s->window = FRAME_X_WINDOW (s->f);
17089 s->char2b = char2b;
17090 s->hl = hl;
17091 s->row = row;
17092 s->area = area;
17093 s->first_glyph = row->glyphs[area] + start;
17094 s->height = row->height;
17095 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17096
17097 /* Display the internal border below the tool-bar window. */
17098 if (s->w == XWINDOW (s->f->tool_bar_window))
17099 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17100
17101 s->ybase = s->y + row->ascent;
17102 }
17103
17104
17105 /* Append the list of glyph strings with head H and tail T to the list
17106 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17107
17108 static INLINE void
17109 append_glyph_string_lists (head, tail, h, t)
17110 struct glyph_string **head, **tail;
17111 struct glyph_string *h, *t;
17112 {
17113 if (h)
17114 {
17115 if (*head)
17116 (*tail)->next = h;
17117 else
17118 *head = h;
17119 h->prev = *tail;
17120 *tail = t;
17121 }
17122 }
17123
17124
17125 /* Prepend the list of glyph strings with head H and tail T to the
17126 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17127 result. */
17128
17129 static INLINE void
17130 prepend_glyph_string_lists (head, tail, h, t)
17131 struct glyph_string **head, **tail;
17132 struct glyph_string *h, *t;
17133 {
17134 if (h)
17135 {
17136 if (*head)
17137 (*head)->prev = t;
17138 else
17139 *tail = t;
17140 t->next = *head;
17141 *head = h;
17142 }
17143 }
17144
17145
17146 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17147 Set *HEAD and *TAIL to the resulting list. */
17148
17149 static INLINE void
17150 append_glyph_string (head, tail, s)
17151 struct glyph_string **head, **tail;
17152 struct glyph_string *s;
17153 {
17154 s->next = s->prev = NULL;
17155 append_glyph_string_lists (head, tail, s, s);
17156 }
17157
17158
17159 /* Get face and two-byte form of character glyph GLYPH on frame F.
17160 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17161 a pointer to a realized face that is ready for display. */
17162
17163 static INLINE struct face *
17164 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17165 struct frame *f;
17166 struct glyph *glyph;
17167 XChar2b *char2b;
17168 int *two_byte_p;
17169 {
17170 struct face *face;
17171
17172 xassert (glyph->type == CHAR_GLYPH);
17173 face = FACE_FROM_ID (f, glyph->face_id);
17174
17175 if (two_byte_p)
17176 *two_byte_p = 0;
17177
17178 if (!glyph->multibyte_p)
17179 {
17180 /* Unibyte case. We don't have to encode, but we have to make
17181 sure to use a face suitable for unibyte. */
17182 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17183 }
17184 else if (glyph->u.ch < 128
17185 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17186 {
17187 /* Case of ASCII in a face known to fit ASCII. */
17188 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17189 }
17190 else
17191 {
17192 int c1, c2, charset;
17193
17194 /* Split characters into bytes. If c2 is -1 afterwards, C is
17195 really a one-byte character so that byte1 is zero. */
17196 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17197 if (c2 > 0)
17198 STORE_XCHAR2B (char2b, c1, c2);
17199 else
17200 STORE_XCHAR2B (char2b, 0, c1);
17201
17202 /* Maybe encode the character in *CHAR2B. */
17203 if (charset != CHARSET_ASCII)
17204 {
17205 struct font_info *font_info
17206 = FONT_INFO_FROM_ID (f, face->font_info_id);
17207 if (font_info)
17208 glyph->font_type
17209 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17210 }
17211 }
17212
17213 /* Make sure X resources of the face are allocated. */
17214 xassert (face != NULL);
17215 PREPARE_FACE_FOR_DISPLAY (f, face);
17216 return face;
17217 }
17218
17219
17220 /* Fill glyph string S with composition components specified by S->cmp.
17221
17222 FACES is an array of faces for all components of this composition.
17223 S->gidx is the index of the first component for S.
17224 OVERLAPS_P non-zero means S should draw the foreground only, and
17225 use its physical height for clipping.
17226
17227 Value is the index of a component not in S. */
17228
17229 static int
17230 fill_composite_glyph_string (s, faces, overlaps_p)
17231 struct glyph_string *s;
17232 struct face **faces;
17233 int overlaps_p;
17234 {
17235 int i;
17236
17237 xassert (s);
17238
17239 s->for_overlaps_p = overlaps_p;
17240
17241 s->face = faces[s->gidx];
17242 s->font = s->face->font;
17243 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17244
17245 /* For all glyphs of this composition, starting at the offset
17246 S->gidx, until we reach the end of the definition or encounter a
17247 glyph that requires the different face, add it to S. */
17248 ++s->nchars;
17249 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17250 ++s->nchars;
17251
17252 /* All glyph strings for the same composition has the same width,
17253 i.e. the width set for the first component of the composition. */
17254
17255 s->width = s->first_glyph->pixel_width;
17256
17257 /* If the specified font could not be loaded, use the frame's
17258 default font, but record the fact that we couldn't load it in
17259 the glyph string so that we can draw rectangles for the
17260 characters of the glyph string. */
17261 if (s->font == NULL)
17262 {
17263 s->font_not_found_p = 1;
17264 s->font = FRAME_FONT (s->f);
17265 }
17266
17267 /* Adjust base line for subscript/superscript text. */
17268 s->ybase += s->first_glyph->voffset;
17269
17270 xassert (s->face && s->face->gc);
17271
17272 /* This glyph string must always be drawn with 16-bit functions. */
17273 s->two_byte_p = 1;
17274
17275 return s->gidx + s->nchars;
17276 }
17277
17278
17279 /* Fill glyph string S from a sequence of character glyphs.
17280
17281 FACE_ID is the face id of the string. START is the index of the
17282 first glyph to consider, END is the index of the last + 1.
17283 OVERLAPS_P non-zero means S should draw the foreground only, and
17284 use its physical height for clipping.
17285
17286 Value is the index of the first glyph not in S. */
17287
17288 static int
17289 fill_glyph_string (s, face_id, start, end, overlaps_p)
17290 struct glyph_string *s;
17291 int face_id;
17292 int start, end, overlaps_p;
17293 {
17294 struct glyph *glyph, *last;
17295 int voffset;
17296 int glyph_not_available_p;
17297
17298 xassert (s->f == XFRAME (s->w->frame));
17299 xassert (s->nchars == 0);
17300 xassert (start >= 0 && end > start);
17301
17302 s->for_overlaps_p = overlaps_p,
17303 glyph = s->row->glyphs[s->area] + start;
17304 last = s->row->glyphs[s->area] + end;
17305 voffset = glyph->voffset;
17306
17307 glyph_not_available_p = glyph->glyph_not_available_p;
17308
17309 while (glyph < last
17310 && glyph->type == CHAR_GLYPH
17311 && glyph->voffset == voffset
17312 /* Same face id implies same font, nowadays. */
17313 && glyph->face_id == face_id
17314 && glyph->glyph_not_available_p == glyph_not_available_p)
17315 {
17316 int two_byte_p;
17317
17318 s->face = get_glyph_face_and_encoding (s->f, glyph,
17319 s->char2b + s->nchars,
17320 &two_byte_p);
17321 s->two_byte_p = two_byte_p;
17322 ++s->nchars;
17323 xassert (s->nchars <= end - start);
17324 s->width += glyph->pixel_width;
17325 ++glyph;
17326 }
17327
17328 s->font = s->face->font;
17329 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17330
17331 /* If the specified font could not be loaded, use the frame's font,
17332 but record the fact that we couldn't load it in
17333 S->font_not_found_p so that we can draw rectangles for the
17334 characters of the glyph string. */
17335 if (s->font == NULL || glyph_not_available_p)
17336 {
17337 s->font_not_found_p = 1;
17338 s->font = FRAME_FONT (s->f);
17339 }
17340
17341 /* Adjust base line for subscript/superscript text. */
17342 s->ybase += voffset;
17343
17344 xassert (s->face && s->face->gc);
17345 return glyph - s->row->glyphs[s->area];
17346 }
17347
17348
17349 /* Fill glyph string S from image glyph S->first_glyph. */
17350
17351 static void
17352 fill_image_glyph_string (s)
17353 struct glyph_string *s;
17354 {
17355 xassert (s->first_glyph->type == IMAGE_GLYPH);
17356 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17357 xassert (s->img);
17358 s->slice = s->first_glyph->slice;
17359 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17360 s->font = s->face->font;
17361 s->width = s->first_glyph->pixel_width;
17362
17363 /* Adjust base line for subscript/superscript text. */
17364 s->ybase += s->first_glyph->voffset;
17365 }
17366
17367
17368 /* Fill glyph string S from a sequence of stretch glyphs.
17369
17370 ROW is the glyph row in which the glyphs are found, AREA is the
17371 area within the row. START is the index of the first glyph to
17372 consider, END is the index of the last + 1.
17373
17374 Value is the index of the first glyph not in S. */
17375
17376 static int
17377 fill_stretch_glyph_string (s, row, area, start, end)
17378 struct glyph_string *s;
17379 struct glyph_row *row;
17380 enum glyph_row_area area;
17381 int start, end;
17382 {
17383 struct glyph *glyph, *last;
17384 int voffset, face_id;
17385
17386 xassert (s->first_glyph->type == STRETCH_GLYPH);
17387
17388 glyph = s->row->glyphs[s->area] + start;
17389 last = s->row->glyphs[s->area] + end;
17390 face_id = glyph->face_id;
17391 s->face = FACE_FROM_ID (s->f, face_id);
17392 s->font = s->face->font;
17393 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17394 s->width = glyph->pixel_width;
17395 voffset = glyph->voffset;
17396
17397 for (++glyph;
17398 (glyph < last
17399 && glyph->type == STRETCH_GLYPH
17400 && glyph->voffset == voffset
17401 && glyph->face_id == face_id);
17402 ++glyph)
17403 s->width += glyph->pixel_width;
17404
17405 /* Adjust base line for subscript/superscript text. */
17406 s->ybase += voffset;
17407
17408 /* The case that face->gc == 0 is handled when drawing the glyph
17409 string by calling PREPARE_FACE_FOR_DISPLAY. */
17410 xassert (s->face);
17411 return glyph - s->row->glyphs[s->area];
17412 }
17413
17414
17415 /* EXPORT for RIF:
17416 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17417 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17418 assumed to be zero. */
17419
17420 void
17421 x_get_glyph_overhangs (glyph, f, left, right)
17422 struct glyph *glyph;
17423 struct frame *f;
17424 int *left, *right;
17425 {
17426 *left = *right = 0;
17427
17428 if (glyph->type == CHAR_GLYPH)
17429 {
17430 XFontStruct *font;
17431 struct face *face;
17432 struct font_info *font_info;
17433 XChar2b char2b;
17434 XCharStruct *pcm;
17435
17436 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17437 font = face->font;
17438 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17439 if (font /* ++KFS: Should this be font_info ? */
17440 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17441 {
17442 if (pcm->rbearing > pcm->width)
17443 *right = pcm->rbearing - pcm->width;
17444 if (pcm->lbearing < 0)
17445 *left = -pcm->lbearing;
17446 }
17447 }
17448 }
17449
17450
17451 /* Return the index of the first glyph preceding glyph string S that
17452 is overwritten by S because of S's left overhang. Value is -1
17453 if no glyphs are overwritten. */
17454
17455 static int
17456 left_overwritten (s)
17457 struct glyph_string *s;
17458 {
17459 int k;
17460
17461 if (s->left_overhang)
17462 {
17463 int x = 0, i;
17464 struct glyph *glyphs = s->row->glyphs[s->area];
17465 int first = s->first_glyph - glyphs;
17466
17467 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17468 x -= glyphs[i].pixel_width;
17469
17470 k = i + 1;
17471 }
17472 else
17473 k = -1;
17474
17475 return k;
17476 }
17477
17478
17479 /* Return the index of the first glyph preceding glyph string S that
17480 is overwriting S because of its right overhang. Value is -1 if no
17481 glyph in front of S overwrites S. */
17482
17483 static int
17484 left_overwriting (s)
17485 struct glyph_string *s;
17486 {
17487 int i, k, x;
17488 struct glyph *glyphs = s->row->glyphs[s->area];
17489 int first = s->first_glyph - glyphs;
17490
17491 k = -1;
17492 x = 0;
17493 for (i = first - 1; i >= 0; --i)
17494 {
17495 int left, right;
17496 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17497 if (x + right > 0)
17498 k = i;
17499 x -= glyphs[i].pixel_width;
17500 }
17501
17502 return k;
17503 }
17504
17505
17506 /* Return the index of the last glyph following glyph string S that is
17507 not overwritten by S because of S's right overhang. Value is -1 if
17508 no such glyph is found. */
17509
17510 static int
17511 right_overwritten (s)
17512 struct glyph_string *s;
17513 {
17514 int k = -1;
17515
17516 if (s->right_overhang)
17517 {
17518 int x = 0, i;
17519 struct glyph *glyphs = s->row->glyphs[s->area];
17520 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17521 int end = s->row->used[s->area];
17522
17523 for (i = first; i < end && s->right_overhang > x; ++i)
17524 x += glyphs[i].pixel_width;
17525
17526 k = i;
17527 }
17528
17529 return k;
17530 }
17531
17532
17533 /* Return the index of the last glyph following glyph string S that
17534 overwrites S because of its left overhang. Value is negative
17535 if no such glyph is found. */
17536
17537 static int
17538 right_overwriting (s)
17539 struct glyph_string *s;
17540 {
17541 int i, k, x;
17542 int end = s->row->used[s->area];
17543 struct glyph *glyphs = s->row->glyphs[s->area];
17544 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17545
17546 k = -1;
17547 x = 0;
17548 for (i = first; i < end; ++i)
17549 {
17550 int left, right;
17551 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17552 if (x - left < 0)
17553 k = i;
17554 x += glyphs[i].pixel_width;
17555 }
17556
17557 return k;
17558 }
17559
17560
17561 /* Get face and two-byte form of character C in face FACE_ID on frame
17562 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17563 means we want to display multibyte text. DISPLAY_P non-zero means
17564 make sure that X resources for the face returned are allocated.
17565 Value is a pointer to a realized face that is ready for display if
17566 DISPLAY_P is non-zero. */
17567
17568 static INLINE struct face *
17569 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17570 struct frame *f;
17571 int c, face_id;
17572 XChar2b *char2b;
17573 int multibyte_p, display_p;
17574 {
17575 struct face *face = FACE_FROM_ID (f, face_id);
17576
17577 if (!multibyte_p)
17578 {
17579 /* Unibyte case. We don't have to encode, but we have to make
17580 sure to use a face suitable for unibyte. */
17581 STORE_XCHAR2B (char2b, 0, c);
17582 face_id = FACE_FOR_CHAR (f, face, c);
17583 face = FACE_FROM_ID (f, face_id);
17584 }
17585 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17586 {
17587 /* Case of ASCII in a face known to fit ASCII. */
17588 STORE_XCHAR2B (char2b, 0, c);
17589 }
17590 else
17591 {
17592 int c1, c2, charset;
17593
17594 /* Split characters into bytes. If c2 is -1 afterwards, C is
17595 really a one-byte character so that byte1 is zero. */
17596 SPLIT_CHAR (c, charset, c1, c2);
17597 if (c2 > 0)
17598 STORE_XCHAR2B (char2b, c1, c2);
17599 else
17600 STORE_XCHAR2B (char2b, 0, c1);
17601
17602 /* Maybe encode the character in *CHAR2B. */
17603 if (face->font != NULL)
17604 {
17605 struct font_info *font_info
17606 = FONT_INFO_FROM_ID (f, face->font_info_id);
17607 if (font_info)
17608 rif->encode_char (c, char2b, font_info, 0);
17609 }
17610 }
17611
17612 /* Make sure X resources of the face are allocated. */
17613 #ifdef HAVE_X_WINDOWS
17614 if (display_p)
17615 #endif
17616 {
17617 xassert (face != NULL);
17618 PREPARE_FACE_FOR_DISPLAY (f, face);
17619 }
17620
17621 return face;
17622 }
17623
17624
17625 /* Set background width of glyph string S. START is the index of the
17626 first glyph following S. LAST_X is the right-most x-position + 1
17627 in the drawing area. */
17628
17629 static INLINE void
17630 set_glyph_string_background_width (s, start, last_x)
17631 struct glyph_string *s;
17632 int start;
17633 int last_x;
17634 {
17635 /* If the face of this glyph string has to be drawn to the end of
17636 the drawing area, set S->extends_to_end_of_line_p. */
17637 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17638
17639 if (start == s->row->used[s->area]
17640 && s->area == TEXT_AREA
17641 && ((s->hl == DRAW_NORMAL_TEXT
17642 && (s->row->fill_line_p
17643 || s->face->background != default_face->background
17644 || s->face->stipple != default_face->stipple
17645 || s->row->mouse_face_p))
17646 || s->hl == DRAW_MOUSE_FACE
17647 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17648 && s->row->fill_line_p)))
17649 s->extends_to_end_of_line_p = 1;
17650
17651 /* If S extends its face to the end of the line, set its
17652 background_width to the distance to the right edge of the drawing
17653 area. */
17654 if (s->extends_to_end_of_line_p)
17655 s->background_width = last_x - s->x + 1;
17656 else
17657 s->background_width = s->width;
17658 }
17659
17660
17661 /* Compute overhangs and x-positions for glyph string S and its
17662 predecessors, or successors. X is the starting x-position for S.
17663 BACKWARD_P non-zero means process predecessors. */
17664
17665 static void
17666 compute_overhangs_and_x (s, x, backward_p)
17667 struct glyph_string *s;
17668 int x;
17669 int backward_p;
17670 {
17671 if (backward_p)
17672 {
17673 while (s)
17674 {
17675 if (rif->compute_glyph_string_overhangs)
17676 rif->compute_glyph_string_overhangs (s);
17677 x -= s->width;
17678 s->x = x;
17679 s = s->prev;
17680 }
17681 }
17682 else
17683 {
17684 while (s)
17685 {
17686 if (rif->compute_glyph_string_overhangs)
17687 rif->compute_glyph_string_overhangs (s);
17688 s->x = x;
17689 x += s->width;
17690 s = s->next;
17691 }
17692 }
17693 }
17694
17695
17696
17697 /* The following macros are only called from draw_glyphs below.
17698 They reference the following parameters of that function directly:
17699 `w', `row', `area', and `overlap_p'
17700 as well as the following local variables:
17701 `s', `f', and `hdc' (in W32) */
17702
17703 #ifdef HAVE_NTGUI
17704 /* On W32, silently add local `hdc' variable to argument list of
17705 init_glyph_string. */
17706 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17707 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17708 #else
17709 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17710 init_glyph_string (s, char2b, w, row, area, start, hl)
17711 #endif
17712
17713 /* Add a glyph string for a stretch glyph to the list of strings
17714 between HEAD and TAIL. START is the index of the stretch glyph in
17715 row area AREA of glyph row ROW. END is the index of the last glyph
17716 in that glyph row area. X is the current output position assigned
17717 to the new glyph string constructed. HL overrides that face of the
17718 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17719 is the right-most x-position of the drawing area. */
17720
17721 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17722 and below -- keep them on one line. */
17723 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17724 do \
17725 { \
17726 s = (struct glyph_string *) alloca (sizeof *s); \
17727 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17728 START = fill_stretch_glyph_string (s, row, area, START, END); \
17729 append_glyph_string (&HEAD, &TAIL, s); \
17730 s->x = (X); \
17731 } \
17732 while (0)
17733
17734
17735 /* Add a glyph string for an image glyph to the list of strings
17736 between HEAD and TAIL. START is the index of the image glyph in
17737 row area AREA of glyph row ROW. END is the index of the last glyph
17738 in that glyph row area. X is the current output position assigned
17739 to the new glyph string constructed. HL overrides that face of the
17740 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17741 is the right-most x-position of the drawing area. */
17742
17743 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17744 do \
17745 { \
17746 s = (struct glyph_string *) alloca (sizeof *s); \
17747 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17748 fill_image_glyph_string (s); \
17749 append_glyph_string (&HEAD, &TAIL, s); \
17750 ++START; \
17751 s->x = (X); \
17752 } \
17753 while (0)
17754
17755
17756 /* Add a glyph string for a sequence of character glyphs to the list
17757 of strings between HEAD and TAIL. START is the index of the first
17758 glyph in row area AREA of glyph row ROW that is part of the new
17759 glyph string. END is the index of the last glyph in that glyph row
17760 area. X is the current output position assigned to the new glyph
17761 string constructed. HL overrides that face of the glyph; e.g. it
17762 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17763 right-most x-position of the drawing area. */
17764
17765 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17766 do \
17767 { \
17768 int c, face_id; \
17769 XChar2b *char2b; \
17770 \
17771 c = (row)->glyphs[area][START].u.ch; \
17772 face_id = (row)->glyphs[area][START].face_id; \
17773 \
17774 s = (struct glyph_string *) alloca (sizeof *s); \
17775 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17776 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17777 append_glyph_string (&HEAD, &TAIL, s); \
17778 s->x = (X); \
17779 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17780 } \
17781 while (0)
17782
17783
17784 /* Add a glyph string for a composite sequence to the list of strings
17785 between HEAD and TAIL. START is the index of the first glyph in
17786 row area AREA of glyph row ROW that is part of the new glyph
17787 string. END is the index of the last glyph in that glyph row area.
17788 X is the current output position assigned to the new glyph string
17789 constructed. HL overrides that face of the glyph; e.g. it is
17790 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17791 x-position of the drawing area. */
17792
17793 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17794 do { \
17795 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17796 int face_id = (row)->glyphs[area][START].face_id; \
17797 struct face *base_face = FACE_FROM_ID (f, face_id); \
17798 struct composition *cmp = composition_table[cmp_id]; \
17799 int glyph_len = cmp->glyph_len; \
17800 XChar2b *char2b; \
17801 struct face **faces; \
17802 struct glyph_string *first_s = NULL; \
17803 int n; \
17804 \
17805 base_face = base_face->ascii_face; \
17806 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17807 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17808 /* At first, fill in `char2b' and `faces'. */ \
17809 for (n = 0; n < glyph_len; n++) \
17810 { \
17811 int c = COMPOSITION_GLYPH (cmp, n); \
17812 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17813 faces[n] = FACE_FROM_ID (f, this_face_id); \
17814 get_char_face_and_encoding (f, c, this_face_id, \
17815 char2b + n, 1, 1); \
17816 } \
17817 \
17818 /* Make glyph_strings for each glyph sequence that is drawable by \
17819 the same face, and append them to HEAD/TAIL. */ \
17820 for (n = 0; n < cmp->glyph_len;) \
17821 { \
17822 s = (struct glyph_string *) alloca (sizeof *s); \
17823 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17824 append_glyph_string (&(HEAD), &(TAIL), s); \
17825 s->cmp = cmp; \
17826 s->gidx = n; \
17827 s->x = (X); \
17828 \
17829 if (n == 0) \
17830 first_s = s; \
17831 \
17832 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17833 } \
17834 \
17835 ++START; \
17836 s = first_s; \
17837 } while (0)
17838
17839
17840 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17841 of AREA of glyph row ROW on window W between indices START and END.
17842 HL overrides the face for drawing glyph strings, e.g. it is
17843 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17844 x-positions of the drawing area.
17845
17846 This is an ugly monster macro construct because we must use alloca
17847 to allocate glyph strings (because draw_glyphs can be called
17848 asynchronously). */
17849
17850 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17851 do \
17852 { \
17853 HEAD = TAIL = NULL; \
17854 while (START < END) \
17855 { \
17856 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17857 switch (first_glyph->type) \
17858 { \
17859 case CHAR_GLYPH: \
17860 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17861 HL, X, LAST_X); \
17862 break; \
17863 \
17864 case COMPOSITE_GLYPH: \
17865 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17866 HL, X, LAST_X); \
17867 break; \
17868 \
17869 case STRETCH_GLYPH: \
17870 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17871 HL, X, LAST_X); \
17872 break; \
17873 \
17874 case IMAGE_GLYPH: \
17875 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17876 HL, X, LAST_X); \
17877 break; \
17878 \
17879 default: \
17880 abort (); \
17881 } \
17882 \
17883 set_glyph_string_background_width (s, START, LAST_X); \
17884 (X) += s->width; \
17885 } \
17886 } \
17887 while (0)
17888
17889
17890 /* Draw glyphs between START and END in AREA of ROW on window W,
17891 starting at x-position X. X is relative to AREA in W. HL is a
17892 face-override with the following meaning:
17893
17894 DRAW_NORMAL_TEXT draw normally
17895 DRAW_CURSOR draw in cursor face
17896 DRAW_MOUSE_FACE draw in mouse face.
17897 DRAW_INVERSE_VIDEO draw in mode line face
17898 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17899 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17900
17901 If OVERLAPS_P is non-zero, draw only the foreground of characters
17902 and clip to the physical height of ROW.
17903
17904 Value is the x-position reached, relative to AREA of W. */
17905
17906 static int
17907 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17908 struct window *w;
17909 int x;
17910 struct glyph_row *row;
17911 enum glyph_row_area area;
17912 int start, end;
17913 enum draw_glyphs_face hl;
17914 int overlaps_p;
17915 {
17916 struct glyph_string *head, *tail;
17917 struct glyph_string *s;
17918 int last_x, area_width;
17919 int x_reached;
17920 int i, j;
17921 struct frame *f = XFRAME (WINDOW_FRAME (w));
17922 DECLARE_HDC (hdc);
17923
17924 ALLOCATE_HDC (hdc, f);
17925
17926 /* Let's rather be paranoid than getting a SEGV. */
17927 end = min (end, row->used[area]);
17928 start = max (0, start);
17929 start = min (end, start);
17930
17931 /* Translate X to frame coordinates. Set last_x to the right
17932 end of the drawing area. */
17933 if (row->full_width_p)
17934 {
17935 /* X is relative to the left edge of W, without scroll bars
17936 or fringes. */
17937 x += WINDOW_LEFT_EDGE_X (w);
17938 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
17939 }
17940 else
17941 {
17942 int area_left = window_box_left (w, area);
17943 x += area_left;
17944 area_width = window_box_width (w, area);
17945 last_x = area_left + area_width;
17946 }
17947
17948 /* Build a doubly-linked list of glyph_string structures between
17949 head and tail from what we have to draw. Note that the macro
17950 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17951 the reason we use a separate variable `i'. */
17952 i = start;
17953 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17954 if (tail)
17955 x_reached = tail->x + tail->background_width;
17956 else
17957 x_reached = x;
17958
17959 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17960 the row, redraw some glyphs in front or following the glyph
17961 strings built above. */
17962 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17963 {
17964 int dummy_x = 0;
17965 struct glyph_string *h, *t;
17966
17967 /* Compute overhangs for all glyph strings. */
17968 if (rif->compute_glyph_string_overhangs)
17969 for (s = head; s; s = s->next)
17970 rif->compute_glyph_string_overhangs (s);
17971
17972 /* Prepend glyph strings for glyphs in front of the first glyph
17973 string that are overwritten because of the first glyph
17974 string's left overhang. The background of all strings
17975 prepended must be drawn because the first glyph string
17976 draws over it. */
17977 i = left_overwritten (head);
17978 if (i >= 0)
17979 {
17980 j = i;
17981 BUILD_GLYPH_STRINGS (j, start, h, t,
17982 DRAW_NORMAL_TEXT, dummy_x, last_x);
17983 start = i;
17984 compute_overhangs_and_x (t, head->x, 1);
17985 prepend_glyph_string_lists (&head, &tail, h, t);
17986 }
17987
17988 /* Prepend glyph strings for glyphs in front of the first glyph
17989 string that overwrite that glyph string because of their
17990 right overhang. For these strings, only the foreground must
17991 be drawn, because it draws over the glyph string at `head'.
17992 The background must not be drawn because this would overwrite
17993 right overhangs of preceding glyphs for which no glyph
17994 strings exist. */
17995 i = left_overwriting (head);
17996 if (i >= 0)
17997 {
17998 BUILD_GLYPH_STRINGS (i, start, h, t,
17999 DRAW_NORMAL_TEXT, dummy_x, last_x);
18000 for (s = h; s; s = s->next)
18001 s->background_filled_p = 1;
18002 compute_overhangs_and_x (t, head->x, 1);
18003 prepend_glyph_string_lists (&head, &tail, h, t);
18004 }
18005
18006 /* Append glyphs strings for glyphs following the last glyph
18007 string tail that are overwritten by tail. The background of
18008 these strings has to be drawn because tail's foreground draws
18009 over it. */
18010 i = right_overwritten (tail);
18011 if (i >= 0)
18012 {
18013 BUILD_GLYPH_STRINGS (end, i, h, t,
18014 DRAW_NORMAL_TEXT, x, last_x);
18015 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18016 append_glyph_string_lists (&head, &tail, h, t);
18017 }
18018
18019 /* Append glyph strings for glyphs following the last glyph
18020 string tail that overwrite tail. The foreground of such
18021 glyphs has to be drawn because it writes into the background
18022 of tail. The background must not be drawn because it could
18023 paint over the foreground of following glyphs. */
18024 i = right_overwriting (tail);
18025 if (i >= 0)
18026 {
18027 BUILD_GLYPH_STRINGS (end, i, h, t,
18028 DRAW_NORMAL_TEXT, x, last_x);
18029 for (s = h; s; s = s->next)
18030 s->background_filled_p = 1;
18031 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18032 append_glyph_string_lists (&head, &tail, h, t);
18033 }
18034 }
18035
18036 /* Draw all strings. */
18037 for (s = head; s; s = s->next)
18038 rif->draw_glyph_string (s);
18039
18040 if (area == TEXT_AREA
18041 && !row->full_width_p
18042 /* When drawing overlapping rows, only the glyph strings'
18043 foreground is drawn, which doesn't erase a cursor
18044 completely. */
18045 && !overlaps_p)
18046 {
18047 int x0 = head ? head->x : x;
18048 int x1 = tail ? tail->x + tail->background_width : x;
18049
18050 int text_left = window_box_left (w, TEXT_AREA);
18051 x0 -= text_left;
18052 x1 -= text_left;
18053
18054 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18055 row->y, MATRIX_ROW_BOTTOM_Y (row));
18056 }
18057
18058 /* Value is the x-position up to which drawn, relative to AREA of W.
18059 This doesn't include parts drawn because of overhangs. */
18060 if (row->full_width_p)
18061 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18062 else
18063 x_reached -= window_box_left (w, area);
18064
18065 RELEASE_HDC (hdc, f);
18066
18067 return x_reached;
18068 }
18069
18070
18071 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18072 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18073
18074 static INLINE void
18075 append_glyph (it)
18076 struct it *it;
18077 {
18078 struct glyph *glyph;
18079 enum glyph_row_area area = it->area;
18080
18081 xassert (it->glyph_row);
18082 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18083
18084 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18085 if (glyph < it->glyph_row->glyphs[area + 1])
18086 {
18087 glyph->charpos = CHARPOS (it->position);
18088 glyph->object = it->object;
18089 glyph->pixel_width = it->pixel_width;
18090 glyph->ascent = it->ascent;
18091 glyph->descent = it->descent;
18092 glyph->voffset = it->voffset;
18093 glyph->type = CHAR_GLYPH;
18094 glyph->multibyte_p = it->multibyte_p;
18095 glyph->left_box_line_p = it->start_of_box_run_p;
18096 glyph->right_box_line_p = it->end_of_box_run_p;
18097 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18098 || it->phys_descent > it->descent);
18099 glyph->padding_p = 0;
18100 glyph->glyph_not_available_p = it->glyph_not_available_p;
18101 glyph->face_id = it->face_id;
18102 glyph->u.ch = it->char_to_display;
18103 glyph->slice = null_glyph_slice;
18104 glyph->font_type = FONT_TYPE_UNKNOWN;
18105 ++it->glyph_row->used[area];
18106 }
18107 }
18108
18109 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18110 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18111
18112 static INLINE void
18113 append_composite_glyph (it)
18114 struct it *it;
18115 {
18116 struct glyph *glyph;
18117 enum glyph_row_area area = it->area;
18118
18119 xassert (it->glyph_row);
18120
18121 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18122 if (glyph < it->glyph_row->glyphs[area + 1])
18123 {
18124 glyph->charpos = CHARPOS (it->position);
18125 glyph->object = it->object;
18126 glyph->pixel_width = it->pixel_width;
18127 glyph->ascent = it->ascent;
18128 glyph->descent = it->descent;
18129 glyph->voffset = it->voffset;
18130 glyph->type = COMPOSITE_GLYPH;
18131 glyph->multibyte_p = it->multibyte_p;
18132 glyph->left_box_line_p = it->start_of_box_run_p;
18133 glyph->right_box_line_p = it->end_of_box_run_p;
18134 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18135 || it->phys_descent > it->descent);
18136 glyph->padding_p = 0;
18137 glyph->glyph_not_available_p = 0;
18138 glyph->face_id = it->face_id;
18139 glyph->u.cmp_id = it->cmp_id;
18140 glyph->slice = null_glyph_slice;
18141 glyph->font_type = FONT_TYPE_UNKNOWN;
18142 ++it->glyph_row->used[area];
18143 }
18144 }
18145
18146
18147 /* Change IT->ascent and IT->height according to the setting of
18148 IT->voffset. */
18149
18150 static INLINE void
18151 take_vertical_position_into_account (it)
18152 struct it *it;
18153 {
18154 if (it->voffset)
18155 {
18156 if (it->voffset < 0)
18157 /* Increase the ascent so that we can display the text higher
18158 in the line. */
18159 it->ascent -= it->voffset;
18160 else
18161 /* Increase the descent so that we can display the text lower
18162 in the line. */
18163 it->descent += it->voffset;
18164 }
18165 }
18166
18167
18168 /* Produce glyphs/get display metrics for the image IT is loaded with.
18169 See the description of struct display_iterator in dispextern.h for
18170 an overview of struct display_iterator. */
18171
18172 static void
18173 produce_image_glyph (it)
18174 struct it *it;
18175 {
18176 struct image *img;
18177 struct face *face;
18178 int face_ascent, glyph_ascent;
18179 struct glyph_slice slice;
18180
18181 xassert (it->what == IT_IMAGE);
18182
18183 face = FACE_FROM_ID (it->f, it->face_id);
18184 xassert (face);
18185 /* Make sure X resources of the face is loaded. */
18186 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18187
18188 if (it->image_id < 0)
18189 {
18190 /* Fringe bitmap. */
18191 it->ascent = it->phys_ascent = 0;
18192 it->descent = it->phys_descent = 0;
18193 it->pixel_width = 0;
18194 it->nglyphs = 0;
18195 return;
18196 }
18197
18198 img = IMAGE_FROM_ID (it->f, it->image_id);
18199 xassert (img);
18200 /* Make sure X resources of the image is loaded. */
18201 prepare_image_for_display (it->f, img);
18202
18203 slice.x = slice.y = 0;
18204 slice.width = img->width;
18205 slice.height = img->height;
18206
18207 if (INTEGERP (it->slice.x))
18208 slice.x = XINT (it->slice.x);
18209 else if (FLOATP (it->slice.x))
18210 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18211
18212 if (INTEGERP (it->slice.y))
18213 slice.y = XINT (it->slice.y);
18214 else if (FLOATP (it->slice.y))
18215 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18216
18217 if (INTEGERP (it->slice.width))
18218 slice.width = XINT (it->slice.width);
18219 else if (FLOATP (it->slice.width))
18220 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18221
18222 if (INTEGERP (it->slice.height))
18223 slice.height = XINT (it->slice.height);
18224 else if (FLOATP (it->slice.height))
18225 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18226
18227 if (slice.x >= img->width)
18228 slice.x = img->width;
18229 if (slice.y >= img->height)
18230 slice.y = img->height;
18231 if (slice.x + slice.width >= img->width)
18232 slice.width = img->width - slice.x;
18233 if (slice.y + slice.height > img->height)
18234 slice.height = img->height - slice.y;
18235
18236 if (slice.width == 0 || slice.height == 0)
18237 return;
18238
18239 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18240
18241 it->descent = slice.height - glyph_ascent;
18242 if (slice.y == 0)
18243 it->descent += img->vmargin;
18244 if (slice.y + slice.height == img->height)
18245 it->descent += img->vmargin;
18246 it->phys_descent = it->descent;
18247
18248 it->pixel_width = slice.width;
18249 if (slice.x == 0)
18250 it->pixel_width += img->hmargin;
18251 if (slice.x + slice.width == img->width)
18252 it->pixel_width += img->hmargin;
18253
18254 /* It's quite possible for images to have an ascent greater than
18255 their height, so don't get confused in that case. */
18256 if (it->descent < 0)
18257 it->descent = 0;
18258
18259 #if 0 /* this breaks image tiling */
18260 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18261 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18262 if (face_ascent > it->ascent)
18263 it->ascent = it->phys_ascent = face_ascent;
18264 #endif
18265
18266 it->nglyphs = 1;
18267
18268 if (face->box != FACE_NO_BOX)
18269 {
18270 if (face->box_line_width > 0)
18271 {
18272 if (slice.y == 0)
18273 it->ascent += face->box_line_width;
18274 if (slice.y + slice.height == img->height)
18275 it->descent += face->box_line_width;
18276 }
18277
18278 if (it->start_of_box_run_p && slice.x == 0)
18279 it->pixel_width += abs (face->box_line_width);
18280 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18281 it->pixel_width += abs (face->box_line_width);
18282 }
18283
18284 take_vertical_position_into_account (it);
18285
18286 if (it->glyph_row)
18287 {
18288 struct glyph *glyph;
18289 enum glyph_row_area area = it->area;
18290
18291 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18292 if (glyph < it->glyph_row->glyphs[area + 1])
18293 {
18294 glyph->charpos = CHARPOS (it->position);
18295 glyph->object = it->object;
18296 glyph->pixel_width = it->pixel_width;
18297 glyph->ascent = glyph_ascent;
18298 glyph->descent = it->descent;
18299 glyph->voffset = it->voffset;
18300 glyph->type = IMAGE_GLYPH;
18301 glyph->multibyte_p = it->multibyte_p;
18302 glyph->left_box_line_p = it->start_of_box_run_p;
18303 glyph->right_box_line_p = it->end_of_box_run_p;
18304 glyph->overlaps_vertically_p = 0;
18305 glyph->padding_p = 0;
18306 glyph->glyph_not_available_p = 0;
18307 glyph->face_id = it->face_id;
18308 glyph->u.img_id = img->id;
18309 glyph->slice = slice;
18310 glyph->font_type = FONT_TYPE_UNKNOWN;
18311 ++it->glyph_row->used[area];
18312 }
18313 }
18314 }
18315
18316
18317 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18318 of the glyph, WIDTH and HEIGHT are the width and height of the
18319 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18320
18321 static void
18322 append_stretch_glyph (it, object, width, height, ascent)
18323 struct it *it;
18324 Lisp_Object object;
18325 int width, height;
18326 int ascent;
18327 {
18328 struct glyph *glyph;
18329 enum glyph_row_area area = it->area;
18330
18331 xassert (ascent >= 0 && ascent <= height);
18332
18333 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18334 if (glyph < it->glyph_row->glyphs[area + 1])
18335 {
18336 glyph->charpos = CHARPOS (it->position);
18337 glyph->object = object;
18338 glyph->pixel_width = width;
18339 glyph->ascent = ascent;
18340 glyph->descent = height - ascent;
18341 glyph->voffset = it->voffset;
18342 glyph->type = STRETCH_GLYPH;
18343 glyph->multibyte_p = it->multibyte_p;
18344 glyph->left_box_line_p = it->start_of_box_run_p;
18345 glyph->right_box_line_p = it->end_of_box_run_p;
18346 glyph->overlaps_vertically_p = 0;
18347 glyph->padding_p = 0;
18348 glyph->glyph_not_available_p = 0;
18349 glyph->face_id = it->face_id;
18350 glyph->u.stretch.ascent = ascent;
18351 glyph->u.stretch.height = height;
18352 glyph->slice = null_glyph_slice;
18353 glyph->font_type = FONT_TYPE_UNKNOWN;
18354 ++it->glyph_row->used[area];
18355 }
18356 }
18357
18358
18359 /* Produce a stretch glyph for iterator IT. IT->object is the value
18360 of the glyph property displayed. The value must be a list
18361 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18362 being recognized:
18363
18364 1. `:width WIDTH' specifies that the space should be WIDTH *
18365 canonical char width wide. WIDTH may be an integer or floating
18366 point number.
18367
18368 2. `:relative-width FACTOR' specifies that the width of the stretch
18369 should be computed from the width of the first character having the
18370 `glyph' property, and should be FACTOR times that width.
18371
18372 3. `:align-to HPOS' specifies that the space should be wide enough
18373 to reach HPOS, a value in canonical character units.
18374
18375 Exactly one of the above pairs must be present.
18376
18377 4. `:height HEIGHT' specifies that the height of the stretch produced
18378 should be HEIGHT, measured in canonical character units.
18379
18380 5. `:relative-height FACTOR' specifies that the height of the
18381 stretch should be FACTOR times the height of the characters having
18382 the glyph property.
18383
18384 Either none or exactly one of 4 or 5 must be present.
18385
18386 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18387 of the stretch should be used for the ascent of the stretch.
18388 ASCENT must be in the range 0 <= ASCENT <= 100. */
18389
18390 static void
18391 produce_stretch_glyph (it)
18392 struct it *it;
18393 {
18394 /* (space :width WIDTH :height HEIGHT ...) */
18395 Lisp_Object prop, plist;
18396 int width = 0, height = 0, align_to = -1;
18397 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18398 int ascent = 0;
18399 double tem;
18400 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18401 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18402
18403 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18404
18405 /* List should start with `space'. */
18406 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18407 plist = XCDR (it->object);
18408
18409 /* Compute the width of the stretch. */
18410 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18411 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18412 {
18413 /* Absolute width `:width WIDTH' specified and valid. */
18414 zero_width_ok_p = 1;
18415 width = (int)tem;
18416 }
18417 else if (prop = Fplist_get (plist, QCrelative_width),
18418 NUMVAL (prop) > 0)
18419 {
18420 /* Relative width `:relative-width FACTOR' specified and valid.
18421 Compute the width of the characters having the `glyph'
18422 property. */
18423 struct it it2;
18424 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18425
18426 it2 = *it;
18427 if (it->multibyte_p)
18428 {
18429 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18430 - IT_BYTEPOS (*it));
18431 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18432 }
18433 else
18434 it2.c = *p, it2.len = 1;
18435
18436 it2.glyph_row = NULL;
18437 it2.what = IT_CHARACTER;
18438 x_produce_glyphs (&it2);
18439 width = NUMVAL (prop) * it2.pixel_width;
18440 }
18441 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18442 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18443 {
18444 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18445 align_to = (align_to < 0
18446 ? 0
18447 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18448 else if (align_to < 0)
18449 align_to = window_box_left_offset (it->w, TEXT_AREA);
18450 width = max (0, (int)tem + align_to - it->current_x);
18451 zero_width_ok_p = 1;
18452 }
18453 else
18454 /* Nothing specified -> width defaults to canonical char width. */
18455 width = FRAME_COLUMN_WIDTH (it->f);
18456
18457 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18458 width = 1;
18459
18460 /* Compute height. */
18461 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18462 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18463 {
18464 height = (int)tem;
18465 zero_height_ok_p = 1;
18466 }
18467 else if (prop = Fplist_get (plist, QCrelative_height),
18468 NUMVAL (prop) > 0)
18469 height = FONT_HEIGHT (font) * NUMVAL (prop);
18470 else
18471 height = FONT_HEIGHT (font);
18472
18473 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18474 height = 1;
18475
18476 /* Compute percentage of height used for ascent. If
18477 `:ascent ASCENT' is present and valid, use that. Otherwise,
18478 derive the ascent from the font in use. */
18479 if (prop = Fplist_get (plist, QCascent),
18480 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18481 ascent = height * NUMVAL (prop) / 100.0;
18482 else if (!NILP (prop)
18483 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18484 ascent = min (max (0, (int)tem), height);
18485 else
18486 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18487
18488 if (width > 0 && height > 0 && it->glyph_row)
18489 {
18490 Lisp_Object object = it->stack[it->sp - 1].string;
18491 if (!STRINGP (object))
18492 object = it->w->buffer;
18493 append_stretch_glyph (it, object, width, height, ascent);
18494 }
18495
18496 it->pixel_width = width;
18497 it->ascent = it->phys_ascent = ascent;
18498 it->descent = it->phys_descent = height - it->ascent;
18499 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18500
18501 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18502 {
18503 if (face->box_line_width > 0)
18504 {
18505 it->ascent += face->box_line_width;
18506 it->descent += face->box_line_width;
18507 }
18508
18509 if (it->start_of_box_run_p)
18510 it->pixel_width += abs (face->box_line_width);
18511 if (it->end_of_box_run_p)
18512 it->pixel_width += abs (face->box_line_width);
18513 }
18514
18515 take_vertical_position_into_account (it);
18516 }
18517
18518 /* Calculate line-height and line-spacing properties.
18519 An integer value specifies explicit pixel value.
18520 A float value specifies relative value to current face height.
18521 A cons (float . face-name) specifies relative value to
18522 height of specified face font.
18523
18524 Returns height in pixels, or nil. */
18525
18526 static Lisp_Object
18527 calc_line_height_property (it, prop, font, boff, total)
18528 struct it *it;
18529 Lisp_Object prop;
18530 XFontStruct *font;
18531 int boff, *total;
18532 {
18533 Lisp_Object position, val;
18534 Lisp_Object face_name = Qnil;
18535 int ascent, descent, height, override;
18536
18537 if (STRINGP (it->object))
18538 position = make_number (IT_STRING_CHARPOS (*it));
18539 else
18540 position = make_number (IT_CHARPOS (*it));
18541
18542 val = Fget_char_property (position, prop, it->object);
18543
18544 if (NILP (val))
18545 return val;
18546
18547 if (total && CONSP (val) && EQ (XCAR (val), Qtotal))
18548 {
18549 *total = 1;
18550 val = XCDR (val);
18551 }
18552
18553 if (INTEGERP (val))
18554 return val;
18555
18556 if (CONSP (val))
18557 {
18558 face_name = XCDR (val);
18559 val = XCAR (val);
18560 }
18561 else if (SYMBOLP (val))
18562 {
18563 face_name = val;
18564 val = Qnil;
18565 }
18566
18567 override = EQ (prop, Qline_height);
18568
18569 if (NILP (face_name))
18570 {
18571 font = FRAME_FONT (it->f);
18572 boff = FRAME_BASELINE_OFFSET (it->f);
18573 }
18574 else if (EQ (face_name, Qt))
18575 {
18576 override = 0;
18577 }
18578 else
18579 {
18580 int face_id;
18581 struct face *face;
18582 struct font_info *font_info;
18583
18584 face_id = lookup_named_face (it->f, face_name, ' ');
18585 if (face_id < 0)
18586 return make_number (-1);
18587
18588 face = FACE_FROM_ID (it->f, face_id);
18589 font = face->font;
18590 if (font == NULL)
18591 return make_number (-1);
18592
18593 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18594 boff = font_info->baseline_offset;
18595 if (font_info->vertical_centering)
18596 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18597 }
18598
18599 ascent = FONT_BASE (font) + boff;
18600 descent = FONT_DESCENT (font) - boff;
18601
18602 if (override)
18603 {
18604 it->override_ascent = ascent;
18605 it->override_descent = descent;
18606 it->override_boff = boff;
18607 }
18608
18609 height = ascent + descent;
18610 if (FLOATP (val))
18611 height = (int)(XFLOAT_DATA (val) * height);
18612 else if (INTEGERP (val))
18613 height *= XINT (val);
18614
18615 return make_number (height);
18616 }
18617
18618
18619 /* RIF:
18620 Produce glyphs/get display metrics for the display element IT is
18621 loaded with. See the description of struct display_iterator in
18622 dispextern.h for an overview of struct display_iterator. */
18623
18624 void
18625 x_produce_glyphs (it)
18626 struct it *it;
18627 {
18628 int extra_line_spacing = it->extra_line_spacing;
18629
18630 it->glyph_not_available_p = 0;
18631
18632 if (it->what == IT_CHARACTER)
18633 {
18634 XChar2b char2b;
18635 XFontStruct *font;
18636 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18637 XCharStruct *pcm;
18638 int font_not_found_p;
18639 struct font_info *font_info;
18640 int boff; /* baseline offset */
18641 /* We may change it->multibyte_p upon unibyte<->multibyte
18642 conversion. So, save the current value now and restore it
18643 later.
18644
18645 Note: It seems that we don't have to record multibyte_p in
18646 struct glyph because the character code itself tells if or
18647 not the character is multibyte. Thus, in the future, we must
18648 consider eliminating the field `multibyte_p' in the struct
18649 glyph. */
18650 int saved_multibyte_p = it->multibyte_p;
18651
18652 /* Maybe translate single-byte characters to multibyte, or the
18653 other way. */
18654 it->char_to_display = it->c;
18655 if (!ASCII_BYTE_P (it->c))
18656 {
18657 if (unibyte_display_via_language_environment
18658 && SINGLE_BYTE_CHAR_P (it->c)
18659 && (it->c >= 0240
18660 || !NILP (Vnonascii_translation_table)))
18661 {
18662 it->char_to_display = unibyte_char_to_multibyte (it->c);
18663 it->multibyte_p = 1;
18664 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18665 face = FACE_FROM_ID (it->f, it->face_id);
18666 }
18667 else if (!SINGLE_BYTE_CHAR_P (it->c)
18668 && !it->multibyte_p)
18669 {
18670 it->multibyte_p = 1;
18671 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18672 face = FACE_FROM_ID (it->f, it->face_id);
18673 }
18674 }
18675
18676 /* Get font to use. Encode IT->char_to_display. */
18677 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18678 &char2b, it->multibyte_p, 0);
18679 font = face->font;
18680
18681 /* When no suitable font found, use the default font. */
18682 font_not_found_p = font == NULL;
18683 if (font_not_found_p)
18684 {
18685 font = FRAME_FONT (it->f);
18686 boff = FRAME_BASELINE_OFFSET (it->f);
18687 font_info = NULL;
18688 }
18689 else
18690 {
18691 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18692 boff = font_info->baseline_offset;
18693 if (font_info->vertical_centering)
18694 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18695 }
18696
18697 if (it->char_to_display >= ' '
18698 && (!it->multibyte_p || it->char_to_display < 128))
18699 {
18700 /* Either unibyte or ASCII. */
18701 int stretched_p;
18702
18703 it->nglyphs = 1;
18704
18705 pcm = rif->per_char_metric (font, &char2b,
18706 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18707
18708 if (it->override_ascent >= 0)
18709 {
18710 it->ascent = it->override_ascent;
18711 it->descent = it->override_descent;
18712 boff = it->override_boff;
18713 }
18714 else
18715 {
18716 it->ascent = FONT_BASE (font) + boff;
18717 it->descent = FONT_DESCENT (font) - boff;
18718 }
18719
18720 if (pcm)
18721 {
18722 it->phys_ascent = pcm->ascent + boff;
18723 it->phys_descent = pcm->descent - boff;
18724 it->pixel_width = pcm->width;
18725 }
18726 else
18727 {
18728 it->glyph_not_available_p = 1;
18729 it->phys_ascent = it->ascent;
18730 it->phys_descent = it->descent;
18731 it->pixel_width = FONT_WIDTH (font);
18732 }
18733
18734 if (it->constrain_row_ascent_descent_p)
18735 {
18736 if (it->descent > it->max_descent)
18737 {
18738 it->ascent += it->descent - it->max_descent;
18739 it->descent = it->max_descent;
18740 }
18741 if (it->ascent > it->max_ascent)
18742 {
18743 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18744 it->ascent = it->max_ascent;
18745 }
18746 it->phys_ascent = min (it->phys_ascent, it->ascent);
18747 it->phys_descent = min (it->phys_descent, it->descent);
18748 extra_line_spacing = 0;
18749 }
18750
18751 /* If this is a space inside a region of text with
18752 `space-width' property, change its width. */
18753 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18754 if (stretched_p)
18755 it->pixel_width *= XFLOATINT (it->space_width);
18756
18757 /* If face has a box, add the box thickness to the character
18758 height. If character has a box line to the left and/or
18759 right, add the box line width to the character's width. */
18760 if (face->box != FACE_NO_BOX)
18761 {
18762 int thick = face->box_line_width;
18763
18764 if (thick > 0)
18765 {
18766 it->ascent += thick;
18767 it->descent += thick;
18768 }
18769 else
18770 thick = -thick;
18771
18772 if (it->start_of_box_run_p)
18773 it->pixel_width += thick;
18774 if (it->end_of_box_run_p)
18775 it->pixel_width += thick;
18776 }
18777
18778 /* If face has an overline, add the height of the overline
18779 (1 pixel) and a 1 pixel margin to the character height. */
18780 if (face->overline_p)
18781 it->ascent += 2;
18782
18783 if (it->constrain_row_ascent_descent_p)
18784 {
18785 if (it->ascent > it->max_ascent)
18786 it->ascent = it->max_ascent;
18787 if (it->descent > it->max_descent)
18788 it->descent = it->max_descent;
18789 }
18790
18791 take_vertical_position_into_account (it);
18792
18793 /* If we have to actually produce glyphs, do it. */
18794 if (it->glyph_row)
18795 {
18796 if (stretched_p)
18797 {
18798 /* Translate a space with a `space-width' property
18799 into a stretch glyph. */
18800 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18801 / FONT_HEIGHT (font));
18802 append_stretch_glyph (it, it->object, it->pixel_width,
18803 it->ascent + it->descent, ascent);
18804 }
18805 else
18806 append_glyph (it);
18807
18808 /* If characters with lbearing or rbearing are displayed
18809 in this line, record that fact in a flag of the
18810 glyph row. This is used to optimize X output code. */
18811 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18812 it->glyph_row->contains_overlapping_glyphs_p = 1;
18813 }
18814 }
18815 else if (it->char_to_display == '\n')
18816 {
18817 /* A newline has no width but we need the height of the line.
18818 But if previous part of the line set a height, don't
18819 increase that height */
18820
18821 Lisp_Object height;
18822
18823 it->override_ascent = -1;
18824 it->pixel_width = 0;
18825 it->nglyphs = 0;
18826
18827 height = calc_line_height_property(it, Qline_height, font, boff, 0);
18828
18829 if (it->override_ascent >= 0)
18830 {
18831 it->ascent = it->override_ascent;
18832 it->descent = it->override_descent;
18833 boff = it->override_boff;
18834 }
18835 else
18836 {
18837 it->ascent = FONT_BASE (font) + boff;
18838 it->descent = FONT_DESCENT (font) - boff;
18839 }
18840
18841 if (EQ (height, make_number(0)))
18842 {
18843 if (it->descent > it->max_descent)
18844 {
18845 it->ascent += it->descent - it->max_descent;
18846 it->descent = it->max_descent;
18847 }
18848 if (it->ascent > it->max_ascent)
18849 {
18850 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18851 it->ascent = it->max_ascent;
18852 }
18853 it->phys_ascent = min (it->phys_ascent, it->ascent);
18854 it->phys_descent = min (it->phys_descent, it->descent);
18855 it->constrain_row_ascent_descent_p = 1;
18856 extra_line_spacing = 0;
18857 }
18858 else
18859 {
18860 Lisp_Object spacing;
18861 int total = 0;
18862
18863 it->phys_ascent = it->ascent;
18864 it->phys_descent = it->descent;
18865
18866 if ((it->max_ascent > 0 || it->max_descent > 0)
18867 && face->box != FACE_NO_BOX
18868 && face->box_line_width > 0)
18869 {
18870 it->ascent += face->box_line_width;
18871 it->descent += face->box_line_width;
18872 }
18873 if (!NILP (height)
18874 && XINT (height) > it->ascent + it->descent)
18875 it->ascent = XINT (height) - it->descent;
18876
18877 spacing = calc_line_height_property(it, Qline_spacing, font, boff, &total);
18878 if (INTEGERP (spacing))
18879 {
18880 extra_line_spacing = XINT (spacing);
18881 if (total)
18882 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
18883 }
18884 }
18885 }
18886 else if (it->char_to_display == '\t')
18887 {
18888 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
18889 int x = it->current_x + it->continuation_lines_width;
18890 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
18891
18892 /* If the distance from the current position to the next tab
18893 stop is less than a canonical character width, use the
18894 tab stop after that. */
18895 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
18896 next_tab_x += tab_width;
18897
18898 it->pixel_width = next_tab_x - x;
18899 it->nglyphs = 1;
18900 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18901 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18902
18903 if (it->glyph_row)
18904 {
18905 append_stretch_glyph (it, it->object, it->pixel_width,
18906 it->ascent + it->descent, it->ascent);
18907 }
18908 }
18909 else
18910 {
18911 /* A multi-byte character. Assume that the display width of the
18912 character is the width of the character multiplied by the
18913 width of the font. */
18914
18915 /* If we found a font, this font should give us the right
18916 metrics. If we didn't find a font, use the frame's
18917 default font and calculate the width of the character
18918 from the charset width; this is what old redisplay code
18919 did. */
18920
18921 pcm = rif->per_char_metric (font, &char2b,
18922 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18923
18924 if (font_not_found_p || !pcm)
18925 {
18926 int charset = CHAR_CHARSET (it->char_to_display);
18927
18928 it->glyph_not_available_p = 1;
18929 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
18930 * CHARSET_WIDTH (charset));
18931 it->phys_ascent = FONT_BASE (font) + boff;
18932 it->phys_descent = FONT_DESCENT (font) - boff;
18933 }
18934 else
18935 {
18936 it->pixel_width = pcm->width;
18937 it->phys_ascent = pcm->ascent + boff;
18938 it->phys_descent = pcm->descent - boff;
18939 if (it->glyph_row
18940 && (pcm->lbearing < 0
18941 || pcm->rbearing > pcm->width))
18942 it->glyph_row->contains_overlapping_glyphs_p = 1;
18943 }
18944 it->nglyphs = 1;
18945 it->ascent = FONT_BASE (font) + boff;
18946 it->descent = FONT_DESCENT (font) - boff;
18947 if (face->box != FACE_NO_BOX)
18948 {
18949 int thick = face->box_line_width;
18950
18951 if (thick > 0)
18952 {
18953 it->ascent += thick;
18954 it->descent += thick;
18955 }
18956 else
18957 thick = - thick;
18958
18959 if (it->start_of_box_run_p)
18960 it->pixel_width += thick;
18961 if (it->end_of_box_run_p)
18962 it->pixel_width += thick;
18963 }
18964
18965 /* If face has an overline, add the height of the overline
18966 (1 pixel) and a 1 pixel margin to the character height. */
18967 if (face->overline_p)
18968 it->ascent += 2;
18969
18970 take_vertical_position_into_account (it);
18971
18972 if (it->glyph_row)
18973 append_glyph (it);
18974 }
18975 it->multibyte_p = saved_multibyte_p;
18976 }
18977 else if (it->what == IT_COMPOSITION)
18978 {
18979 /* Note: A composition is represented as one glyph in the
18980 glyph matrix. There are no padding glyphs. */
18981 XChar2b char2b;
18982 XFontStruct *font;
18983 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18984 XCharStruct *pcm;
18985 int font_not_found_p;
18986 struct font_info *font_info;
18987 int boff; /* baseline offset */
18988 struct composition *cmp = composition_table[it->cmp_id];
18989
18990 /* Maybe translate single-byte characters to multibyte. */
18991 it->char_to_display = it->c;
18992 if (unibyte_display_via_language_environment
18993 && SINGLE_BYTE_CHAR_P (it->c)
18994 && (it->c >= 0240
18995 || (it->c >= 0200
18996 && !NILP (Vnonascii_translation_table))))
18997 {
18998 it->char_to_display = unibyte_char_to_multibyte (it->c);
18999 }
19000
19001 /* Get face and font to use. Encode IT->char_to_display. */
19002 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19003 face = FACE_FROM_ID (it->f, it->face_id);
19004 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19005 &char2b, it->multibyte_p, 0);
19006 font = face->font;
19007
19008 /* When no suitable font found, use the default font. */
19009 font_not_found_p = font == NULL;
19010 if (font_not_found_p)
19011 {
19012 font = FRAME_FONT (it->f);
19013 boff = FRAME_BASELINE_OFFSET (it->f);
19014 font_info = NULL;
19015 }
19016 else
19017 {
19018 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19019 boff = font_info->baseline_offset;
19020 if (font_info->vertical_centering)
19021 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19022 }
19023
19024 /* There are no padding glyphs, so there is only one glyph to
19025 produce for the composition. Important is that pixel_width,
19026 ascent and descent are the values of what is drawn by
19027 draw_glyphs (i.e. the values of the overall glyphs composed). */
19028 it->nglyphs = 1;
19029
19030 /* If we have not yet calculated pixel size data of glyphs of
19031 the composition for the current face font, calculate them
19032 now. Theoretically, we have to check all fonts for the
19033 glyphs, but that requires much time and memory space. So,
19034 here we check only the font of the first glyph. This leads
19035 to incorrect display very rarely, and C-l (recenter) can
19036 correct the display anyway. */
19037 if (cmp->font != (void *) font)
19038 {
19039 /* Ascent and descent of the font of the first character of
19040 this composition (adjusted by baseline offset). Ascent
19041 and descent of overall glyphs should not be less than
19042 them respectively. */
19043 int font_ascent = FONT_BASE (font) + boff;
19044 int font_descent = FONT_DESCENT (font) - boff;
19045 /* Bounding box of the overall glyphs. */
19046 int leftmost, rightmost, lowest, highest;
19047 int i, width, ascent, descent;
19048
19049 cmp->font = (void *) font;
19050
19051 /* Initialize the bounding box. */
19052 if (font_info
19053 && (pcm = rif->per_char_metric (font, &char2b,
19054 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19055 {
19056 width = pcm->width;
19057 ascent = pcm->ascent;
19058 descent = pcm->descent;
19059 }
19060 else
19061 {
19062 width = FONT_WIDTH (font);
19063 ascent = FONT_BASE (font);
19064 descent = FONT_DESCENT (font);
19065 }
19066
19067 rightmost = width;
19068 lowest = - descent + boff;
19069 highest = ascent + boff;
19070 leftmost = 0;
19071
19072 if (font_info
19073 && font_info->default_ascent
19074 && CHAR_TABLE_P (Vuse_default_ascent)
19075 && !NILP (Faref (Vuse_default_ascent,
19076 make_number (it->char_to_display))))
19077 highest = font_info->default_ascent + boff;
19078
19079 /* Draw the first glyph at the normal position. It may be
19080 shifted to right later if some other glyphs are drawn at
19081 the left. */
19082 cmp->offsets[0] = 0;
19083 cmp->offsets[1] = boff;
19084
19085 /* Set cmp->offsets for the remaining glyphs. */
19086 for (i = 1; i < cmp->glyph_len; i++)
19087 {
19088 int left, right, btm, top;
19089 int ch = COMPOSITION_GLYPH (cmp, i);
19090 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19091
19092 face = FACE_FROM_ID (it->f, face_id);
19093 get_char_face_and_encoding (it->f, ch, face->id,
19094 &char2b, it->multibyte_p, 0);
19095 font = face->font;
19096 if (font == NULL)
19097 {
19098 font = FRAME_FONT (it->f);
19099 boff = FRAME_BASELINE_OFFSET (it->f);
19100 font_info = NULL;
19101 }
19102 else
19103 {
19104 font_info
19105 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19106 boff = font_info->baseline_offset;
19107 if (font_info->vertical_centering)
19108 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19109 }
19110
19111 if (font_info
19112 && (pcm = rif->per_char_metric (font, &char2b,
19113 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19114 {
19115 width = pcm->width;
19116 ascent = pcm->ascent;
19117 descent = pcm->descent;
19118 }
19119 else
19120 {
19121 width = FONT_WIDTH (font);
19122 ascent = 1;
19123 descent = 0;
19124 }
19125
19126 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19127 {
19128 /* Relative composition with or without
19129 alternate chars. */
19130 left = (leftmost + rightmost - width) / 2;
19131 btm = - descent + boff;
19132 if (font_info && font_info->relative_compose
19133 && (! CHAR_TABLE_P (Vignore_relative_composition)
19134 || NILP (Faref (Vignore_relative_composition,
19135 make_number (ch)))))
19136 {
19137
19138 if (- descent >= font_info->relative_compose)
19139 /* One extra pixel between two glyphs. */
19140 btm = highest + 1;
19141 else if (ascent <= 0)
19142 /* One extra pixel between two glyphs. */
19143 btm = lowest - 1 - ascent - descent;
19144 }
19145 }
19146 else
19147 {
19148 /* A composition rule is specified by an integer
19149 value that encodes global and new reference
19150 points (GREF and NREF). GREF and NREF are
19151 specified by numbers as below:
19152
19153 0---1---2 -- ascent
19154 | |
19155 | |
19156 | |
19157 9--10--11 -- center
19158 | |
19159 ---3---4---5--- baseline
19160 | |
19161 6---7---8 -- descent
19162 */
19163 int rule = COMPOSITION_RULE (cmp, i);
19164 int gref, nref, grefx, grefy, nrefx, nrefy;
19165
19166 COMPOSITION_DECODE_RULE (rule, gref, nref);
19167 grefx = gref % 3, nrefx = nref % 3;
19168 grefy = gref / 3, nrefy = nref / 3;
19169
19170 left = (leftmost
19171 + grefx * (rightmost - leftmost) / 2
19172 - nrefx * width / 2);
19173 btm = ((grefy == 0 ? highest
19174 : grefy == 1 ? 0
19175 : grefy == 2 ? lowest
19176 : (highest + lowest) / 2)
19177 - (nrefy == 0 ? ascent + descent
19178 : nrefy == 1 ? descent - boff
19179 : nrefy == 2 ? 0
19180 : (ascent + descent) / 2));
19181 }
19182
19183 cmp->offsets[i * 2] = left;
19184 cmp->offsets[i * 2 + 1] = btm + descent;
19185
19186 /* Update the bounding box of the overall glyphs. */
19187 right = left + width;
19188 top = btm + descent + ascent;
19189 if (left < leftmost)
19190 leftmost = left;
19191 if (right > rightmost)
19192 rightmost = right;
19193 if (top > highest)
19194 highest = top;
19195 if (btm < lowest)
19196 lowest = btm;
19197 }
19198
19199 /* If there are glyphs whose x-offsets are negative,
19200 shift all glyphs to the right and make all x-offsets
19201 non-negative. */
19202 if (leftmost < 0)
19203 {
19204 for (i = 0; i < cmp->glyph_len; i++)
19205 cmp->offsets[i * 2] -= leftmost;
19206 rightmost -= leftmost;
19207 }
19208
19209 cmp->pixel_width = rightmost;
19210 cmp->ascent = highest;
19211 cmp->descent = - lowest;
19212 if (cmp->ascent < font_ascent)
19213 cmp->ascent = font_ascent;
19214 if (cmp->descent < font_descent)
19215 cmp->descent = font_descent;
19216 }
19217
19218 it->pixel_width = cmp->pixel_width;
19219 it->ascent = it->phys_ascent = cmp->ascent;
19220 it->descent = it->phys_descent = cmp->descent;
19221
19222 if (face->box != FACE_NO_BOX)
19223 {
19224 int thick = face->box_line_width;
19225
19226 if (thick > 0)
19227 {
19228 it->ascent += thick;
19229 it->descent += thick;
19230 }
19231 else
19232 thick = - thick;
19233
19234 if (it->start_of_box_run_p)
19235 it->pixel_width += thick;
19236 if (it->end_of_box_run_p)
19237 it->pixel_width += thick;
19238 }
19239
19240 /* If face has an overline, add the height of the overline
19241 (1 pixel) and a 1 pixel margin to the character height. */
19242 if (face->overline_p)
19243 it->ascent += 2;
19244
19245 take_vertical_position_into_account (it);
19246
19247 if (it->glyph_row)
19248 append_composite_glyph (it);
19249 }
19250 else if (it->what == IT_IMAGE)
19251 produce_image_glyph (it);
19252 else if (it->what == IT_STRETCH)
19253 produce_stretch_glyph (it);
19254
19255 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19256 because this isn't true for images with `:ascent 100'. */
19257 xassert (it->ascent >= 0 && it->descent >= 0);
19258 if (it->area == TEXT_AREA)
19259 it->current_x += it->pixel_width;
19260
19261 if (extra_line_spacing > 0)
19262 it->descent += extra_line_spacing;
19263
19264 it->max_ascent = max (it->max_ascent, it->ascent);
19265 it->max_descent = max (it->max_descent, it->descent);
19266 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19267 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19268 }
19269
19270 /* EXPORT for RIF:
19271 Output LEN glyphs starting at START at the nominal cursor position.
19272 Advance the nominal cursor over the text. The global variable
19273 updated_window contains the window being updated, updated_row is
19274 the glyph row being updated, and updated_area is the area of that
19275 row being updated. */
19276
19277 void
19278 x_write_glyphs (start, len)
19279 struct glyph *start;
19280 int len;
19281 {
19282 int x, hpos;
19283
19284 xassert (updated_window && updated_row);
19285 BLOCK_INPUT;
19286
19287 /* Write glyphs. */
19288
19289 hpos = start - updated_row->glyphs[updated_area];
19290 x = draw_glyphs (updated_window, output_cursor.x,
19291 updated_row, updated_area,
19292 hpos, hpos + len,
19293 DRAW_NORMAL_TEXT, 0);
19294
19295 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19296 if (updated_area == TEXT_AREA
19297 && updated_window->phys_cursor_on_p
19298 && updated_window->phys_cursor.vpos == output_cursor.vpos
19299 && updated_window->phys_cursor.hpos >= hpos
19300 && updated_window->phys_cursor.hpos < hpos + len)
19301 updated_window->phys_cursor_on_p = 0;
19302
19303 UNBLOCK_INPUT;
19304
19305 /* Advance the output cursor. */
19306 output_cursor.hpos += len;
19307 output_cursor.x = x;
19308 }
19309
19310
19311 /* EXPORT for RIF:
19312 Insert LEN glyphs from START at the nominal cursor position. */
19313
19314 void
19315 x_insert_glyphs (start, len)
19316 struct glyph *start;
19317 int len;
19318 {
19319 struct frame *f;
19320 struct window *w;
19321 int line_height, shift_by_width, shifted_region_width;
19322 struct glyph_row *row;
19323 struct glyph *glyph;
19324 int frame_x, frame_y, hpos;
19325
19326 xassert (updated_window && updated_row);
19327 BLOCK_INPUT;
19328 w = updated_window;
19329 f = XFRAME (WINDOW_FRAME (w));
19330
19331 /* Get the height of the line we are in. */
19332 row = updated_row;
19333 line_height = row->height;
19334
19335 /* Get the width of the glyphs to insert. */
19336 shift_by_width = 0;
19337 for (glyph = start; glyph < start + len; ++glyph)
19338 shift_by_width += glyph->pixel_width;
19339
19340 /* Get the width of the region to shift right. */
19341 shifted_region_width = (window_box_width (w, updated_area)
19342 - output_cursor.x
19343 - shift_by_width);
19344
19345 /* Shift right. */
19346 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19347 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19348
19349 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19350 line_height, shift_by_width);
19351
19352 /* Write the glyphs. */
19353 hpos = start - row->glyphs[updated_area];
19354 draw_glyphs (w, output_cursor.x, row, updated_area,
19355 hpos, hpos + len,
19356 DRAW_NORMAL_TEXT, 0);
19357
19358 /* Advance the output cursor. */
19359 output_cursor.hpos += len;
19360 output_cursor.x += shift_by_width;
19361 UNBLOCK_INPUT;
19362 }
19363
19364
19365 /* EXPORT for RIF:
19366 Erase the current text line from the nominal cursor position
19367 (inclusive) to pixel column TO_X (exclusive). The idea is that
19368 everything from TO_X onward is already erased.
19369
19370 TO_X is a pixel position relative to updated_area of
19371 updated_window. TO_X == -1 means clear to the end of this area. */
19372
19373 void
19374 x_clear_end_of_line (to_x)
19375 int to_x;
19376 {
19377 struct frame *f;
19378 struct window *w = updated_window;
19379 int max_x, min_y, max_y;
19380 int from_x, from_y, to_y;
19381
19382 xassert (updated_window && updated_row);
19383 f = XFRAME (w->frame);
19384
19385 if (updated_row->full_width_p)
19386 max_x = WINDOW_TOTAL_WIDTH (w);
19387 else
19388 max_x = window_box_width (w, updated_area);
19389 max_y = window_text_bottom_y (w);
19390
19391 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19392 of window. For TO_X > 0, truncate to end of drawing area. */
19393 if (to_x == 0)
19394 return;
19395 else if (to_x < 0)
19396 to_x = max_x;
19397 else
19398 to_x = min (to_x, max_x);
19399
19400 to_y = min (max_y, output_cursor.y + updated_row->height);
19401
19402 /* Notice if the cursor will be cleared by this operation. */
19403 if (!updated_row->full_width_p)
19404 notice_overwritten_cursor (w, updated_area,
19405 output_cursor.x, -1,
19406 updated_row->y,
19407 MATRIX_ROW_BOTTOM_Y (updated_row));
19408
19409 from_x = output_cursor.x;
19410
19411 /* Translate to frame coordinates. */
19412 if (updated_row->full_width_p)
19413 {
19414 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19415 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19416 }
19417 else
19418 {
19419 int area_left = window_box_left (w, updated_area);
19420 from_x += area_left;
19421 to_x += area_left;
19422 }
19423
19424 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19425 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19426 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19427
19428 /* Prevent inadvertently clearing to end of the X window. */
19429 if (to_x > from_x && to_y > from_y)
19430 {
19431 BLOCK_INPUT;
19432 rif->clear_frame_area (f, from_x, from_y,
19433 to_x - from_x, to_y - from_y);
19434 UNBLOCK_INPUT;
19435 }
19436 }
19437
19438 #endif /* HAVE_WINDOW_SYSTEM */
19439
19440
19441 \f
19442 /***********************************************************************
19443 Cursor types
19444 ***********************************************************************/
19445
19446 /* Value is the internal representation of the specified cursor type
19447 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19448 of the bar cursor. */
19449
19450 static enum text_cursor_kinds
19451 get_specified_cursor_type (arg, width)
19452 Lisp_Object arg;
19453 int *width;
19454 {
19455 enum text_cursor_kinds type;
19456
19457 if (NILP (arg))
19458 return NO_CURSOR;
19459
19460 if (EQ (arg, Qbox))
19461 return FILLED_BOX_CURSOR;
19462
19463 if (EQ (arg, Qhollow))
19464 return HOLLOW_BOX_CURSOR;
19465
19466 if (EQ (arg, Qbar))
19467 {
19468 *width = 2;
19469 return BAR_CURSOR;
19470 }
19471
19472 if (CONSP (arg)
19473 && EQ (XCAR (arg), Qbar)
19474 && INTEGERP (XCDR (arg))
19475 && XINT (XCDR (arg)) >= 0)
19476 {
19477 *width = XINT (XCDR (arg));
19478 return BAR_CURSOR;
19479 }
19480
19481 if (EQ (arg, Qhbar))
19482 {
19483 *width = 2;
19484 return HBAR_CURSOR;
19485 }
19486
19487 if (CONSP (arg)
19488 && EQ (XCAR (arg), Qhbar)
19489 && INTEGERP (XCDR (arg))
19490 && XINT (XCDR (arg)) >= 0)
19491 {
19492 *width = XINT (XCDR (arg));
19493 return HBAR_CURSOR;
19494 }
19495
19496 /* Treat anything unknown as "hollow box cursor".
19497 It was bad to signal an error; people have trouble fixing
19498 .Xdefaults with Emacs, when it has something bad in it. */
19499 type = HOLLOW_BOX_CURSOR;
19500
19501 return type;
19502 }
19503
19504 /* Set the default cursor types for specified frame. */
19505 void
19506 set_frame_cursor_types (f, arg)
19507 struct frame *f;
19508 Lisp_Object arg;
19509 {
19510 int width;
19511 Lisp_Object tem;
19512
19513 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19514 FRAME_CURSOR_WIDTH (f) = width;
19515
19516 /* By default, set up the blink-off state depending on the on-state. */
19517
19518 tem = Fassoc (arg, Vblink_cursor_alist);
19519 if (!NILP (tem))
19520 {
19521 FRAME_BLINK_OFF_CURSOR (f)
19522 = get_specified_cursor_type (XCDR (tem), &width);
19523 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19524 }
19525 else
19526 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19527 }
19528
19529
19530 /* Return the cursor we want to be displayed in window W. Return
19531 width of bar/hbar cursor through WIDTH arg. Return with
19532 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19533 (i.e. if the `system caret' should track this cursor).
19534
19535 In a mini-buffer window, we want the cursor only to appear if we
19536 are reading input from this window. For the selected window, we
19537 want the cursor type given by the frame parameter or buffer local
19538 setting of cursor-type. If explicitly marked off, draw no cursor.
19539 In all other cases, we want a hollow box cursor. */
19540
19541 static enum text_cursor_kinds
19542 get_window_cursor_type (w, glyph, width, active_cursor)
19543 struct window *w;
19544 struct glyph *glyph;
19545 int *width;
19546 int *active_cursor;
19547 {
19548 struct frame *f = XFRAME (w->frame);
19549 struct buffer *b = XBUFFER (w->buffer);
19550 int cursor_type = DEFAULT_CURSOR;
19551 Lisp_Object alt_cursor;
19552 int non_selected = 0;
19553
19554 *active_cursor = 1;
19555
19556 /* Echo area */
19557 if (cursor_in_echo_area
19558 && FRAME_HAS_MINIBUF_P (f)
19559 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19560 {
19561 if (w == XWINDOW (echo_area_window))
19562 {
19563 *width = FRAME_CURSOR_WIDTH (f);
19564 return FRAME_DESIRED_CURSOR (f);
19565 }
19566
19567 *active_cursor = 0;
19568 non_selected = 1;
19569 }
19570
19571 /* Nonselected window or nonselected frame. */
19572 else if (w != XWINDOW (f->selected_window)
19573 #ifdef HAVE_WINDOW_SYSTEM
19574 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19575 #endif
19576 )
19577 {
19578 *active_cursor = 0;
19579
19580 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19581 return NO_CURSOR;
19582
19583 non_selected = 1;
19584 }
19585
19586 /* Never display a cursor in a window in which cursor-type is nil. */
19587 if (NILP (b->cursor_type))
19588 return NO_CURSOR;
19589
19590 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19591 if (non_selected)
19592 {
19593 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19594 return get_specified_cursor_type (alt_cursor, width);
19595 }
19596
19597 /* Get the normal cursor type for this window. */
19598 if (EQ (b->cursor_type, Qt))
19599 {
19600 cursor_type = FRAME_DESIRED_CURSOR (f);
19601 *width = FRAME_CURSOR_WIDTH (f);
19602 }
19603 else
19604 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19605
19606 /* Use normal cursor if not blinked off. */
19607 if (!w->cursor_off_p)
19608 {
19609 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19610 if (cursor_type == FILLED_BOX_CURSOR)
19611 cursor_type = HOLLOW_BOX_CURSOR;
19612 }
19613 return cursor_type;
19614 }
19615
19616 /* Cursor is blinked off, so determine how to "toggle" it. */
19617
19618 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19619 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19620 return get_specified_cursor_type (XCDR (alt_cursor), width);
19621
19622 /* Then see if frame has specified a specific blink off cursor type. */
19623 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19624 {
19625 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19626 return FRAME_BLINK_OFF_CURSOR (f);
19627 }
19628
19629 #if 0
19630 /* Some people liked having a permanently visible blinking cursor,
19631 while others had very strong opinions against it. So it was
19632 decided to remove it. KFS 2003-09-03 */
19633
19634 /* Finally perform built-in cursor blinking:
19635 filled box <-> hollow box
19636 wide [h]bar <-> narrow [h]bar
19637 narrow [h]bar <-> no cursor
19638 other type <-> no cursor */
19639
19640 if (cursor_type == FILLED_BOX_CURSOR)
19641 return HOLLOW_BOX_CURSOR;
19642
19643 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19644 {
19645 *width = 1;
19646 return cursor_type;
19647 }
19648 #endif
19649
19650 return NO_CURSOR;
19651 }
19652
19653
19654 #ifdef HAVE_WINDOW_SYSTEM
19655
19656 /* Notice when the text cursor of window W has been completely
19657 overwritten by a drawing operation that outputs glyphs in AREA
19658 starting at X0 and ending at X1 in the line starting at Y0 and
19659 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19660 the rest of the line after X0 has been written. Y coordinates
19661 are window-relative. */
19662
19663 static void
19664 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19665 struct window *w;
19666 enum glyph_row_area area;
19667 int x0, y0, x1, y1;
19668 {
19669 int cx0, cx1, cy0, cy1;
19670 struct glyph_row *row;
19671
19672 if (!w->phys_cursor_on_p)
19673 return;
19674 if (area != TEXT_AREA)
19675 return;
19676
19677 row = w->current_matrix->rows + w->phys_cursor.vpos;
19678 if (!row->displays_text_p)
19679 return;
19680
19681 if (row->cursor_in_fringe_p)
19682 {
19683 row->cursor_in_fringe_p = 0;
19684 draw_fringe_bitmap (w, row, 0);
19685 w->phys_cursor_on_p = 0;
19686 return;
19687 }
19688
19689 cx0 = w->phys_cursor.x;
19690 cx1 = cx0 + w->phys_cursor_width;
19691 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19692 return;
19693
19694 /* The cursor image will be completely removed from the
19695 screen if the output area intersects the cursor area in
19696 y-direction. When we draw in [y0 y1[, and some part of
19697 the cursor is at y < y0, that part must have been drawn
19698 before. When scrolling, the cursor is erased before
19699 actually scrolling, so we don't come here. When not
19700 scrolling, the rows above the old cursor row must have
19701 changed, and in this case these rows must have written
19702 over the cursor image.
19703
19704 Likewise if part of the cursor is below y1, with the
19705 exception of the cursor being in the first blank row at
19706 the buffer and window end because update_text_area
19707 doesn't draw that row. (Except when it does, but
19708 that's handled in update_text_area.) */
19709
19710 cy0 = w->phys_cursor.y;
19711 cy1 = cy0 + w->phys_cursor_height;
19712 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19713 return;
19714
19715 w->phys_cursor_on_p = 0;
19716 }
19717
19718 #endif /* HAVE_WINDOW_SYSTEM */
19719
19720 \f
19721 /************************************************************************
19722 Mouse Face
19723 ************************************************************************/
19724
19725 #ifdef HAVE_WINDOW_SYSTEM
19726
19727 /* EXPORT for RIF:
19728 Fix the display of area AREA of overlapping row ROW in window W. */
19729
19730 void
19731 x_fix_overlapping_area (w, row, area)
19732 struct window *w;
19733 struct glyph_row *row;
19734 enum glyph_row_area area;
19735 {
19736 int i, x;
19737
19738 BLOCK_INPUT;
19739
19740 x = 0;
19741 for (i = 0; i < row->used[area];)
19742 {
19743 if (row->glyphs[area][i].overlaps_vertically_p)
19744 {
19745 int start = i, start_x = x;
19746
19747 do
19748 {
19749 x += row->glyphs[area][i].pixel_width;
19750 ++i;
19751 }
19752 while (i < row->used[area]
19753 && row->glyphs[area][i].overlaps_vertically_p);
19754
19755 draw_glyphs (w, start_x, row, area,
19756 start, i,
19757 DRAW_NORMAL_TEXT, 1);
19758 }
19759 else
19760 {
19761 x += row->glyphs[area][i].pixel_width;
19762 ++i;
19763 }
19764 }
19765
19766 UNBLOCK_INPUT;
19767 }
19768
19769
19770 /* EXPORT:
19771 Draw the cursor glyph of window W in glyph row ROW. See the
19772 comment of draw_glyphs for the meaning of HL. */
19773
19774 void
19775 draw_phys_cursor_glyph (w, row, hl)
19776 struct window *w;
19777 struct glyph_row *row;
19778 enum draw_glyphs_face hl;
19779 {
19780 /* If cursor hpos is out of bounds, don't draw garbage. This can
19781 happen in mini-buffer windows when switching between echo area
19782 glyphs and mini-buffer. */
19783 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19784 {
19785 int on_p = w->phys_cursor_on_p;
19786 int x1;
19787 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19788 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19789 hl, 0);
19790 w->phys_cursor_on_p = on_p;
19791
19792 if (hl == DRAW_CURSOR)
19793 w->phys_cursor_width = x1 - w->phys_cursor.x;
19794 /* When we erase the cursor, and ROW is overlapped by other
19795 rows, make sure that these overlapping parts of other rows
19796 are redrawn. */
19797 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19798 {
19799 if (row > w->current_matrix->rows
19800 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19801 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19802
19803 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19804 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19805 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19806 }
19807 }
19808 }
19809
19810
19811 /* EXPORT:
19812 Erase the image of a cursor of window W from the screen. */
19813
19814 void
19815 erase_phys_cursor (w)
19816 struct window *w;
19817 {
19818 struct frame *f = XFRAME (w->frame);
19819 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19820 int hpos = w->phys_cursor.hpos;
19821 int vpos = w->phys_cursor.vpos;
19822 int mouse_face_here_p = 0;
19823 struct glyph_matrix *active_glyphs = w->current_matrix;
19824 struct glyph_row *cursor_row;
19825 struct glyph *cursor_glyph;
19826 enum draw_glyphs_face hl;
19827
19828 /* No cursor displayed or row invalidated => nothing to do on the
19829 screen. */
19830 if (w->phys_cursor_type == NO_CURSOR)
19831 goto mark_cursor_off;
19832
19833 /* VPOS >= active_glyphs->nrows means that window has been resized.
19834 Don't bother to erase the cursor. */
19835 if (vpos >= active_glyphs->nrows)
19836 goto mark_cursor_off;
19837
19838 /* If row containing cursor is marked invalid, there is nothing we
19839 can do. */
19840 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19841 if (!cursor_row->enabled_p)
19842 goto mark_cursor_off;
19843
19844 /* If row is completely invisible, don't attempt to delete a cursor which
19845 isn't there. This can happen if cursor is at top of a window, and
19846 we switch to a buffer with a header line in that window. */
19847 if (cursor_row->visible_height <= 0)
19848 goto mark_cursor_off;
19849
19850 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19851 if (cursor_row->cursor_in_fringe_p)
19852 {
19853 cursor_row->cursor_in_fringe_p = 0;
19854 draw_fringe_bitmap (w, cursor_row, 0);
19855 goto mark_cursor_off;
19856 }
19857
19858 /* This can happen when the new row is shorter than the old one.
19859 In this case, either draw_glyphs or clear_end_of_line
19860 should have cleared the cursor. Note that we wouldn't be
19861 able to erase the cursor in this case because we don't have a
19862 cursor glyph at hand. */
19863 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19864 goto mark_cursor_off;
19865
19866 /* If the cursor is in the mouse face area, redisplay that when
19867 we clear the cursor. */
19868 if (! NILP (dpyinfo->mouse_face_window)
19869 && w == XWINDOW (dpyinfo->mouse_face_window)
19870 && (vpos > dpyinfo->mouse_face_beg_row
19871 || (vpos == dpyinfo->mouse_face_beg_row
19872 && hpos >= dpyinfo->mouse_face_beg_col))
19873 && (vpos < dpyinfo->mouse_face_end_row
19874 || (vpos == dpyinfo->mouse_face_end_row
19875 && hpos < dpyinfo->mouse_face_end_col))
19876 /* Don't redraw the cursor's spot in mouse face if it is at the
19877 end of a line (on a newline). The cursor appears there, but
19878 mouse highlighting does not. */
19879 && cursor_row->used[TEXT_AREA] > hpos)
19880 mouse_face_here_p = 1;
19881
19882 /* Maybe clear the display under the cursor. */
19883 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19884 {
19885 int x, y;
19886 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
19887
19888 cursor_glyph = get_phys_cursor_glyph (w);
19889 if (cursor_glyph == NULL)
19890 goto mark_cursor_off;
19891
19892 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
19893 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
19894
19895 rif->clear_frame_area (f, x, y,
19896 cursor_glyph->pixel_width, cursor_row->visible_height);
19897 }
19898
19899 /* Erase the cursor by redrawing the character underneath it. */
19900 if (mouse_face_here_p)
19901 hl = DRAW_MOUSE_FACE;
19902 else
19903 hl = DRAW_NORMAL_TEXT;
19904 draw_phys_cursor_glyph (w, cursor_row, hl);
19905
19906 mark_cursor_off:
19907 w->phys_cursor_on_p = 0;
19908 w->phys_cursor_type = NO_CURSOR;
19909 }
19910
19911
19912 /* EXPORT:
19913 Display or clear cursor of window W. If ON is zero, clear the
19914 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19915 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19916
19917 void
19918 display_and_set_cursor (w, on, hpos, vpos, x, y)
19919 struct window *w;
19920 int on, hpos, vpos, x, y;
19921 {
19922 struct frame *f = XFRAME (w->frame);
19923 int new_cursor_type;
19924 int new_cursor_width;
19925 int active_cursor;
19926 struct glyph_row *glyph_row;
19927 struct glyph *glyph;
19928
19929 /* This is pointless on invisible frames, and dangerous on garbaged
19930 windows and frames; in the latter case, the frame or window may
19931 be in the midst of changing its size, and x and y may be off the
19932 window. */
19933 if (! FRAME_VISIBLE_P (f)
19934 || FRAME_GARBAGED_P (f)
19935 || vpos >= w->current_matrix->nrows
19936 || hpos >= w->current_matrix->matrix_w)
19937 return;
19938
19939 /* If cursor is off and we want it off, return quickly. */
19940 if (!on && !w->phys_cursor_on_p)
19941 return;
19942
19943 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
19944 /* If cursor row is not enabled, we don't really know where to
19945 display the cursor. */
19946 if (!glyph_row->enabled_p)
19947 {
19948 w->phys_cursor_on_p = 0;
19949 return;
19950 }
19951
19952 glyph = NULL;
19953 if (!glyph_row->exact_window_width_line_p
19954 || hpos < glyph_row->used[TEXT_AREA])
19955 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
19956
19957 xassert (interrupt_input_blocked);
19958
19959 /* Set new_cursor_type to the cursor we want to be displayed. */
19960 new_cursor_type = get_window_cursor_type (w, glyph,
19961 &new_cursor_width, &active_cursor);
19962
19963 /* If cursor is currently being shown and we don't want it to be or
19964 it is in the wrong place, or the cursor type is not what we want,
19965 erase it. */
19966 if (w->phys_cursor_on_p
19967 && (!on
19968 || w->phys_cursor.x != x
19969 || w->phys_cursor.y != y
19970 || new_cursor_type != w->phys_cursor_type
19971 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19972 && new_cursor_width != w->phys_cursor_width)))
19973 erase_phys_cursor (w);
19974
19975 /* Don't check phys_cursor_on_p here because that flag is only set
19976 to zero in some cases where we know that the cursor has been
19977 completely erased, to avoid the extra work of erasing the cursor
19978 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19979 still not be visible, or it has only been partly erased. */
19980 if (on)
19981 {
19982 w->phys_cursor_ascent = glyph_row->ascent;
19983 w->phys_cursor_height = glyph_row->height;
19984
19985 /* Set phys_cursor_.* before x_draw_.* is called because some
19986 of them may need the information. */
19987 w->phys_cursor.x = x;
19988 w->phys_cursor.y = glyph_row->y;
19989 w->phys_cursor.hpos = hpos;
19990 w->phys_cursor.vpos = vpos;
19991 }
19992
19993 rif->draw_window_cursor (w, glyph_row, x, y,
19994 new_cursor_type, new_cursor_width,
19995 on, active_cursor);
19996 }
19997
19998
19999 /* Switch the display of W's cursor on or off, according to the value
20000 of ON. */
20001
20002 static void
20003 update_window_cursor (w, on)
20004 struct window *w;
20005 int on;
20006 {
20007 /* Don't update cursor in windows whose frame is in the process
20008 of being deleted. */
20009 if (w->current_matrix)
20010 {
20011 BLOCK_INPUT;
20012 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20013 w->phys_cursor.x, w->phys_cursor.y);
20014 UNBLOCK_INPUT;
20015 }
20016 }
20017
20018
20019 /* Call update_window_cursor with parameter ON_P on all leaf windows
20020 in the window tree rooted at W. */
20021
20022 static void
20023 update_cursor_in_window_tree (w, on_p)
20024 struct window *w;
20025 int on_p;
20026 {
20027 while (w)
20028 {
20029 if (!NILP (w->hchild))
20030 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20031 else if (!NILP (w->vchild))
20032 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20033 else
20034 update_window_cursor (w, on_p);
20035
20036 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20037 }
20038 }
20039
20040
20041 /* EXPORT:
20042 Display the cursor on window W, or clear it, according to ON_P.
20043 Don't change the cursor's position. */
20044
20045 void
20046 x_update_cursor (f, on_p)
20047 struct frame *f;
20048 int on_p;
20049 {
20050 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20051 }
20052
20053
20054 /* EXPORT:
20055 Clear the cursor of window W to background color, and mark the
20056 cursor as not shown. This is used when the text where the cursor
20057 is is about to be rewritten. */
20058
20059 void
20060 x_clear_cursor (w)
20061 struct window *w;
20062 {
20063 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20064 update_window_cursor (w, 0);
20065 }
20066
20067
20068 /* EXPORT:
20069 Display the active region described by mouse_face_* according to DRAW. */
20070
20071 void
20072 show_mouse_face (dpyinfo, draw)
20073 Display_Info *dpyinfo;
20074 enum draw_glyphs_face draw;
20075 {
20076 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20077 struct frame *f = XFRAME (WINDOW_FRAME (w));
20078
20079 if (/* If window is in the process of being destroyed, don't bother
20080 to do anything. */
20081 w->current_matrix != NULL
20082 /* Don't update mouse highlight if hidden */
20083 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20084 /* Recognize when we are called to operate on rows that don't exist
20085 anymore. This can happen when a window is split. */
20086 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20087 {
20088 int phys_cursor_on_p = w->phys_cursor_on_p;
20089 struct glyph_row *row, *first, *last;
20090
20091 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20092 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20093
20094 for (row = first; row <= last && row->enabled_p; ++row)
20095 {
20096 int start_hpos, end_hpos, start_x;
20097
20098 /* For all but the first row, the highlight starts at column 0. */
20099 if (row == first)
20100 {
20101 start_hpos = dpyinfo->mouse_face_beg_col;
20102 start_x = dpyinfo->mouse_face_beg_x;
20103 }
20104 else
20105 {
20106 start_hpos = 0;
20107 start_x = 0;
20108 }
20109
20110 if (row == last)
20111 end_hpos = dpyinfo->mouse_face_end_col;
20112 else
20113 end_hpos = row->used[TEXT_AREA];
20114
20115 if (end_hpos > start_hpos)
20116 {
20117 draw_glyphs (w, start_x, row, TEXT_AREA,
20118 start_hpos, end_hpos,
20119 draw, 0);
20120
20121 row->mouse_face_p
20122 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20123 }
20124 }
20125
20126 /* When we've written over the cursor, arrange for it to
20127 be displayed again. */
20128 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20129 {
20130 BLOCK_INPUT;
20131 display_and_set_cursor (w, 1,
20132 w->phys_cursor.hpos, w->phys_cursor.vpos,
20133 w->phys_cursor.x, w->phys_cursor.y);
20134 UNBLOCK_INPUT;
20135 }
20136 }
20137
20138 /* Change the mouse cursor. */
20139 if (draw == DRAW_NORMAL_TEXT)
20140 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20141 else if (draw == DRAW_MOUSE_FACE)
20142 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20143 else
20144 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20145 }
20146
20147 /* EXPORT:
20148 Clear out the mouse-highlighted active region.
20149 Redraw it un-highlighted first. Value is non-zero if mouse
20150 face was actually drawn unhighlighted. */
20151
20152 int
20153 clear_mouse_face (dpyinfo)
20154 Display_Info *dpyinfo;
20155 {
20156 int cleared = 0;
20157
20158 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20159 {
20160 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20161 cleared = 1;
20162 }
20163
20164 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20165 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20166 dpyinfo->mouse_face_window = Qnil;
20167 dpyinfo->mouse_face_overlay = Qnil;
20168 return cleared;
20169 }
20170
20171
20172 /* EXPORT:
20173 Non-zero if physical cursor of window W is within mouse face. */
20174
20175 int
20176 cursor_in_mouse_face_p (w)
20177 struct window *w;
20178 {
20179 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20180 int in_mouse_face = 0;
20181
20182 if (WINDOWP (dpyinfo->mouse_face_window)
20183 && XWINDOW (dpyinfo->mouse_face_window) == w)
20184 {
20185 int hpos = w->phys_cursor.hpos;
20186 int vpos = w->phys_cursor.vpos;
20187
20188 if (vpos >= dpyinfo->mouse_face_beg_row
20189 && vpos <= dpyinfo->mouse_face_end_row
20190 && (vpos > dpyinfo->mouse_face_beg_row
20191 || hpos >= dpyinfo->mouse_face_beg_col)
20192 && (vpos < dpyinfo->mouse_face_end_row
20193 || hpos < dpyinfo->mouse_face_end_col
20194 || dpyinfo->mouse_face_past_end))
20195 in_mouse_face = 1;
20196 }
20197
20198 return in_mouse_face;
20199 }
20200
20201
20202
20203 \f
20204 /* Find the glyph matrix position of buffer position CHARPOS in window
20205 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20206 current glyphs must be up to date. If CHARPOS is above window
20207 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20208 of last line in W. In the row containing CHARPOS, stop before glyphs
20209 having STOP as object. */
20210
20211 #if 1 /* This is a version of fast_find_position that's more correct
20212 in the presence of hscrolling, for example. I didn't install
20213 it right away because the problem fixed is minor, it failed
20214 in 20.x as well, and I think it's too risky to install
20215 so near the release of 21.1. 2001-09-25 gerd. */
20216
20217 static int
20218 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20219 struct window *w;
20220 int charpos;
20221 int *hpos, *vpos, *x, *y;
20222 Lisp_Object stop;
20223 {
20224 struct glyph_row *row, *first;
20225 struct glyph *glyph, *end;
20226 int past_end = 0;
20227
20228 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20229 row = row_containing_pos (w, charpos, first, NULL, 0);
20230 if (row == NULL)
20231 {
20232 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20233 {
20234 *x = *y = *hpos = *vpos = 0;
20235 return 1;
20236 }
20237 else
20238 {
20239 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20240 past_end = 1;
20241 }
20242 }
20243
20244 *x = row->x;
20245 *y = row->y;
20246 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20247
20248 glyph = row->glyphs[TEXT_AREA];
20249 end = glyph + row->used[TEXT_AREA];
20250
20251 /* Skip over glyphs not having an object at the start of the row.
20252 These are special glyphs like truncation marks on terminal
20253 frames. */
20254 if (row->displays_text_p)
20255 while (glyph < end
20256 && INTEGERP (glyph->object)
20257 && !EQ (stop, glyph->object)
20258 && glyph->charpos < 0)
20259 {
20260 *x += glyph->pixel_width;
20261 ++glyph;
20262 }
20263
20264 while (glyph < end
20265 && !INTEGERP (glyph->object)
20266 && !EQ (stop, glyph->object)
20267 && (!BUFFERP (glyph->object)
20268 || glyph->charpos < charpos))
20269 {
20270 *x += glyph->pixel_width;
20271 ++glyph;
20272 }
20273
20274 *hpos = glyph - row->glyphs[TEXT_AREA];
20275 return !past_end;
20276 }
20277
20278 #else /* not 1 */
20279
20280 static int
20281 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20282 struct window *w;
20283 int pos;
20284 int *hpos, *vpos, *x, *y;
20285 Lisp_Object stop;
20286 {
20287 int i;
20288 int lastcol;
20289 int maybe_next_line_p = 0;
20290 int line_start_position;
20291 int yb = window_text_bottom_y (w);
20292 struct glyph_row *row, *best_row;
20293 int row_vpos, best_row_vpos;
20294 int current_x;
20295
20296 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20297 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20298
20299 while (row->y < yb)
20300 {
20301 if (row->used[TEXT_AREA])
20302 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20303 else
20304 line_start_position = 0;
20305
20306 if (line_start_position > pos)
20307 break;
20308 /* If the position sought is the end of the buffer,
20309 don't include the blank lines at the bottom of the window. */
20310 else if (line_start_position == pos
20311 && pos == BUF_ZV (XBUFFER (w->buffer)))
20312 {
20313 maybe_next_line_p = 1;
20314 break;
20315 }
20316 else if (line_start_position > 0)
20317 {
20318 best_row = row;
20319 best_row_vpos = row_vpos;
20320 }
20321
20322 if (row->y + row->height >= yb)
20323 break;
20324
20325 ++row;
20326 ++row_vpos;
20327 }
20328
20329 /* Find the right column within BEST_ROW. */
20330 lastcol = 0;
20331 current_x = best_row->x;
20332 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20333 {
20334 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20335 int charpos = glyph->charpos;
20336
20337 if (BUFFERP (glyph->object))
20338 {
20339 if (charpos == pos)
20340 {
20341 *hpos = i;
20342 *vpos = best_row_vpos;
20343 *x = current_x;
20344 *y = best_row->y;
20345 return 1;
20346 }
20347 else if (charpos > pos)
20348 break;
20349 }
20350 else if (EQ (glyph->object, stop))
20351 break;
20352
20353 if (charpos > 0)
20354 lastcol = i;
20355 current_x += glyph->pixel_width;
20356 }
20357
20358 /* If we're looking for the end of the buffer,
20359 and we didn't find it in the line we scanned,
20360 use the start of the following line. */
20361 if (maybe_next_line_p)
20362 {
20363 ++best_row;
20364 ++best_row_vpos;
20365 lastcol = 0;
20366 current_x = best_row->x;
20367 }
20368
20369 *vpos = best_row_vpos;
20370 *hpos = lastcol + 1;
20371 *x = current_x;
20372 *y = best_row->y;
20373 return 0;
20374 }
20375
20376 #endif /* not 1 */
20377
20378
20379 /* Find the position of the glyph for position POS in OBJECT in
20380 window W's current matrix, and return in *X, *Y the pixel
20381 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20382
20383 RIGHT_P non-zero means return the position of the right edge of the
20384 glyph, RIGHT_P zero means return the left edge position.
20385
20386 If no glyph for POS exists in the matrix, return the position of
20387 the glyph with the next smaller position that is in the matrix, if
20388 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20389 exists in the matrix, return the position of the glyph with the
20390 next larger position in OBJECT.
20391
20392 Value is non-zero if a glyph was found. */
20393
20394 static int
20395 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20396 struct window *w;
20397 int pos;
20398 Lisp_Object object;
20399 int *hpos, *vpos, *x, *y;
20400 int right_p;
20401 {
20402 int yb = window_text_bottom_y (w);
20403 struct glyph_row *r;
20404 struct glyph *best_glyph = NULL;
20405 struct glyph_row *best_row = NULL;
20406 int best_x = 0;
20407
20408 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20409 r->enabled_p && r->y < yb;
20410 ++r)
20411 {
20412 struct glyph *g = r->glyphs[TEXT_AREA];
20413 struct glyph *e = g + r->used[TEXT_AREA];
20414 int gx;
20415
20416 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20417 if (EQ (g->object, object))
20418 {
20419 if (g->charpos == pos)
20420 {
20421 best_glyph = g;
20422 best_x = gx;
20423 best_row = r;
20424 goto found;
20425 }
20426 else if (best_glyph == NULL
20427 || ((abs (g->charpos - pos)
20428 < abs (best_glyph->charpos - pos))
20429 && (right_p
20430 ? g->charpos < pos
20431 : g->charpos > pos)))
20432 {
20433 best_glyph = g;
20434 best_x = gx;
20435 best_row = r;
20436 }
20437 }
20438 }
20439
20440 found:
20441
20442 if (best_glyph)
20443 {
20444 *x = best_x;
20445 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20446
20447 if (right_p)
20448 {
20449 *x += best_glyph->pixel_width;
20450 ++*hpos;
20451 }
20452
20453 *y = best_row->y;
20454 *vpos = best_row - w->current_matrix->rows;
20455 }
20456
20457 return best_glyph != NULL;
20458 }
20459
20460
20461 /* See if position X, Y is within a hot-spot of an image. */
20462
20463 static int
20464 on_hot_spot_p (hot_spot, x, y)
20465 Lisp_Object hot_spot;
20466 int x, y;
20467 {
20468 if (!CONSP (hot_spot))
20469 return 0;
20470
20471 if (EQ (XCAR (hot_spot), Qrect))
20472 {
20473 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20474 Lisp_Object rect = XCDR (hot_spot);
20475 Lisp_Object tem;
20476 if (!CONSP (rect))
20477 return 0;
20478 if (!CONSP (XCAR (rect)))
20479 return 0;
20480 if (!CONSP (XCDR (rect)))
20481 return 0;
20482 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20483 return 0;
20484 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20485 return 0;
20486 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20487 return 0;
20488 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20489 return 0;
20490 return 1;
20491 }
20492 else if (EQ (XCAR (hot_spot), Qcircle))
20493 {
20494 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20495 Lisp_Object circ = XCDR (hot_spot);
20496 Lisp_Object lr, lx0, ly0;
20497 if (CONSP (circ)
20498 && CONSP (XCAR (circ))
20499 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20500 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20501 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20502 {
20503 double r = XFLOATINT (lr);
20504 double dx = XINT (lx0) - x;
20505 double dy = XINT (ly0) - y;
20506 return (dx * dx + dy * dy <= r * r);
20507 }
20508 }
20509 else if (EQ (XCAR (hot_spot), Qpoly))
20510 {
20511 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20512 if (VECTORP (XCDR (hot_spot)))
20513 {
20514 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20515 Lisp_Object *poly = v->contents;
20516 int n = v->size;
20517 int i;
20518 int inside = 0;
20519 Lisp_Object lx, ly;
20520 int x0, y0;
20521
20522 /* Need an even number of coordinates, and at least 3 edges. */
20523 if (n < 6 || n & 1)
20524 return 0;
20525
20526 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20527 If count is odd, we are inside polygon. Pixels on edges
20528 may or may not be included depending on actual geometry of the
20529 polygon. */
20530 if ((lx = poly[n-2], !INTEGERP (lx))
20531 || (ly = poly[n-1], !INTEGERP (lx)))
20532 return 0;
20533 x0 = XINT (lx), y0 = XINT (ly);
20534 for (i = 0; i < n; i += 2)
20535 {
20536 int x1 = x0, y1 = y0;
20537 if ((lx = poly[i], !INTEGERP (lx))
20538 || (ly = poly[i+1], !INTEGERP (ly)))
20539 return 0;
20540 x0 = XINT (lx), y0 = XINT (ly);
20541
20542 /* Does this segment cross the X line? */
20543 if (x0 >= x)
20544 {
20545 if (x1 >= x)
20546 continue;
20547 }
20548 else if (x1 < x)
20549 continue;
20550 if (y > y0 && y > y1)
20551 continue;
20552 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20553 inside = !inside;
20554 }
20555 return inside;
20556 }
20557 }
20558 /* If we don't understand the format, pretend we're not in the hot-spot. */
20559 return 0;
20560 }
20561
20562 Lisp_Object
20563 find_hot_spot (map, x, y)
20564 Lisp_Object map;
20565 int x, y;
20566 {
20567 while (CONSP (map))
20568 {
20569 if (CONSP (XCAR (map))
20570 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20571 return XCAR (map);
20572 map = XCDR (map);
20573 }
20574
20575 return Qnil;
20576 }
20577
20578 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20579 3, 3, 0,
20580 doc: /* Lookup in image map MAP coordinates X and Y.
20581 An image map is an alist where each element has the format (AREA ID PLIST).
20582 An AREA is specified as either a rectangle, a circle, or a polygon:
20583 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20584 pixel coordinates of the upper left and bottom right corners.
20585 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20586 and the radius of the circle; r may be a float or integer.
20587 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20588 vector describes one corner in the polygon.
20589 Returns the alist element for the first matching AREA in MAP. */)
20590 (map, x, y)
20591 Lisp_Object map;
20592 Lisp_Object x, y;
20593 {
20594 if (NILP (map))
20595 return Qnil;
20596
20597 CHECK_NUMBER (x);
20598 CHECK_NUMBER (y);
20599
20600 return find_hot_spot (map, XINT (x), XINT (y));
20601 }
20602
20603
20604 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20605 static void
20606 define_frame_cursor1 (f, cursor, pointer)
20607 struct frame *f;
20608 Cursor cursor;
20609 Lisp_Object pointer;
20610 {
20611 if (!NILP (pointer))
20612 {
20613 if (EQ (pointer, Qarrow))
20614 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20615 else if (EQ (pointer, Qhand))
20616 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20617 else if (EQ (pointer, Qtext))
20618 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20619 else if (EQ (pointer, intern ("hdrag")))
20620 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20621 #ifdef HAVE_X_WINDOWS
20622 else if (EQ (pointer, intern ("vdrag")))
20623 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20624 #endif
20625 else if (EQ (pointer, intern ("hourglass")))
20626 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20627 else if (EQ (pointer, Qmodeline))
20628 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20629 else
20630 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20631 }
20632
20633 #ifndef HAVE_CARBON
20634 if (cursor != No_Cursor)
20635 #else
20636 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20637 #endif
20638 rif->define_frame_cursor (f, cursor);
20639 }
20640
20641 /* Take proper action when mouse has moved to the mode or header line
20642 or marginal area AREA of window W, x-position X and y-position Y.
20643 X is relative to the start of the text display area of W, so the
20644 width of bitmap areas and scroll bars must be subtracted to get a
20645 position relative to the start of the mode line. */
20646
20647 static void
20648 note_mode_line_or_margin_highlight (w, x, y, area)
20649 struct window *w;
20650 int x, y;
20651 enum window_part area;
20652 {
20653 struct frame *f = XFRAME (w->frame);
20654 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20655 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20656 Lisp_Object pointer = Qnil;
20657 int charpos, dx, dy, width, height;
20658 Lisp_Object string, object = Qnil;
20659 Lisp_Object pos, help;
20660
20661 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20662 string = mode_line_string (w, area, &x, &y, &charpos,
20663 &object, &dx, &dy, &width, &height);
20664 else
20665 {
20666 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20667 string = marginal_area_string (w, area, &x, &y, &charpos,
20668 &object, &dx, &dy, &width, &height);
20669 }
20670
20671 help = Qnil;
20672
20673 if (IMAGEP (object))
20674 {
20675 Lisp_Object image_map, hotspot;
20676 if ((image_map = Fplist_get (XCDR (object), QCmap),
20677 !NILP (image_map))
20678 && (hotspot = find_hot_spot (image_map, dx, dy),
20679 CONSP (hotspot))
20680 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20681 {
20682 Lisp_Object area_id, plist;
20683
20684 area_id = XCAR (hotspot);
20685 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20686 If so, we could look for mouse-enter, mouse-leave
20687 properties in PLIST (and do something...). */
20688 if ((plist = XCDR (hotspot), CONSP (plist)))
20689 {
20690 pointer = Fplist_get (plist, Qpointer);
20691 if (NILP (pointer))
20692 pointer = Qhand;
20693 help = Fplist_get (plist, Qhelp_echo);
20694 if (!NILP (help))
20695 {
20696 help_echo_string = help;
20697 /* Is this correct? ++kfs */
20698 XSETWINDOW (help_echo_window, w);
20699 help_echo_object = w->buffer;
20700 help_echo_pos = charpos;
20701 }
20702 }
20703 if (NILP (pointer))
20704 pointer = Fplist_get (XCDR (object), QCpointer);
20705 }
20706 }
20707
20708 if (STRINGP (string))
20709 {
20710 pos = make_number (charpos);
20711 /* If we're on a string with `help-echo' text property, arrange
20712 for the help to be displayed. This is done by setting the
20713 global variable help_echo_string to the help string. */
20714 help = Fget_text_property (pos, Qhelp_echo, string);
20715 if (!NILP (help))
20716 {
20717 help_echo_string = help;
20718 XSETWINDOW (help_echo_window, w);
20719 help_echo_object = string;
20720 help_echo_pos = charpos;
20721 }
20722
20723 if (NILP (pointer))
20724 pointer = Fget_text_property (pos, Qpointer, string);
20725
20726 /* Change the mouse pointer according to what is under X/Y. */
20727 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
20728 {
20729 Lisp_Object map;
20730 map = Fget_text_property (pos, Qlocal_map, string);
20731 if (!KEYMAPP (map))
20732 map = Fget_text_property (pos, Qkeymap, string);
20733 if (!KEYMAPP (map))
20734 cursor = dpyinfo->vertical_scroll_bar_cursor;
20735 }
20736 }
20737
20738 define_frame_cursor1 (f, cursor, pointer);
20739 }
20740
20741
20742 /* EXPORT:
20743 Take proper action when the mouse has moved to position X, Y on
20744 frame F as regards highlighting characters that have mouse-face
20745 properties. Also de-highlighting chars where the mouse was before.
20746 X and Y can be negative or out of range. */
20747
20748 void
20749 note_mouse_highlight (f, x, y)
20750 struct frame *f;
20751 int x, y;
20752 {
20753 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20754 enum window_part part;
20755 Lisp_Object window;
20756 struct window *w;
20757 Cursor cursor = No_Cursor;
20758 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20759 struct buffer *b;
20760
20761 /* When a menu is active, don't highlight because this looks odd. */
20762 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20763 if (popup_activated ())
20764 return;
20765 #endif
20766
20767 if (NILP (Vmouse_highlight)
20768 || !f->glyphs_initialized_p)
20769 return;
20770
20771 dpyinfo->mouse_face_mouse_x = x;
20772 dpyinfo->mouse_face_mouse_y = y;
20773 dpyinfo->mouse_face_mouse_frame = f;
20774
20775 if (dpyinfo->mouse_face_defer)
20776 return;
20777
20778 if (gc_in_progress)
20779 {
20780 dpyinfo->mouse_face_deferred_gc = 1;
20781 return;
20782 }
20783
20784 /* Which window is that in? */
20785 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20786
20787 /* If we were displaying active text in another window, clear that. */
20788 if (! EQ (window, dpyinfo->mouse_face_window))
20789 clear_mouse_face (dpyinfo);
20790
20791 /* Not on a window -> return. */
20792 if (!WINDOWP (window))
20793 return;
20794
20795 /* Reset help_echo_string. It will get recomputed below. */
20796 help_echo_string = Qnil;
20797
20798 /* Convert to window-relative pixel coordinates. */
20799 w = XWINDOW (window);
20800 frame_to_window_pixel_xy (w, &x, &y);
20801
20802 /* Handle tool-bar window differently since it doesn't display a
20803 buffer. */
20804 if (EQ (window, f->tool_bar_window))
20805 {
20806 note_tool_bar_highlight (f, x, y);
20807 return;
20808 }
20809
20810 /* Mouse is on the mode, header line or margin? */
20811 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20812 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20813 {
20814 note_mode_line_or_margin_highlight (w, x, y, part);
20815 return;
20816 }
20817
20818 if (part == ON_VERTICAL_BORDER)
20819 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20820 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
20821 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20822 else
20823 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20824
20825 /* Are we in a window whose display is up to date?
20826 And verify the buffer's text has not changed. */
20827 b = XBUFFER (w->buffer);
20828 if (part == ON_TEXT
20829 && EQ (w->window_end_valid, w->buffer)
20830 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20831 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20832 {
20833 int hpos, vpos, pos, i, dx, dy, area;
20834 struct glyph *glyph;
20835 Lisp_Object object;
20836 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20837 Lisp_Object *overlay_vec = NULL;
20838 int noverlays;
20839 struct buffer *obuf;
20840 int obegv, ozv, same_region;
20841
20842 /* Find the glyph under X/Y. */
20843 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20844
20845 /* Look for :pointer property on image. */
20846 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20847 {
20848 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20849 if (img != NULL && IMAGEP (img->spec))
20850 {
20851 Lisp_Object image_map, hotspot;
20852 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20853 !NILP (image_map))
20854 && (hotspot = find_hot_spot (image_map,
20855 glyph->slice.x + dx,
20856 glyph->slice.y + dy),
20857 CONSP (hotspot))
20858 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20859 {
20860 Lisp_Object area_id, plist;
20861
20862 area_id = XCAR (hotspot);
20863 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20864 If so, we could look for mouse-enter, mouse-leave
20865 properties in PLIST (and do something...). */
20866 if ((plist = XCDR (hotspot), CONSP (plist)))
20867 {
20868 pointer = Fplist_get (plist, Qpointer);
20869 if (NILP (pointer))
20870 pointer = Qhand;
20871 help_echo_string = Fplist_get (plist, Qhelp_echo);
20872 if (!NILP (help_echo_string))
20873 {
20874 help_echo_window = window;
20875 help_echo_object = glyph->object;
20876 help_echo_pos = glyph->charpos;
20877 }
20878 }
20879 }
20880 if (NILP (pointer))
20881 pointer = Fplist_get (XCDR (img->spec), QCpointer);
20882 }
20883 }
20884
20885 /* Clear mouse face if X/Y not over text. */
20886 if (glyph == NULL
20887 || area != TEXT_AREA
20888 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
20889 {
20890 if (clear_mouse_face (dpyinfo))
20891 cursor = No_Cursor;
20892 if (NILP (pointer))
20893 {
20894 if (area != TEXT_AREA)
20895 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20896 else
20897 pointer = Vvoid_text_area_pointer;
20898 }
20899 goto set_cursor;
20900 }
20901
20902 pos = glyph->charpos;
20903 object = glyph->object;
20904 if (!STRINGP (object) && !BUFFERP (object))
20905 goto set_cursor;
20906
20907 /* If we get an out-of-range value, return now; avoid an error. */
20908 if (BUFFERP (object) && pos > BUF_Z (b))
20909 goto set_cursor;
20910
20911 /* Make the window's buffer temporarily current for
20912 overlays_at and compute_char_face. */
20913 obuf = current_buffer;
20914 current_buffer = b;
20915 obegv = BEGV;
20916 ozv = ZV;
20917 BEGV = BEG;
20918 ZV = Z;
20919
20920 /* Is this char mouse-active or does it have help-echo? */
20921 position = make_number (pos);
20922
20923 if (BUFFERP (object))
20924 {
20925 /* Put all the overlays we want in a vector in overlay_vec. */
20926 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
20927 /* Sort overlays into increasing priority order. */
20928 noverlays = sort_overlays (overlay_vec, noverlays, w);
20929 }
20930 else
20931 noverlays = 0;
20932
20933 same_region = (EQ (window, dpyinfo->mouse_face_window)
20934 && vpos >= dpyinfo->mouse_face_beg_row
20935 && vpos <= dpyinfo->mouse_face_end_row
20936 && (vpos > dpyinfo->mouse_face_beg_row
20937 || hpos >= dpyinfo->mouse_face_beg_col)
20938 && (vpos < dpyinfo->mouse_face_end_row
20939 || hpos < dpyinfo->mouse_face_end_col
20940 || dpyinfo->mouse_face_past_end));
20941
20942 if (same_region)
20943 cursor = No_Cursor;
20944
20945 /* Check mouse-face highlighting. */
20946 if (! same_region
20947 /* If there exists an overlay with mouse-face overlapping
20948 the one we are currently highlighting, we have to
20949 check if we enter the overlapping overlay, and then
20950 highlight only that. */
20951 || (OVERLAYP (dpyinfo->mouse_face_overlay)
20952 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
20953 {
20954 /* Find the highest priority overlay that has a mouse-face
20955 property. */
20956 overlay = Qnil;
20957 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
20958 {
20959 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
20960 if (!NILP (mouse_face))
20961 overlay = overlay_vec[i];
20962 }
20963
20964 /* If we're actually highlighting the same overlay as
20965 before, there's no need to do that again. */
20966 if (!NILP (overlay)
20967 && EQ (overlay, dpyinfo->mouse_face_overlay))
20968 goto check_help_echo;
20969
20970 dpyinfo->mouse_face_overlay = overlay;
20971
20972 /* Clear the display of the old active region, if any. */
20973 if (clear_mouse_face (dpyinfo))
20974 cursor = No_Cursor;
20975
20976 /* If no overlay applies, get a text property. */
20977 if (NILP (overlay))
20978 mouse_face = Fget_text_property (position, Qmouse_face, object);
20979
20980 /* Handle the overlay case. */
20981 if (!NILP (overlay))
20982 {
20983 /* Find the range of text around this char that
20984 should be active. */
20985 Lisp_Object before, after;
20986 int ignore;
20987
20988 before = Foverlay_start (overlay);
20989 after = Foverlay_end (overlay);
20990 /* Record this as the current active region. */
20991 fast_find_position (w, XFASTINT (before),
20992 &dpyinfo->mouse_face_beg_col,
20993 &dpyinfo->mouse_face_beg_row,
20994 &dpyinfo->mouse_face_beg_x,
20995 &dpyinfo->mouse_face_beg_y, Qnil);
20996
20997 dpyinfo->mouse_face_past_end
20998 = !fast_find_position (w, XFASTINT (after),
20999 &dpyinfo->mouse_face_end_col,
21000 &dpyinfo->mouse_face_end_row,
21001 &dpyinfo->mouse_face_end_x,
21002 &dpyinfo->mouse_face_end_y, Qnil);
21003 dpyinfo->mouse_face_window = window;
21004
21005 dpyinfo->mouse_face_face_id
21006 = face_at_buffer_position (w, pos, 0, 0,
21007 &ignore, pos + 1,
21008 !dpyinfo->mouse_face_hidden);
21009
21010 /* Display it as active. */
21011 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21012 cursor = No_Cursor;
21013 }
21014 /* Handle the text property case. */
21015 else if (!NILP (mouse_face) && BUFFERP (object))
21016 {
21017 /* Find the range of text around this char that
21018 should be active. */
21019 Lisp_Object before, after, beginning, end;
21020 int ignore;
21021
21022 beginning = Fmarker_position (w->start);
21023 end = make_number (BUF_Z (XBUFFER (object))
21024 - XFASTINT (w->window_end_pos));
21025 before
21026 = Fprevious_single_property_change (make_number (pos + 1),
21027 Qmouse_face,
21028 object, beginning);
21029 after
21030 = Fnext_single_property_change (position, Qmouse_face,
21031 object, end);
21032
21033 /* Record this as the current active region. */
21034 fast_find_position (w, XFASTINT (before),
21035 &dpyinfo->mouse_face_beg_col,
21036 &dpyinfo->mouse_face_beg_row,
21037 &dpyinfo->mouse_face_beg_x,
21038 &dpyinfo->mouse_face_beg_y, Qnil);
21039 dpyinfo->mouse_face_past_end
21040 = !fast_find_position (w, XFASTINT (after),
21041 &dpyinfo->mouse_face_end_col,
21042 &dpyinfo->mouse_face_end_row,
21043 &dpyinfo->mouse_face_end_x,
21044 &dpyinfo->mouse_face_end_y, Qnil);
21045 dpyinfo->mouse_face_window = window;
21046
21047 if (BUFFERP (object))
21048 dpyinfo->mouse_face_face_id
21049 = face_at_buffer_position (w, pos, 0, 0,
21050 &ignore, pos + 1,
21051 !dpyinfo->mouse_face_hidden);
21052
21053 /* Display it as active. */
21054 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21055 cursor = No_Cursor;
21056 }
21057 else if (!NILP (mouse_face) && STRINGP (object))
21058 {
21059 Lisp_Object b, e;
21060 int ignore;
21061
21062 b = Fprevious_single_property_change (make_number (pos + 1),
21063 Qmouse_face,
21064 object, Qnil);
21065 e = Fnext_single_property_change (position, Qmouse_face,
21066 object, Qnil);
21067 if (NILP (b))
21068 b = make_number (0);
21069 if (NILP (e))
21070 e = make_number (SCHARS (object) - 1);
21071 fast_find_string_pos (w, XINT (b), object,
21072 &dpyinfo->mouse_face_beg_col,
21073 &dpyinfo->mouse_face_beg_row,
21074 &dpyinfo->mouse_face_beg_x,
21075 &dpyinfo->mouse_face_beg_y, 0);
21076 fast_find_string_pos (w, XINT (e), object,
21077 &dpyinfo->mouse_face_end_col,
21078 &dpyinfo->mouse_face_end_row,
21079 &dpyinfo->mouse_face_end_x,
21080 &dpyinfo->mouse_face_end_y, 1);
21081 dpyinfo->mouse_face_past_end = 0;
21082 dpyinfo->mouse_face_window = window;
21083 dpyinfo->mouse_face_face_id
21084 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21085 glyph->face_id, 1);
21086 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21087 cursor = No_Cursor;
21088 }
21089 else if (STRINGP (object) && NILP (mouse_face))
21090 {
21091 /* A string which doesn't have mouse-face, but
21092 the text ``under'' it might have. */
21093 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21094 int start = MATRIX_ROW_START_CHARPOS (r);
21095
21096 pos = string_buffer_position (w, object, start);
21097 if (pos > 0)
21098 mouse_face = get_char_property_and_overlay (make_number (pos),
21099 Qmouse_face,
21100 w->buffer,
21101 &overlay);
21102 if (!NILP (mouse_face) && !NILP (overlay))
21103 {
21104 Lisp_Object before = Foverlay_start (overlay);
21105 Lisp_Object after = Foverlay_end (overlay);
21106 int ignore;
21107
21108 /* Note that we might not be able to find position
21109 BEFORE in the glyph matrix if the overlay is
21110 entirely covered by a `display' property. In
21111 this case, we overshoot. So let's stop in
21112 the glyph matrix before glyphs for OBJECT. */
21113 fast_find_position (w, XFASTINT (before),
21114 &dpyinfo->mouse_face_beg_col,
21115 &dpyinfo->mouse_face_beg_row,
21116 &dpyinfo->mouse_face_beg_x,
21117 &dpyinfo->mouse_face_beg_y,
21118 object);
21119
21120 dpyinfo->mouse_face_past_end
21121 = !fast_find_position (w, XFASTINT (after),
21122 &dpyinfo->mouse_face_end_col,
21123 &dpyinfo->mouse_face_end_row,
21124 &dpyinfo->mouse_face_end_x,
21125 &dpyinfo->mouse_face_end_y,
21126 Qnil);
21127 dpyinfo->mouse_face_window = window;
21128 dpyinfo->mouse_face_face_id
21129 = face_at_buffer_position (w, pos, 0, 0,
21130 &ignore, pos + 1,
21131 !dpyinfo->mouse_face_hidden);
21132
21133 /* Display it as active. */
21134 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21135 cursor = No_Cursor;
21136 }
21137 }
21138 }
21139
21140 check_help_echo:
21141
21142 /* Look for a `help-echo' property. */
21143 if (NILP (help_echo_string)) {
21144 Lisp_Object help, overlay;
21145
21146 /* Check overlays first. */
21147 help = overlay = Qnil;
21148 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21149 {
21150 overlay = overlay_vec[i];
21151 help = Foverlay_get (overlay, Qhelp_echo);
21152 }
21153
21154 if (!NILP (help))
21155 {
21156 help_echo_string = help;
21157 help_echo_window = window;
21158 help_echo_object = overlay;
21159 help_echo_pos = pos;
21160 }
21161 else
21162 {
21163 Lisp_Object object = glyph->object;
21164 int charpos = glyph->charpos;
21165
21166 /* Try text properties. */
21167 if (STRINGP (object)
21168 && charpos >= 0
21169 && charpos < SCHARS (object))
21170 {
21171 help = Fget_text_property (make_number (charpos),
21172 Qhelp_echo, object);
21173 if (NILP (help))
21174 {
21175 /* If the string itself doesn't specify a help-echo,
21176 see if the buffer text ``under'' it does. */
21177 struct glyph_row *r
21178 = MATRIX_ROW (w->current_matrix, vpos);
21179 int start = MATRIX_ROW_START_CHARPOS (r);
21180 int pos = string_buffer_position (w, object, start);
21181 if (pos > 0)
21182 {
21183 help = Fget_char_property (make_number (pos),
21184 Qhelp_echo, w->buffer);
21185 if (!NILP (help))
21186 {
21187 charpos = pos;
21188 object = w->buffer;
21189 }
21190 }
21191 }
21192 }
21193 else if (BUFFERP (object)
21194 && charpos >= BEGV
21195 && charpos < ZV)
21196 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21197 object);
21198
21199 if (!NILP (help))
21200 {
21201 help_echo_string = help;
21202 help_echo_window = window;
21203 help_echo_object = object;
21204 help_echo_pos = charpos;
21205 }
21206 }
21207 }
21208
21209 /* Look for a `pointer' property. */
21210 if (NILP (pointer))
21211 {
21212 /* Check overlays first. */
21213 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21214 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21215
21216 if (NILP (pointer))
21217 {
21218 Lisp_Object object = glyph->object;
21219 int charpos = glyph->charpos;
21220
21221 /* Try text properties. */
21222 if (STRINGP (object)
21223 && charpos >= 0
21224 && charpos < SCHARS (object))
21225 {
21226 pointer = Fget_text_property (make_number (charpos),
21227 Qpointer, object);
21228 if (NILP (pointer))
21229 {
21230 /* If the string itself doesn't specify a pointer,
21231 see if the buffer text ``under'' it does. */
21232 struct glyph_row *r
21233 = MATRIX_ROW (w->current_matrix, vpos);
21234 int start = MATRIX_ROW_START_CHARPOS (r);
21235 int pos = string_buffer_position (w, object, start);
21236 if (pos > 0)
21237 pointer = Fget_char_property (make_number (pos),
21238 Qpointer, w->buffer);
21239 }
21240 }
21241 else if (BUFFERP (object)
21242 && charpos >= BEGV
21243 && charpos < ZV)
21244 pointer = Fget_text_property (make_number (charpos),
21245 Qpointer, object);
21246 }
21247 }
21248
21249 BEGV = obegv;
21250 ZV = ozv;
21251 current_buffer = obuf;
21252 }
21253
21254 set_cursor:
21255
21256 define_frame_cursor1 (f, cursor, pointer);
21257 }
21258
21259
21260 /* EXPORT for RIF:
21261 Clear any mouse-face on window W. This function is part of the
21262 redisplay interface, and is called from try_window_id and similar
21263 functions to ensure the mouse-highlight is off. */
21264
21265 void
21266 x_clear_window_mouse_face (w)
21267 struct window *w;
21268 {
21269 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21270 Lisp_Object window;
21271
21272 BLOCK_INPUT;
21273 XSETWINDOW (window, w);
21274 if (EQ (window, dpyinfo->mouse_face_window))
21275 clear_mouse_face (dpyinfo);
21276 UNBLOCK_INPUT;
21277 }
21278
21279
21280 /* EXPORT:
21281 Just discard the mouse face information for frame F, if any.
21282 This is used when the size of F is changed. */
21283
21284 void
21285 cancel_mouse_face (f)
21286 struct frame *f;
21287 {
21288 Lisp_Object window;
21289 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21290
21291 window = dpyinfo->mouse_face_window;
21292 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21293 {
21294 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21295 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21296 dpyinfo->mouse_face_window = Qnil;
21297 }
21298 }
21299
21300
21301 #endif /* HAVE_WINDOW_SYSTEM */
21302
21303 \f
21304 /***********************************************************************
21305 Exposure Events
21306 ***********************************************************************/
21307
21308 #ifdef HAVE_WINDOW_SYSTEM
21309
21310 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21311 which intersects rectangle R. R is in window-relative coordinates. */
21312
21313 static void
21314 expose_area (w, row, r, area)
21315 struct window *w;
21316 struct glyph_row *row;
21317 XRectangle *r;
21318 enum glyph_row_area area;
21319 {
21320 struct glyph *first = row->glyphs[area];
21321 struct glyph *end = row->glyphs[area] + row->used[area];
21322 struct glyph *last;
21323 int first_x, start_x, x;
21324
21325 if (area == TEXT_AREA && row->fill_line_p)
21326 /* If row extends face to end of line write the whole line. */
21327 draw_glyphs (w, 0, row, area,
21328 0, row->used[area],
21329 DRAW_NORMAL_TEXT, 0);
21330 else
21331 {
21332 /* Set START_X to the window-relative start position for drawing glyphs of
21333 AREA. The first glyph of the text area can be partially visible.
21334 The first glyphs of other areas cannot. */
21335 start_x = window_box_left_offset (w, area);
21336 x = start_x;
21337 if (area == TEXT_AREA)
21338 x += row->x;
21339
21340 /* Find the first glyph that must be redrawn. */
21341 while (first < end
21342 && x + first->pixel_width < r->x)
21343 {
21344 x += first->pixel_width;
21345 ++first;
21346 }
21347
21348 /* Find the last one. */
21349 last = first;
21350 first_x = x;
21351 while (last < end
21352 && x < r->x + r->width)
21353 {
21354 x += last->pixel_width;
21355 ++last;
21356 }
21357
21358 /* Repaint. */
21359 if (last > first)
21360 draw_glyphs (w, first_x - start_x, row, area,
21361 first - row->glyphs[area], last - row->glyphs[area],
21362 DRAW_NORMAL_TEXT, 0);
21363 }
21364 }
21365
21366
21367 /* Redraw the parts of the glyph row ROW on window W intersecting
21368 rectangle R. R is in window-relative coordinates. Value is
21369 non-zero if mouse-face was overwritten. */
21370
21371 static int
21372 expose_line (w, row, r)
21373 struct window *w;
21374 struct glyph_row *row;
21375 XRectangle *r;
21376 {
21377 xassert (row->enabled_p);
21378
21379 if (row->mode_line_p || w->pseudo_window_p)
21380 draw_glyphs (w, 0, row, TEXT_AREA,
21381 0, row->used[TEXT_AREA],
21382 DRAW_NORMAL_TEXT, 0);
21383 else
21384 {
21385 if (row->used[LEFT_MARGIN_AREA])
21386 expose_area (w, row, r, LEFT_MARGIN_AREA);
21387 if (row->used[TEXT_AREA])
21388 expose_area (w, row, r, TEXT_AREA);
21389 if (row->used[RIGHT_MARGIN_AREA])
21390 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21391 draw_row_fringe_bitmaps (w, row);
21392 }
21393
21394 return row->mouse_face_p;
21395 }
21396
21397
21398 /* Redraw those parts of glyphs rows during expose event handling that
21399 overlap other rows. Redrawing of an exposed line writes over parts
21400 of lines overlapping that exposed line; this function fixes that.
21401
21402 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21403 row in W's current matrix that is exposed and overlaps other rows.
21404 LAST_OVERLAPPING_ROW is the last such row. */
21405
21406 static void
21407 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21408 struct window *w;
21409 struct glyph_row *first_overlapping_row;
21410 struct glyph_row *last_overlapping_row;
21411 {
21412 struct glyph_row *row;
21413
21414 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21415 if (row->overlapping_p)
21416 {
21417 xassert (row->enabled_p && !row->mode_line_p);
21418
21419 if (row->used[LEFT_MARGIN_AREA])
21420 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21421
21422 if (row->used[TEXT_AREA])
21423 x_fix_overlapping_area (w, row, TEXT_AREA);
21424
21425 if (row->used[RIGHT_MARGIN_AREA])
21426 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21427 }
21428 }
21429
21430
21431 /* Return non-zero if W's cursor intersects rectangle R. */
21432
21433 static int
21434 phys_cursor_in_rect_p (w, r)
21435 struct window *w;
21436 XRectangle *r;
21437 {
21438 XRectangle cr, result;
21439 struct glyph *cursor_glyph;
21440
21441 cursor_glyph = get_phys_cursor_glyph (w);
21442 if (cursor_glyph)
21443 {
21444 /* r is relative to W's box, but w->phys_cursor.x is relative
21445 to left edge of W's TEXT area. Adjust it. */
21446 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21447 cr.y = w->phys_cursor.y;
21448 cr.width = cursor_glyph->pixel_width;
21449 cr.height = w->phys_cursor_height;
21450 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21451 I assume the effect is the same -- and this is portable. */
21452 return x_intersect_rectangles (&cr, r, &result);
21453 }
21454 else
21455 return 0;
21456 }
21457
21458
21459 /* EXPORT:
21460 Draw a vertical window border to the right of window W if W doesn't
21461 have vertical scroll bars. */
21462
21463 void
21464 x_draw_vertical_border (w)
21465 struct window *w;
21466 {
21467 /* We could do better, if we knew what type of scroll-bar the adjacent
21468 windows (on either side) have... But we don't :-(
21469 However, I think this works ok. ++KFS 2003-04-25 */
21470
21471 /* Redraw borders between horizontally adjacent windows. Don't
21472 do it for frames with vertical scroll bars because either the
21473 right scroll bar of a window, or the left scroll bar of its
21474 neighbor will suffice as a border. */
21475 if (!WINDOW_RIGHTMOST_P (w)
21476 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21477 {
21478 int x0, x1, y0, y1;
21479
21480 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21481 y1 -= 1;
21482
21483 rif->draw_vertical_window_border (w, x1, y0, y1);
21484 }
21485 else if (!WINDOW_LEFTMOST_P (w)
21486 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21487 {
21488 int x0, x1, y0, y1;
21489
21490 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21491 y1 -= 1;
21492
21493 rif->draw_vertical_window_border (w, x0, y0, y1);
21494 }
21495 }
21496
21497
21498 /* Redraw the part of window W intersection rectangle FR. Pixel
21499 coordinates in FR are frame-relative. Call this function with
21500 input blocked. Value is non-zero if the exposure overwrites
21501 mouse-face. */
21502
21503 static int
21504 expose_window (w, fr)
21505 struct window *w;
21506 XRectangle *fr;
21507 {
21508 struct frame *f = XFRAME (w->frame);
21509 XRectangle wr, r;
21510 int mouse_face_overwritten_p = 0;
21511
21512 /* If window is not yet fully initialized, do nothing. This can
21513 happen when toolkit scroll bars are used and a window is split.
21514 Reconfiguring the scroll bar will generate an expose for a newly
21515 created window. */
21516 if (w->current_matrix == NULL)
21517 return 0;
21518
21519 /* When we're currently updating the window, display and current
21520 matrix usually don't agree. Arrange for a thorough display
21521 later. */
21522 if (w == updated_window)
21523 {
21524 SET_FRAME_GARBAGED (f);
21525 return 0;
21526 }
21527
21528 /* Frame-relative pixel rectangle of W. */
21529 wr.x = WINDOW_LEFT_EDGE_X (w);
21530 wr.y = WINDOW_TOP_EDGE_Y (w);
21531 wr.width = WINDOW_TOTAL_WIDTH (w);
21532 wr.height = WINDOW_TOTAL_HEIGHT (w);
21533
21534 if (x_intersect_rectangles (fr, &wr, &r))
21535 {
21536 int yb = window_text_bottom_y (w);
21537 struct glyph_row *row;
21538 int cursor_cleared_p;
21539 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21540
21541 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21542 r.x, r.y, r.width, r.height));
21543
21544 /* Convert to window coordinates. */
21545 r.x -= WINDOW_LEFT_EDGE_X (w);
21546 r.y -= WINDOW_TOP_EDGE_Y (w);
21547
21548 /* Turn off the cursor. */
21549 if (!w->pseudo_window_p
21550 && phys_cursor_in_rect_p (w, &r))
21551 {
21552 x_clear_cursor (w);
21553 cursor_cleared_p = 1;
21554 }
21555 else
21556 cursor_cleared_p = 0;
21557
21558 /* Update lines intersecting rectangle R. */
21559 first_overlapping_row = last_overlapping_row = NULL;
21560 for (row = w->current_matrix->rows;
21561 row->enabled_p;
21562 ++row)
21563 {
21564 int y0 = row->y;
21565 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21566
21567 if ((y0 >= r.y && y0 < r.y + r.height)
21568 || (y1 > r.y && y1 < r.y + r.height)
21569 || (r.y >= y0 && r.y < y1)
21570 || (r.y + r.height > y0 && r.y + r.height < y1))
21571 {
21572 if (row->overlapping_p)
21573 {
21574 if (first_overlapping_row == NULL)
21575 first_overlapping_row = row;
21576 last_overlapping_row = row;
21577 }
21578
21579 if (expose_line (w, row, &r))
21580 mouse_face_overwritten_p = 1;
21581 }
21582
21583 if (y1 >= yb)
21584 break;
21585 }
21586
21587 /* Display the mode line if there is one. */
21588 if (WINDOW_WANTS_MODELINE_P (w)
21589 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21590 row->enabled_p)
21591 && row->y < r.y + r.height)
21592 {
21593 if (expose_line (w, row, &r))
21594 mouse_face_overwritten_p = 1;
21595 }
21596
21597 if (!w->pseudo_window_p)
21598 {
21599 /* Fix the display of overlapping rows. */
21600 if (first_overlapping_row)
21601 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21602
21603 /* Draw border between windows. */
21604 x_draw_vertical_border (w);
21605
21606 /* Turn the cursor on again. */
21607 if (cursor_cleared_p)
21608 update_window_cursor (w, 1);
21609 }
21610 }
21611
21612 #ifdef HAVE_CARBON
21613 /* Display scroll bar for this window. */
21614 if (!NILP (w->vertical_scroll_bar))
21615 {
21616 /* ++KFS:
21617 If this doesn't work here (maybe some header files are missing),
21618 make a function in macterm.c and call it to do the job! */
21619 ControlHandle ch
21620 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21621
21622 Draw1Control (ch);
21623 }
21624 #endif
21625
21626 return mouse_face_overwritten_p;
21627 }
21628
21629
21630
21631 /* Redraw (parts) of all windows in the window tree rooted at W that
21632 intersect R. R contains frame pixel coordinates. Value is
21633 non-zero if the exposure overwrites mouse-face. */
21634
21635 static int
21636 expose_window_tree (w, r)
21637 struct window *w;
21638 XRectangle *r;
21639 {
21640 struct frame *f = XFRAME (w->frame);
21641 int mouse_face_overwritten_p = 0;
21642
21643 while (w && !FRAME_GARBAGED_P (f))
21644 {
21645 if (!NILP (w->hchild))
21646 mouse_face_overwritten_p
21647 |= expose_window_tree (XWINDOW (w->hchild), r);
21648 else if (!NILP (w->vchild))
21649 mouse_face_overwritten_p
21650 |= expose_window_tree (XWINDOW (w->vchild), r);
21651 else
21652 mouse_face_overwritten_p |= expose_window (w, r);
21653
21654 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21655 }
21656
21657 return mouse_face_overwritten_p;
21658 }
21659
21660
21661 /* EXPORT:
21662 Redisplay an exposed area of frame F. X and Y are the upper-left
21663 corner of the exposed rectangle. W and H are width and height of
21664 the exposed area. All are pixel values. W or H zero means redraw
21665 the entire frame. */
21666
21667 void
21668 expose_frame (f, x, y, w, h)
21669 struct frame *f;
21670 int x, y, w, h;
21671 {
21672 XRectangle r;
21673 int mouse_face_overwritten_p = 0;
21674
21675 TRACE ((stderr, "expose_frame "));
21676
21677 /* No need to redraw if frame will be redrawn soon. */
21678 if (FRAME_GARBAGED_P (f))
21679 {
21680 TRACE ((stderr, " garbaged\n"));
21681 return;
21682 }
21683
21684 #ifdef HAVE_CARBON
21685 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21686 or deactivated here, for unknown reasons, activated scroll bars
21687 are shown in deactivated frames in some instances. */
21688 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21689 activate_scroll_bars (f);
21690 else
21691 deactivate_scroll_bars (f);
21692 #endif
21693
21694 /* If basic faces haven't been realized yet, there is no point in
21695 trying to redraw anything. This can happen when we get an expose
21696 event while Emacs is starting, e.g. by moving another window. */
21697 if (FRAME_FACE_CACHE (f) == NULL
21698 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21699 {
21700 TRACE ((stderr, " no faces\n"));
21701 return;
21702 }
21703
21704 if (w == 0 || h == 0)
21705 {
21706 r.x = r.y = 0;
21707 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21708 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21709 }
21710 else
21711 {
21712 r.x = x;
21713 r.y = y;
21714 r.width = w;
21715 r.height = h;
21716 }
21717
21718 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21719 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21720
21721 if (WINDOWP (f->tool_bar_window))
21722 mouse_face_overwritten_p
21723 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21724
21725 #ifdef HAVE_X_WINDOWS
21726 #ifndef MSDOS
21727 #ifndef USE_X_TOOLKIT
21728 if (WINDOWP (f->menu_bar_window))
21729 mouse_face_overwritten_p
21730 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21731 #endif /* not USE_X_TOOLKIT */
21732 #endif
21733 #endif
21734
21735 /* Some window managers support a focus-follows-mouse style with
21736 delayed raising of frames. Imagine a partially obscured frame,
21737 and moving the mouse into partially obscured mouse-face on that
21738 frame. The visible part of the mouse-face will be highlighted,
21739 then the WM raises the obscured frame. With at least one WM, KDE
21740 2.1, Emacs is not getting any event for the raising of the frame
21741 (even tried with SubstructureRedirectMask), only Expose events.
21742 These expose events will draw text normally, i.e. not
21743 highlighted. Which means we must redo the highlight here.
21744 Subsume it under ``we love X''. --gerd 2001-08-15 */
21745 /* Included in Windows version because Windows most likely does not
21746 do the right thing if any third party tool offers
21747 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21748 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21749 {
21750 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21751 if (f == dpyinfo->mouse_face_mouse_frame)
21752 {
21753 int x = dpyinfo->mouse_face_mouse_x;
21754 int y = dpyinfo->mouse_face_mouse_y;
21755 clear_mouse_face (dpyinfo);
21756 note_mouse_highlight (f, x, y);
21757 }
21758 }
21759 }
21760
21761
21762 /* EXPORT:
21763 Determine the intersection of two rectangles R1 and R2. Return
21764 the intersection in *RESULT. Value is non-zero if RESULT is not
21765 empty. */
21766
21767 int
21768 x_intersect_rectangles (r1, r2, result)
21769 XRectangle *r1, *r2, *result;
21770 {
21771 XRectangle *left, *right;
21772 XRectangle *upper, *lower;
21773 int intersection_p = 0;
21774
21775 /* Rearrange so that R1 is the left-most rectangle. */
21776 if (r1->x < r2->x)
21777 left = r1, right = r2;
21778 else
21779 left = r2, right = r1;
21780
21781 /* X0 of the intersection is right.x0, if this is inside R1,
21782 otherwise there is no intersection. */
21783 if (right->x <= left->x + left->width)
21784 {
21785 result->x = right->x;
21786
21787 /* The right end of the intersection is the minimum of the
21788 the right ends of left and right. */
21789 result->width = (min (left->x + left->width, right->x + right->width)
21790 - result->x);
21791
21792 /* Same game for Y. */
21793 if (r1->y < r2->y)
21794 upper = r1, lower = r2;
21795 else
21796 upper = r2, lower = r1;
21797
21798 /* The upper end of the intersection is lower.y0, if this is inside
21799 of upper. Otherwise, there is no intersection. */
21800 if (lower->y <= upper->y + upper->height)
21801 {
21802 result->y = lower->y;
21803
21804 /* The lower end of the intersection is the minimum of the lower
21805 ends of upper and lower. */
21806 result->height = (min (lower->y + lower->height,
21807 upper->y + upper->height)
21808 - result->y);
21809 intersection_p = 1;
21810 }
21811 }
21812
21813 return intersection_p;
21814 }
21815
21816 #endif /* HAVE_WINDOW_SYSTEM */
21817
21818 \f
21819 /***********************************************************************
21820 Initialization
21821 ***********************************************************************/
21822
21823 void
21824 syms_of_xdisp ()
21825 {
21826 Vwith_echo_area_save_vector = Qnil;
21827 staticpro (&Vwith_echo_area_save_vector);
21828
21829 Vmessage_stack = Qnil;
21830 staticpro (&Vmessage_stack);
21831
21832 Qinhibit_redisplay = intern ("inhibit-redisplay");
21833 staticpro (&Qinhibit_redisplay);
21834
21835 message_dolog_marker1 = Fmake_marker ();
21836 staticpro (&message_dolog_marker1);
21837 message_dolog_marker2 = Fmake_marker ();
21838 staticpro (&message_dolog_marker2);
21839 message_dolog_marker3 = Fmake_marker ();
21840 staticpro (&message_dolog_marker3);
21841
21842 #if GLYPH_DEBUG
21843 defsubr (&Sdump_frame_glyph_matrix);
21844 defsubr (&Sdump_glyph_matrix);
21845 defsubr (&Sdump_glyph_row);
21846 defsubr (&Sdump_tool_bar_row);
21847 defsubr (&Strace_redisplay);
21848 defsubr (&Strace_to_stderr);
21849 #endif
21850 #ifdef HAVE_WINDOW_SYSTEM
21851 defsubr (&Stool_bar_lines_needed);
21852 defsubr (&Slookup_image_map);
21853 #endif
21854 defsubr (&Sformat_mode_line);
21855
21856 staticpro (&Qmenu_bar_update_hook);
21857 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21858
21859 staticpro (&Qoverriding_terminal_local_map);
21860 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21861
21862 staticpro (&Qoverriding_local_map);
21863 Qoverriding_local_map = intern ("overriding-local-map");
21864
21865 staticpro (&Qwindow_scroll_functions);
21866 Qwindow_scroll_functions = intern ("window-scroll-functions");
21867
21868 staticpro (&Qredisplay_end_trigger_functions);
21869 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21870
21871 staticpro (&Qinhibit_point_motion_hooks);
21872 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21873
21874 QCdata = intern (":data");
21875 staticpro (&QCdata);
21876 Qdisplay = intern ("display");
21877 staticpro (&Qdisplay);
21878 Qspace_width = intern ("space-width");
21879 staticpro (&Qspace_width);
21880 Qraise = intern ("raise");
21881 staticpro (&Qraise);
21882 Qslice = intern ("slice");
21883 staticpro (&Qslice);
21884 Qspace = intern ("space");
21885 staticpro (&Qspace);
21886 Qmargin = intern ("margin");
21887 staticpro (&Qmargin);
21888 Qpointer = intern ("pointer");
21889 staticpro (&Qpointer);
21890 Qleft_margin = intern ("left-margin");
21891 staticpro (&Qleft_margin);
21892 Qright_margin = intern ("right-margin");
21893 staticpro (&Qright_margin);
21894 Qcenter = intern ("center");
21895 staticpro (&Qcenter);
21896 Qline_height = intern ("line-height");
21897 staticpro (&Qline_height);
21898 Qtotal = intern ("total");
21899 staticpro (&Qtotal);
21900 QCalign_to = intern (":align-to");
21901 staticpro (&QCalign_to);
21902 QCrelative_width = intern (":relative-width");
21903 staticpro (&QCrelative_width);
21904 QCrelative_height = intern (":relative-height");
21905 staticpro (&QCrelative_height);
21906 QCeval = intern (":eval");
21907 staticpro (&QCeval);
21908 QCpropertize = intern (":propertize");
21909 staticpro (&QCpropertize);
21910 QCfile = intern (":file");
21911 staticpro (&QCfile);
21912 Qfontified = intern ("fontified");
21913 staticpro (&Qfontified);
21914 Qfontification_functions = intern ("fontification-functions");
21915 staticpro (&Qfontification_functions);
21916 Qtrailing_whitespace = intern ("trailing-whitespace");
21917 staticpro (&Qtrailing_whitespace);
21918 Qimage = intern ("image");
21919 staticpro (&Qimage);
21920 QCmap = intern (":map");
21921 staticpro (&QCmap);
21922 QCpointer = intern (":pointer");
21923 staticpro (&QCpointer);
21924 Qrect = intern ("rect");
21925 staticpro (&Qrect);
21926 Qcircle = intern ("circle");
21927 staticpro (&Qcircle);
21928 Qpoly = intern ("poly");
21929 staticpro (&Qpoly);
21930 Qmessage_truncate_lines = intern ("message-truncate-lines");
21931 staticpro (&Qmessage_truncate_lines);
21932 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
21933 staticpro (&Qcursor_in_non_selected_windows);
21934 Qgrow_only = intern ("grow-only");
21935 staticpro (&Qgrow_only);
21936 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
21937 staticpro (&Qinhibit_menubar_update);
21938 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
21939 staticpro (&Qinhibit_eval_during_redisplay);
21940 Qposition = intern ("position");
21941 staticpro (&Qposition);
21942 Qbuffer_position = intern ("buffer-position");
21943 staticpro (&Qbuffer_position);
21944 Qobject = intern ("object");
21945 staticpro (&Qobject);
21946 Qbar = intern ("bar");
21947 staticpro (&Qbar);
21948 Qhbar = intern ("hbar");
21949 staticpro (&Qhbar);
21950 Qbox = intern ("box");
21951 staticpro (&Qbox);
21952 Qhollow = intern ("hollow");
21953 staticpro (&Qhollow);
21954 Qhand = intern ("hand");
21955 staticpro (&Qhand);
21956 Qarrow = intern ("arrow");
21957 staticpro (&Qarrow);
21958 Qtext = intern ("text");
21959 staticpro (&Qtext);
21960 Qrisky_local_variable = intern ("risky-local-variable");
21961 staticpro (&Qrisky_local_variable);
21962 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
21963 staticpro (&Qinhibit_free_realized_faces);
21964
21965 list_of_error = Fcons (Fcons (intern ("error"),
21966 Fcons (intern ("void-variable"), Qnil)),
21967 Qnil);
21968 staticpro (&list_of_error);
21969
21970 Qlast_arrow_position = intern ("last-arrow-position");
21971 staticpro (&Qlast_arrow_position);
21972 Qlast_arrow_string = intern ("last-arrow-string");
21973 staticpro (&Qlast_arrow_string);
21974
21975 Qoverlay_arrow_string = intern ("overlay-arrow-string");
21976 staticpro (&Qoverlay_arrow_string);
21977 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
21978 staticpro (&Qoverlay_arrow_bitmap);
21979
21980 echo_buffer[0] = echo_buffer[1] = Qnil;
21981 staticpro (&echo_buffer[0]);
21982 staticpro (&echo_buffer[1]);
21983
21984 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
21985 staticpro (&echo_area_buffer[0]);
21986 staticpro (&echo_area_buffer[1]);
21987
21988 Vmessages_buffer_name = build_string ("*Messages*");
21989 staticpro (&Vmessages_buffer_name);
21990
21991 mode_line_proptrans_alist = Qnil;
21992 staticpro (&mode_line_proptrans_alist);
21993
21994 mode_line_string_list = Qnil;
21995 staticpro (&mode_line_string_list);
21996
21997 help_echo_string = Qnil;
21998 staticpro (&help_echo_string);
21999 help_echo_object = Qnil;
22000 staticpro (&help_echo_object);
22001 help_echo_window = Qnil;
22002 staticpro (&help_echo_window);
22003 previous_help_echo_string = Qnil;
22004 staticpro (&previous_help_echo_string);
22005 help_echo_pos = -1;
22006
22007 #ifdef HAVE_WINDOW_SYSTEM
22008 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22009 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22010 For example, if a block cursor is over a tab, it will be drawn as
22011 wide as that tab on the display. */);
22012 x_stretch_cursor_p = 0;
22013 #endif
22014
22015 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22016 doc: /* *Non-nil means highlight trailing whitespace.
22017 The face used for trailing whitespace is `trailing-whitespace'. */);
22018 Vshow_trailing_whitespace = Qnil;
22019
22020 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22021 doc: /* *The pointer shape to show in void text areas.
22022 Nil means to show the text pointer. Other options are `arrow', `text',
22023 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22024 Vvoid_text_area_pointer = Qarrow;
22025
22026 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22027 doc: /* Non-nil means don't actually do any redisplay.
22028 This is used for internal purposes. */);
22029 Vinhibit_redisplay = Qnil;
22030
22031 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22032 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22033 Vglobal_mode_string = Qnil;
22034
22035 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22036 doc: /* Marker for where to display an arrow on top of the buffer text.
22037 This must be the beginning of a line in order to work.
22038 See also `overlay-arrow-string'. */);
22039 Voverlay_arrow_position = Qnil;
22040
22041 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22042 doc: /* String to display as an arrow in non-window frames.
22043 See also `overlay-arrow-position'. */);
22044 Voverlay_arrow_string = Qnil;
22045
22046 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22047 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22048 The symbols on this list are examined during redisplay to determine
22049 where to display overlay arrows. */);
22050 Voverlay_arrow_variable_list
22051 = Fcons (intern ("overlay-arrow-position"), Qnil);
22052
22053 DEFVAR_INT ("scroll-step", &scroll_step,
22054 doc: /* *The number of lines to try scrolling a window by when point moves out.
22055 If that fails to bring point back on frame, point is centered instead.
22056 If this is zero, point is always centered after it moves off frame.
22057 If you want scrolling to always be a line at a time, you should set
22058 `scroll-conservatively' to a large value rather than set this to 1. */);
22059
22060 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22061 doc: /* *Scroll up to this many lines, to bring point back on screen.
22062 A value of zero means to scroll the text to center point vertically
22063 in the window. */);
22064 scroll_conservatively = 0;
22065
22066 DEFVAR_INT ("scroll-margin", &scroll_margin,
22067 doc: /* *Number of lines of margin at the top and bottom of a window.
22068 Recenter the window whenever point gets within this many lines
22069 of the top or bottom of the window. */);
22070 scroll_margin = 0;
22071
22072 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22073 doc: /* Pixels per inch on current display.
22074 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22075 Vdisplay_pixels_per_inch = make_float (72.0);
22076
22077 #if GLYPH_DEBUG
22078 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22079 #endif
22080
22081 DEFVAR_BOOL ("truncate-partial-width-windows",
22082 &truncate_partial_width_windows,
22083 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22084 truncate_partial_width_windows = 1;
22085
22086 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22087 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22088 Any other value means to use the appropriate face, `mode-line',
22089 `header-line', or `menu' respectively. */);
22090 mode_line_inverse_video = 1;
22091
22092 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22093 doc: /* *Maximum buffer size for which line number should be displayed.
22094 If the buffer is bigger than this, the line number does not appear
22095 in the mode line. A value of nil means no limit. */);
22096 Vline_number_display_limit = Qnil;
22097
22098 DEFVAR_INT ("line-number-display-limit-width",
22099 &line_number_display_limit_width,
22100 doc: /* *Maximum line width (in characters) for line number display.
22101 If the average length of the lines near point is bigger than this, then the
22102 line number may be omitted from the mode line. */);
22103 line_number_display_limit_width = 200;
22104
22105 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22106 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22107 highlight_nonselected_windows = 0;
22108
22109 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22110 doc: /* Non-nil if more than one frame is visible on this display.
22111 Minibuffer-only frames don't count, but iconified frames do.
22112 This variable is not guaranteed to be accurate except while processing
22113 `frame-title-format' and `icon-title-format'. */);
22114
22115 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22116 doc: /* Template for displaying the title bar of visible frames.
22117 \(Assuming the window manager supports this feature.)
22118 This variable has the same structure as `mode-line-format' (which see),
22119 and is used only on frames for which no explicit name has been set
22120 \(see `modify-frame-parameters'). */);
22121
22122 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22123 doc: /* Template for displaying the title bar of an iconified frame.
22124 \(Assuming the window manager supports this feature.)
22125 This variable has the same structure as `mode-line-format' (which see),
22126 and is used only on frames for which no explicit name has been set
22127 \(see `modify-frame-parameters'). */);
22128 Vicon_title_format
22129 = Vframe_title_format
22130 = Fcons (intern ("multiple-frames"),
22131 Fcons (build_string ("%b"),
22132 Fcons (Fcons (empty_string,
22133 Fcons (intern ("invocation-name"),
22134 Fcons (build_string ("@"),
22135 Fcons (intern ("system-name"),
22136 Qnil)))),
22137 Qnil)));
22138
22139 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22140 doc: /* Maximum number of lines to keep in the message log buffer.
22141 If nil, disable message logging. If t, log messages but don't truncate
22142 the buffer when it becomes large. */);
22143 Vmessage_log_max = make_number (50);
22144
22145 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22146 doc: /* Functions called before redisplay, if window sizes have changed.
22147 The value should be a list of functions that take one argument.
22148 Just before redisplay, for each frame, if any of its windows have changed
22149 size since the last redisplay, or have been split or deleted,
22150 all the functions in the list are called, with the frame as argument. */);
22151 Vwindow_size_change_functions = Qnil;
22152
22153 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22154 doc: /* List of Functions to call before redisplaying a window with scrolling.
22155 Each function is called with two arguments, the window
22156 and its new display-start position. Note that the value of `window-end'
22157 is not valid when these functions are called. */);
22158 Vwindow_scroll_functions = Qnil;
22159
22160 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22161 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22162 mouse_autoselect_window = 0;
22163
22164 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22165 doc: /* *Non-nil means automatically resize tool-bars.
22166 This increases a tool-bar's height if not all tool-bar items are visible.
22167 It decreases a tool-bar's height when it would display blank lines
22168 otherwise. */);
22169 auto_resize_tool_bars_p = 1;
22170
22171 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22172 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22173 auto_raise_tool_bar_buttons_p = 1;
22174
22175 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22176 doc: /* *Margin around tool-bar buttons in pixels.
22177 If an integer, use that for both horizontal and vertical margins.
22178 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22179 HORZ specifying the horizontal margin, and VERT specifying the
22180 vertical margin. */);
22181 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22182
22183 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22184 doc: /* *Relief thickness of tool-bar buttons. */);
22185 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22186
22187 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22188 doc: /* List of functions to call to fontify regions of text.
22189 Each function is called with one argument POS. Functions must
22190 fontify a region starting at POS in the current buffer, and give
22191 fontified regions the property `fontified'. */);
22192 Vfontification_functions = Qnil;
22193 Fmake_variable_buffer_local (Qfontification_functions);
22194
22195 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22196 &unibyte_display_via_language_environment,
22197 doc: /* *Non-nil means display unibyte text according to language environment.
22198 Specifically this means that unibyte non-ASCII characters
22199 are displayed by converting them to the equivalent multibyte characters
22200 according to the current language environment. As a result, they are
22201 displayed according to the current fontset. */);
22202 unibyte_display_via_language_environment = 0;
22203
22204 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22205 doc: /* *Maximum height for resizing mini-windows.
22206 If a float, it specifies a fraction of the mini-window frame's height.
22207 If an integer, it specifies a number of lines. */);
22208 Vmax_mini_window_height = make_float (0.25);
22209
22210 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22211 doc: /* *How to resize mini-windows.
22212 A value of nil means don't automatically resize mini-windows.
22213 A value of t means resize them to fit the text displayed in them.
22214 A value of `grow-only', the default, means let mini-windows grow
22215 only, until their display becomes empty, at which point the windows
22216 go back to their normal size. */);
22217 Vresize_mini_windows = Qgrow_only;
22218
22219 DEFVAR_LISP ("cursor-in-non-selected-windows",
22220 &Vcursor_in_non_selected_windows,
22221 doc: /* *Cursor type to display in non-selected windows.
22222 t means to use hollow box cursor. See `cursor-type' for other values. */);
22223 Vcursor_in_non_selected_windows = Qt;
22224
22225 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22226 doc: /* Alist specifying how to blink the cursor off.
22227 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22228 `cursor-type' frame-parameter or variable equals ON-STATE,
22229 comparing using `equal', Emacs uses OFF-STATE to specify
22230 how to blink it off. */);
22231 Vblink_cursor_alist = Qnil;
22232
22233 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22234 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22235 automatic_hscrolling_p = 1;
22236
22237 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22238 doc: /* *How many columns away from the window edge point is allowed to get
22239 before automatic hscrolling will horizontally scroll the window. */);
22240 hscroll_margin = 5;
22241
22242 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22243 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22244 When point is less than `automatic-hscroll-margin' columns from the window
22245 edge, automatic hscrolling will scroll the window by the amount of columns
22246 determined by this variable. If its value is a positive integer, scroll that
22247 many columns. If it's a positive floating-point number, it specifies the
22248 fraction of the window's width to scroll. If it's nil or zero, point will be
22249 centered horizontally after the scroll. Any other value, including negative
22250 numbers, are treated as if the value were zero.
22251
22252 Automatic hscrolling always moves point outside the scroll margin, so if
22253 point was more than scroll step columns inside the margin, the window will
22254 scroll more than the value given by the scroll step.
22255
22256 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22257 and `scroll-right' overrides this variable's effect. */);
22258 Vhscroll_step = make_number (0);
22259
22260 DEFVAR_LISP ("image-types", &Vimage_types,
22261 doc: /* List of supported image types.
22262 Each element of the list is a symbol for a supported image type. */);
22263 Vimage_types = Qnil;
22264
22265 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22266 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22267 Bind this around calls to `message' to let it take effect. */);
22268 message_truncate_lines = 0;
22269
22270 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22271 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22272 Can be used to update submenus whose contents should vary. */);
22273 Vmenu_bar_update_hook = Qnil;
22274
22275 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22276 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22277 inhibit_menubar_update = 0;
22278
22279 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22280 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22281 inhibit_eval_during_redisplay = 0;
22282
22283 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22284 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22285 inhibit_free_realized_faces = 0;
22286
22287 #if GLYPH_DEBUG
22288 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22289 doc: /* Inhibit try_window_id display optimization. */);
22290 inhibit_try_window_id = 0;
22291
22292 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22293 doc: /* Inhibit try_window_reusing display optimization. */);
22294 inhibit_try_window_reusing = 0;
22295
22296 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22297 doc: /* Inhibit try_cursor_movement display optimization. */);
22298 inhibit_try_cursor_movement = 0;
22299 #endif /* GLYPH_DEBUG */
22300 }
22301
22302
22303 /* Initialize this module when Emacs starts. */
22304
22305 void
22306 init_xdisp ()
22307 {
22308 Lisp_Object root_window;
22309 struct window *mini_w;
22310
22311 current_header_line_height = current_mode_line_height = -1;
22312
22313 CHARPOS (this_line_start_pos) = 0;
22314
22315 mini_w = XWINDOW (minibuf_window);
22316 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22317
22318 if (!noninteractive)
22319 {
22320 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22321 int i;
22322
22323 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22324 set_window_height (root_window,
22325 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22326 0);
22327 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22328 set_window_height (minibuf_window, 1, 0);
22329
22330 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22331 mini_w->total_cols = make_number (FRAME_COLS (f));
22332
22333 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22334 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22335 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22336
22337 /* The default ellipsis glyphs `...'. */
22338 for (i = 0; i < 3; ++i)
22339 default_invis_vector[i] = make_number ('.');
22340 }
22341
22342 {
22343 /* Allocate the buffer for frame titles.
22344 Also used for `format-mode-line'. */
22345 int size = 100;
22346 frame_title_buf = (char *) xmalloc (size);
22347 frame_title_buf_end = frame_title_buf + size;
22348 frame_title_ptr = NULL;
22349 }
22350
22351 help_echo_showing_p = 0;
22352 }
22353
22354
22355 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22356 (do not change this comment) */