]> code.delx.au - gnu-emacs/blob - src/xdisp.c
(handle_invisible_prop): Set it->position to fix cursor
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
3 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005, 2006 Free Software Foundation, Inc.
5
6 This file is part of GNU Emacs.
7
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
24
25 Redisplay.
26
27 Emacs separates the task of updating the display from code
28 modifying global state, e.g. buffer text. This way functions
29 operating on buffers don't also have to be concerned with updating
30 the display.
31
32 Updating the display is triggered by the Lisp interpreter when it
33 decides it's time to do it. This is done either automatically for
34 you as part of the interpreter's command loop or as the result of
35 calling Lisp functions like `sit-for'. The C function `redisplay'
36 in xdisp.c is the only entry into the inner redisplay code. (Or,
37 let's say almost---see the description of direct update
38 operations, below.)
39
40 The following diagram shows how redisplay code is invoked. As you
41 can see, Lisp calls redisplay and vice versa. Under window systems
42 like X, some portions of the redisplay code are also called
43 asynchronously during mouse movement or expose events. It is very
44 important that these code parts do NOT use the C library (malloc,
45 free) because many C libraries under Unix are not reentrant. They
46 may also NOT call functions of the Lisp interpreter which could
47 change the interpreter's state. If you don't follow these rules,
48 you will encounter bugs which are very hard to explain.
49
50 (Direct functions, see below)
51 direct_output_for_insert,
52 direct_forward_char (dispnew.c)
53 +---------------------------------+
54 | |
55 | V
56 +--------------+ redisplay +----------------+
57 | Lisp machine |---------------->| Redisplay code |<--+
58 +--------------+ (xdisp.c) +----------------+ |
59 ^ | |
60 +----------------------------------+ |
61 Don't use this path when called |
62 asynchronously! |
63 |
64 expose_window (asynchronous) |
65 |
66 X expose events -----+
67
68 What does redisplay do? Obviously, it has to figure out somehow what
69 has been changed since the last time the display has been updated,
70 and to make these changes visible. Preferably it would do that in
71 a moderately intelligent way, i.e. fast.
72
73 Changes in buffer text can be deduced from window and buffer
74 structures, and from some global variables like `beg_unchanged' and
75 `end_unchanged'. The contents of the display are additionally
76 recorded in a `glyph matrix', a two-dimensional matrix of glyph
77 structures. Each row in such a matrix corresponds to a line on the
78 display, and each glyph in a row corresponds to a column displaying
79 a character, an image, or what else. This matrix is called the
80 `current glyph matrix' or `current matrix' in redisplay
81 terminology.
82
83 For buffer parts that have been changed since the last update, a
84 second glyph matrix is constructed, the so called `desired glyph
85 matrix' or short `desired matrix'. Current and desired matrix are
86 then compared to find a cheap way to update the display, e.g. by
87 reusing part of the display by scrolling lines.
88
89
90 Direct operations.
91
92 You will find a lot of redisplay optimizations when you start
93 looking at the innards of redisplay. The overall goal of all these
94 optimizations is to make redisplay fast because it is done
95 frequently.
96
97 Two optimizations are not found in xdisp.c. These are the direct
98 operations mentioned above. As the name suggests they follow a
99 different principle than the rest of redisplay. Instead of
100 building a desired matrix and then comparing it with the current
101 display, they perform their actions directly on the display and on
102 the current matrix.
103
104 One direct operation updates the display after one character has
105 been entered. The other one moves the cursor by one position
106 forward or backward. You find these functions under the names
107 `direct_output_for_insert' and `direct_output_forward_char' in
108 dispnew.c.
109
110
111 Desired matrices.
112
113 Desired matrices are always built per Emacs window. The function
114 `display_line' is the central function to look at if you are
115 interested. It constructs one row in a desired matrix given an
116 iterator structure containing both a buffer position and a
117 description of the environment in which the text is to be
118 displayed. But this is too early, read on.
119
120 Characters and pixmaps displayed for a range of buffer text depend
121 on various settings of buffers and windows, on overlays and text
122 properties, on display tables, on selective display. The good news
123 is that all this hairy stuff is hidden behind a small set of
124 interface functions taking an iterator structure (struct it)
125 argument.
126
127 Iteration over things to be displayed is then simple. It is
128 started by initializing an iterator with a call to init_iterator.
129 Calls to get_next_display_element fill the iterator structure with
130 relevant information about the next thing to display. Calls to
131 set_iterator_to_next move the iterator to the next thing.
132
133 Besides this, an iterator also contains information about the
134 display environment in which glyphs for display elements are to be
135 produced. It has fields for the width and height of the display,
136 the information whether long lines are truncated or continued, a
137 current X and Y position, and lots of other stuff you can better
138 see in dispextern.h.
139
140 Glyphs in a desired matrix are normally constructed in a loop
141 calling get_next_display_element and then produce_glyphs. The call
142 to produce_glyphs will fill the iterator structure with pixel
143 information about the element being displayed and at the same time
144 produce glyphs for it. If the display element fits on the line
145 being displayed, set_iterator_to_next is called next, otherwise the
146 glyphs produced are discarded.
147
148
149 Frame matrices.
150
151 That just couldn't be all, could it? What about terminal types not
152 supporting operations on sub-windows of the screen? To update the
153 display on such a terminal, window-based glyph matrices are not
154 well suited. To be able to reuse part of the display (scrolling
155 lines up and down), we must instead have a view of the whole
156 screen. This is what `frame matrices' are for. They are a trick.
157
158 Frames on terminals like above have a glyph pool. Windows on such
159 a frame sub-allocate their glyph memory from their frame's glyph
160 pool. The frame itself is given its own glyph matrices. By
161 coincidence---or maybe something else---rows in window glyph
162 matrices are slices of corresponding rows in frame matrices. Thus
163 writing to window matrices implicitly updates a frame matrix which
164 provides us with the view of the whole screen that we originally
165 wanted to have without having to move many bytes around. To be
166 honest, there is a little bit more done, but not much more. If you
167 plan to extend that code, take a look at dispnew.c. The function
168 build_frame_matrix is a good starting point. */
169
170 #include <config.h>
171 #include <stdio.h>
172
173 #include "lisp.h"
174 #include "keyboard.h"
175 #include "frame.h"
176 #include "window.h"
177 #include "termchar.h"
178 #include "dispextern.h"
179 #include "buffer.h"
180 #include "charset.h"
181 #include "indent.h"
182 #include "commands.h"
183 #include "keymap.h"
184 #include "macros.h"
185 #include "disptab.h"
186 #include "termhooks.h"
187 #include "intervals.h"
188 #include "coding.h"
189 #include "process.h"
190 #include "region-cache.h"
191 #include "fontset.h"
192 #include "blockinput.h"
193
194 #ifdef HAVE_X_WINDOWS
195 #include "xterm.h"
196 #endif
197 #ifdef WINDOWSNT
198 #include "w32term.h"
199 #endif
200 #ifdef MAC_OS
201 #include "macterm.h"
202 #endif
203
204 #ifndef FRAME_X_OUTPUT
205 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
206 #endif
207
208 #define INFINITY 10000000
209
210 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
211 || defined (USE_GTK)
212 extern void set_frame_menubar P_ ((struct frame *f, int, int));
213 extern int pending_menu_activation;
214 #endif
215
216 extern int interrupt_input;
217 extern int command_loop_level;
218
219 extern Lisp_Object do_mouse_tracking;
220
221 extern int minibuffer_auto_raise;
222 extern Lisp_Object Vminibuffer_list;
223
224 extern Lisp_Object Qface;
225 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226
227 extern Lisp_Object Voverriding_local_map;
228 extern Lisp_Object Voverriding_local_map_menu_flag;
229 extern Lisp_Object Qmenu_item;
230 extern Lisp_Object Qwhen;
231 extern Lisp_Object Qhelp_echo;
232
233 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
234 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
235 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
236 Lisp_Object Qinhibit_point_motion_hooks;
237 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
238 Lisp_Object Qfontified;
239 Lisp_Object Qgrow_only;
240 Lisp_Object Qinhibit_eval_during_redisplay;
241 Lisp_Object Qbuffer_position, Qposition, Qobject;
242
243 /* Cursor shapes */
244 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245
246 /* Pointer shapes */
247 Lisp_Object Qarrow, Qhand, Qtext;
248
249 Lisp_Object Qrisky_local_variable;
250
251 /* Holds the list (error). */
252 Lisp_Object list_of_error;
253
254 /* Functions called to fontify regions of text. */
255
256 Lisp_Object Vfontification_functions;
257 Lisp_Object Qfontification_functions;
258
259 /* Non-zero means automatically select any window when the mouse
260 cursor moves into it. */
261 int mouse_autoselect_window;
262
263 /* Non-zero means draw tool bar buttons raised when the mouse moves
264 over them. */
265
266 int auto_raise_tool_bar_buttons_p;
267
268 /* Non-zero means to reposition window if cursor line is only partially visible. */
269
270 int make_cursor_line_fully_visible_p;
271
272 /* Margin around tool bar buttons in pixels. */
273
274 Lisp_Object Vtool_bar_button_margin;
275
276 /* Thickness of shadow to draw around tool bar buttons. */
277
278 EMACS_INT tool_bar_button_relief;
279
280 /* Non-zero means automatically resize tool-bars so that all tool-bar
281 items are visible, and no blank lines remain. */
282
283 int auto_resize_tool_bars_p;
284
285 /* Non-zero means draw block and hollow cursor as wide as the glyph
286 under it. For example, if a block cursor is over a tab, it will be
287 drawn as wide as that tab on the display. */
288
289 int x_stretch_cursor_p;
290
291 /* Non-nil means don't actually do any redisplay. */
292
293 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
294
295 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
296
297 int inhibit_eval_during_redisplay;
298
299 /* Names of text properties relevant for redisplay. */
300
301 Lisp_Object Qdisplay;
302 extern Lisp_Object Qface, Qinvisible, Qwidth;
303
304 /* Symbols used in text property values. */
305
306 Lisp_Object Vdisplay_pixels_per_inch;
307 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
308 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
309 Lisp_Object Qslice;
310 Lisp_Object Qcenter;
311 Lisp_Object Qmargin, Qpointer;
312 Lisp_Object Qline_height;
313 extern Lisp_Object Qheight;
314 extern Lisp_Object QCwidth, QCheight, QCascent;
315 extern Lisp_Object Qscroll_bar;
316 extern Lisp_Object Qcursor;
317
318 /* Non-nil means highlight trailing whitespace. */
319
320 Lisp_Object Vshow_trailing_whitespace;
321
322 /* Non-nil means escape non-break space and hyphens. */
323
324 Lisp_Object Vnobreak_char_display;
325
326 #ifdef HAVE_WINDOW_SYSTEM
327 extern Lisp_Object Voverflow_newline_into_fringe;
328
329 /* Test if overflow newline into fringe. Called with iterator IT
330 at or past right window margin, and with IT->current_x set. */
331
332 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
333 (!NILP (Voverflow_newline_into_fringe) \
334 && FRAME_WINDOW_P (it->f) \
335 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
336 && it->current_x == it->last_visible_x)
337
338 #endif /* HAVE_WINDOW_SYSTEM */
339
340 /* Non-nil means show the text cursor in void text areas
341 i.e. in blank areas after eol and eob. This used to be
342 the default in 21.3. */
343
344 Lisp_Object Vvoid_text_area_pointer;
345
346 /* Name of the face used to highlight trailing whitespace. */
347
348 Lisp_Object Qtrailing_whitespace;
349
350 /* Name and number of the face used to highlight escape glyphs. */
351
352 Lisp_Object Qescape_glyph;
353
354 /* Name and number of the face used to highlight non-breaking spaces. */
355
356 Lisp_Object Qnobreak_space;
357
358 /* The symbol `image' which is the car of the lists used to represent
359 images in Lisp. */
360
361 Lisp_Object Qimage;
362
363 /* The image map types. */
364 Lisp_Object QCmap, QCpointer;
365 Lisp_Object Qrect, Qcircle, Qpoly;
366
367 /* Non-zero means print newline to stdout before next mini-buffer
368 message. */
369
370 int noninteractive_need_newline;
371
372 /* Non-zero means print newline to message log before next message. */
373
374 static int message_log_need_newline;
375
376 /* Three markers that message_dolog uses.
377 It could allocate them itself, but that causes trouble
378 in handling memory-full errors. */
379 static Lisp_Object message_dolog_marker1;
380 static Lisp_Object message_dolog_marker2;
381 static Lisp_Object message_dolog_marker3;
382 \f
383 /* The buffer position of the first character appearing entirely or
384 partially on the line of the selected window which contains the
385 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
386 redisplay optimization in redisplay_internal. */
387
388 static struct text_pos this_line_start_pos;
389
390 /* Number of characters past the end of the line above, including the
391 terminating newline. */
392
393 static struct text_pos this_line_end_pos;
394
395 /* The vertical positions and the height of this line. */
396
397 static int this_line_vpos;
398 static int this_line_y;
399 static int this_line_pixel_height;
400
401 /* X position at which this display line starts. Usually zero;
402 negative if first character is partially visible. */
403
404 static int this_line_start_x;
405
406 /* Buffer that this_line_.* variables are referring to. */
407
408 static struct buffer *this_line_buffer;
409
410 /* Nonzero means truncate lines in all windows less wide than the
411 frame. */
412
413 int truncate_partial_width_windows;
414
415 /* A flag to control how to display unibyte 8-bit character. */
416
417 int unibyte_display_via_language_environment;
418
419 /* Nonzero means we have more than one non-mini-buffer-only frame.
420 Not guaranteed to be accurate except while parsing
421 frame-title-format. */
422
423 int multiple_frames;
424
425 Lisp_Object Vglobal_mode_string;
426
427
428 /* List of variables (symbols) which hold markers for overlay arrows.
429 The symbols on this list are examined during redisplay to determine
430 where to display overlay arrows. */
431
432 Lisp_Object Voverlay_arrow_variable_list;
433
434 /* Marker for where to display an arrow on top of the buffer text. */
435
436 Lisp_Object Voverlay_arrow_position;
437
438 /* String to display for the arrow. Only used on terminal frames. */
439
440 Lisp_Object Voverlay_arrow_string;
441
442 /* Values of those variables at last redisplay are stored as
443 properties on `overlay-arrow-position' symbol. However, if
444 Voverlay_arrow_position is a marker, last-arrow-position is its
445 numerical position. */
446
447 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
448
449 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
450 properties on a symbol in overlay-arrow-variable-list. */
451
452 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
453
454 /* Like mode-line-format, but for the title bar on a visible frame. */
455
456 Lisp_Object Vframe_title_format;
457
458 /* Like mode-line-format, but for the title bar on an iconified frame. */
459
460 Lisp_Object Vicon_title_format;
461
462 /* List of functions to call when a window's size changes. These
463 functions get one arg, a frame on which one or more windows' sizes
464 have changed. */
465
466 static Lisp_Object Vwindow_size_change_functions;
467
468 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
469
470 /* Nonzero if an overlay arrow has been displayed in this window. */
471
472 static int overlay_arrow_seen;
473
474 /* Nonzero means highlight the region even in nonselected windows. */
475
476 int highlight_nonselected_windows;
477
478 /* If cursor motion alone moves point off frame, try scrolling this
479 many lines up or down if that will bring it back. */
480
481 static EMACS_INT scroll_step;
482
483 /* Nonzero means scroll just far enough to bring point back on the
484 screen, when appropriate. */
485
486 static EMACS_INT scroll_conservatively;
487
488 /* Recenter the window whenever point gets within this many lines of
489 the top or bottom of the window. This value is translated into a
490 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
491 that there is really a fixed pixel height scroll margin. */
492
493 EMACS_INT scroll_margin;
494
495 /* Number of windows showing the buffer of the selected window (or
496 another buffer with the same base buffer). keyboard.c refers to
497 this. */
498
499 int buffer_shared;
500
501 /* Vector containing glyphs for an ellipsis `...'. */
502
503 static Lisp_Object default_invis_vector[3];
504
505 /* Zero means display the mode-line/header-line/menu-bar in the default face
506 (this slightly odd definition is for compatibility with previous versions
507 of emacs), non-zero means display them using their respective faces.
508
509 This variable is deprecated. */
510
511 int mode_line_inverse_video;
512
513 /* Prompt to display in front of the mini-buffer contents. */
514
515 Lisp_Object minibuf_prompt;
516
517 /* Width of current mini-buffer prompt. Only set after display_line
518 of the line that contains the prompt. */
519
520 int minibuf_prompt_width;
521
522 /* This is the window where the echo area message was displayed. It
523 is always a mini-buffer window, but it may not be the same window
524 currently active as a mini-buffer. */
525
526 Lisp_Object echo_area_window;
527
528 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
529 pushes the current message and the value of
530 message_enable_multibyte on the stack, the function restore_message
531 pops the stack and displays MESSAGE again. */
532
533 Lisp_Object Vmessage_stack;
534
535 /* Nonzero means multibyte characters were enabled when the echo area
536 message was specified. */
537
538 int message_enable_multibyte;
539
540 /* Nonzero if we should redraw the mode lines on the next redisplay. */
541
542 int update_mode_lines;
543
544 /* Nonzero if window sizes or contents have changed since last
545 redisplay that finished. */
546
547 int windows_or_buffers_changed;
548
549 /* Nonzero means a frame's cursor type has been changed. */
550
551 int cursor_type_changed;
552
553 /* Nonzero after display_mode_line if %l was used and it displayed a
554 line number. */
555
556 int line_number_displayed;
557
558 /* Maximum buffer size for which to display line numbers. */
559
560 Lisp_Object Vline_number_display_limit;
561
562 /* Line width to consider when repositioning for line number display. */
563
564 static EMACS_INT line_number_display_limit_width;
565
566 /* Number of lines to keep in the message log buffer. t means
567 infinite. nil means don't log at all. */
568
569 Lisp_Object Vmessage_log_max;
570
571 /* The name of the *Messages* buffer, a string. */
572
573 static Lisp_Object Vmessages_buffer_name;
574
575 /* Index 0 is the buffer that holds the current (desired) echo area message,
576 or nil if none is desired right now.
577
578 Index 1 is the buffer that holds the previously displayed echo area message,
579 or nil to indicate no message. This is normally what's on the screen now.
580
581 These two can point to the same buffer. That happens when the last
582 message output by the user (or made by echoing) has been displayed. */
583
584 Lisp_Object echo_area_buffer[2];
585
586 /* Permanent pointers to the two buffers that are used for echo area
587 purposes. Once the two buffers are made, and their pointers are
588 placed here, these two slots remain unchanged unless those buffers
589 need to be created afresh. */
590
591 static Lisp_Object echo_buffer[2];
592
593 /* A vector saved used in with_area_buffer to reduce consing. */
594
595 static Lisp_Object Vwith_echo_area_save_vector;
596
597 /* Non-zero means display_echo_area should display the last echo area
598 message again. Set by redisplay_preserve_echo_area. */
599
600 static int display_last_displayed_message_p;
601
602 /* Nonzero if echo area is being used by print; zero if being used by
603 message. */
604
605 int message_buf_print;
606
607 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
608
609 Lisp_Object Qinhibit_menubar_update;
610 int inhibit_menubar_update;
611
612 /* Maximum height for resizing mini-windows. Either a float
613 specifying a fraction of the available height, or an integer
614 specifying a number of lines. */
615
616 Lisp_Object Vmax_mini_window_height;
617
618 /* Non-zero means messages should be displayed with truncated
619 lines instead of being continued. */
620
621 int message_truncate_lines;
622 Lisp_Object Qmessage_truncate_lines;
623
624 /* Set to 1 in clear_message to make redisplay_internal aware
625 of an emptied echo area. */
626
627 static int message_cleared_p;
628
629 /* How to blink the default frame cursor off. */
630 Lisp_Object Vblink_cursor_alist;
631
632 /* A scratch glyph row with contents used for generating truncation
633 glyphs. Also used in direct_output_for_insert. */
634
635 #define MAX_SCRATCH_GLYPHS 100
636 struct glyph_row scratch_glyph_row;
637 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
638
639 /* Ascent and height of the last line processed by move_it_to. */
640
641 static int last_max_ascent, last_height;
642
643 /* Non-zero if there's a help-echo in the echo area. */
644
645 int help_echo_showing_p;
646
647 /* If >= 0, computed, exact values of mode-line and header-line height
648 to use in the macros CURRENT_MODE_LINE_HEIGHT and
649 CURRENT_HEADER_LINE_HEIGHT. */
650
651 int current_mode_line_height, current_header_line_height;
652
653 /* The maximum distance to look ahead for text properties. Values
654 that are too small let us call compute_char_face and similar
655 functions too often which is expensive. Values that are too large
656 let us call compute_char_face and alike too often because we
657 might not be interested in text properties that far away. */
658
659 #define TEXT_PROP_DISTANCE_LIMIT 100
660
661 #if GLYPH_DEBUG
662
663 /* Variables to turn off display optimizations from Lisp. */
664
665 int inhibit_try_window_id, inhibit_try_window_reusing;
666 int inhibit_try_cursor_movement;
667
668 /* Non-zero means print traces of redisplay if compiled with
669 GLYPH_DEBUG != 0. */
670
671 int trace_redisplay_p;
672
673 #endif /* GLYPH_DEBUG */
674
675 #ifdef DEBUG_TRACE_MOVE
676 /* Non-zero means trace with TRACE_MOVE to stderr. */
677 int trace_move;
678
679 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
680 #else
681 #define TRACE_MOVE(x) (void) 0
682 #endif
683
684 /* Non-zero means automatically scroll windows horizontally to make
685 point visible. */
686
687 int automatic_hscrolling_p;
688
689 /* How close to the margin can point get before the window is scrolled
690 horizontally. */
691 EMACS_INT hscroll_margin;
692
693 /* How much to scroll horizontally when point is inside the above margin. */
694 Lisp_Object Vhscroll_step;
695
696 /* The variable `resize-mini-windows'. If nil, don't resize
697 mini-windows. If t, always resize them to fit the text they
698 display. If `grow-only', let mini-windows grow only until they
699 become empty. */
700
701 Lisp_Object Vresize_mini_windows;
702
703 /* Buffer being redisplayed -- for redisplay_window_error. */
704
705 struct buffer *displayed_buffer;
706
707 /* Value returned from text property handlers (see below). */
708
709 enum prop_handled
710 {
711 HANDLED_NORMALLY,
712 HANDLED_RECOMPUTE_PROPS,
713 HANDLED_OVERLAY_STRING_CONSUMED,
714 HANDLED_RETURN
715 };
716
717 /* A description of text properties that redisplay is interested
718 in. */
719
720 struct props
721 {
722 /* The name of the property. */
723 Lisp_Object *name;
724
725 /* A unique index for the property. */
726 enum prop_idx idx;
727
728 /* A handler function called to set up iterator IT from the property
729 at IT's current position. Value is used to steer handle_stop. */
730 enum prop_handled (*handler) P_ ((struct it *it));
731 };
732
733 static enum prop_handled handle_face_prop P_ ((struct it *));
734 static enum prop_handled handle_invisible_prop P_ ((struct it *));
735 static enum prop_handled handle_display_prop P_ ((struct it *));
736 static enum prop_handled handle_composition_prop P_ ((struct it *));
737 static enum prop_handled handle_overlay_change P_ ((struct it *));
738 static enum prop_handled handle_fontified_prop P_ ((struct it *));
739
740 /* Properties handled by iterators. */
741
742 static struct props it_props[] =
743 {
744 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
745 /* Handle `face' before `display' because some sub-properties of
746 `display' need to know the face. */
747 {&Qface, FACE_PROP_IDX, handle_face_prop},
748 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
749 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
750 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
751 {NULL, 0, NULL}
752 };
753
754 /* Value is the position described by X. If X is a marker, value is
755 the marker_position of X. Otherwise, value is X. */
756
757 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
758
759 /* Enumeration returned by some move_it_.* functions internally. */
760
761 enum move_it_result
762 {
763 /* Not used. Undefined value. */
764 MOVE_UNDEFINED,
765
766 /* Move ended at the requested buffer position or ZV. */
767 MOVE_POS_MATCH_OR_ZV,
768
769 /* Move ended at the requested X pixel position. */
770 MOVE_X_REACHED,
771
772 /* Move within a line ended at the end of a line that must be
773 continued. */
774 MOVE_LINE_CONTINUED,
775
776 /* Move within a line ended at the end of a line that would
777 be displayed truncated. */
778 MOVE_LINE_TRUNCATED,
779
780 /* Move within a line ended at a line end. */
781 MOVE_NEWLINE_OR_CR
782 };
783
784 /* This counter is used to clear the face cache every once in a while
785 in redisplay_internal. It is incremented for each redisplay.
786 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
787 cleared. */
788
789 #define CLEAR_FACE_CACHE_COUNT 500
790 static int clear_face_cache_count;
791
792 /* Similarly for the image cache. */
793
794 #ifdef HAVE_WINDOW_SYSTEM
795 #define CLEAR_IMAGE_CACHE_COUNT 101
796 static int clear_image_cache_count;
797 #endif
798
799 /* Record the previous terminal frame we displayed. */
800
801 static struct frame *previous_terminal_frame;
802
803 /* Non-zero while redisplay_internal is in progress. */
804
805 int redisplaying_p;
806
807 /* Non-zero means don't free realized faces. Bound while freeing
808 realized faces is dangerous because glyph matrices might still
809 reference them. */
810
811 int inhibit_free_realized_faces;
812 Lisp_Object Qinhibit_free_realized_faces;
813
814 /* If a string, XTread_socket generates an event to display that string.
815 (The display is done in read_char.) */
816
817 Lisp_Object help_echo_string;
818 Lisp_Object help_echo_window;
819 Lisp_Object help_echo_object;
820 int help_echo_pos;
821
822 /* Temporary variable for XTread_socket. */
823
824 Lisp_Object previous_help_echo_string;
825
826 /* Null glyph slice */
827
828 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
829
830 \f
831 /* Function prototypes. */
832
833 static void setup_for_ellipsis P_ ((struct it *, int));
834 static void mark_window_display_accurate_1 P_ ((struct window *, int));
835 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
836 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
837 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
838 static int redisplay_mode_lines P_ ((Lisp_Object, int));
839 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
840
841 #if 0
842 static int invisible_text_between_p P_ ((struct it *, int, int));
843 #endif
844
845 static void pint2str P_ ((char *, int, int));
846 static void pint2hrstr P_ ((char *, int, int));
847 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
848 struct text_pos));
849 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
850 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
851 static void store_mode_line_noprop_char P_ ((char));
852 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
853 static void x_consider_frame_title P_ ((Lisp_Object));
854 static void handle_stop P_ ((struct it *));
855 static int tool_bar_lines_needed P_ ((struct frame *));
856 static int single_display_spec_intangible_p P_ ((Lisp_Object));
857 static void ensure_echo_area_buffers P_ ((void));
858 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
859 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
860 static int with_echo_area_buffer P_ ((struct window *, int,
861 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
862 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
863 static void clear_garbaged_frames P_ ((void));
864 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
865 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
866 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
867 static int display_echo_area P_ ((struct window *));
868 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
869 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
870 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
871 static int string_char_and_length P_ ((const unsigned char *, int, int *));
872 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
873 struct text_pos));
874 static int compute_window_start_on_continuation_line P_ ((struct window *));
875 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
876 static void insert_left_trunc_glyphs P_ ((struct it *));
877 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
878 Lisp_Object));
879 static void extend_face_to_end_of_line P_ ((struct it *));
880 static int append_space_for_newline P_ ((struct it *, int));
881 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
882 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
883 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
884 static int trailing_whitespace_p P_ ((int));
885 static int message_log_check_duplicate P_ ((int, int, int, int));
886 static void push_it P_ ((struct it *));
887 static void pop_it P_ ((struct it *));
888 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
889 static void select_frame_for_redisplay P_ ((Lisp_Object));
890 static void redisplay_internal P_ ((int));
891 static int echo_area_display P_ ((int));
892 static void redisplay_windows P_ ((Lisp_Object));
893 static void redisplay_window P_ ((Lisp_Object, int));
894 static Lisp_Object redisplay_window_error ();
895 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
896 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
897 static void update_menu_bar P_ ((struct frame *, int));
898 static int try_window_reusing_current_matrix P_ ((struct window *));
899 static int try_window_id P_ ((struct window *));
900 static int display_line P_ ((struct it *));
901 static int display_mode_lines P_ ((struct window *));
902 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
903 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
904 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
905 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
906 static void display_menu_bar P_ ((struct window *));
907 static int display_count_lines P_ ((int, int, int, int, int *));
908 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
909 int, int, struct it *, int, int, int, int));
910 static void compute_line_metrics P_ ((struct it *));
911 static void run_redisplay_end_trigger_hook P_ ((struct it *));
912 static int get_overlay_strings P_ ((struct it *, int));
913 static void next_overlay_string P_ ((struct it *));
914 static void reseat P_ ((struct it *, struct text_pos, int));
915 static void reseat_1 P_ ((struct it *, struct text_pos, int));
916 static void back_to_previous_visible_line_start P_ ((struct it *));
917 void reseat_at_previous_visible_line_start P_ ((struct it *));
918 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
919 static int next_element_from_ellipsis P_ ((struct it *));
920 static int next_element_from_display_vector P_ ((struct it *));
921 static int next_element_from_string P_ ((struct it *));
922 static int next_element_from_c_string P_ ((struct it *));
923 static int next_element_from_buffer P_ ((struct it *));
924 static int next_element_from_composition P_ ((struct it *));
925 static int next_element_from_image P_ ((struct it *));
926 static int next_element_from_stretch P_ ((struct it *));
927 static void load_overlay_strings P_ ((struct it *, int));
928 static int init_from_display_pos P_ ((struct it *, struct window *,
929 struct display_pos *));
930 static void reseat_to_string P_ ((struct it *, unsigned char *,
931 Lisp_Object, int, int, int, int));
932 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
933 int, int, int));
934 void move_it_vertically_backward P_ ((struct it *, int));
935 static void init_to_row_start P_ ((struct it *, struct window *,
936 struct glyph_row *));
937 static int init_to_row_end P_ ((struct it *, struct window *,
938 struct glyph_row *));
939 static void back_to_previous_line_start P_ ((struct it *));
940 static int forward_to_next_line_start P_ ((struct it *, int *));
941 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
942 Lisp_Object, int));
943 static struct text_pos string_pos P_ ((int, Lisp_Object));
944 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
945 static int number_of_chars P_ ((unsigned char *, int));
946 static void compute_stop_pos P_ ((struct it *));
947 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
948 Lisp_Object));
949 static int face_before_or_after_it_pos P_ ((struct it *, int));
950 static int next_overlay_change P_ ((int));
951 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
952 Lisp_Object, struct text_pos *,
953 int));
954 static int underlying_face_id P_ ((struct it *));
955 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
956 struct window *));
957
958 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
959 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
960
961 #ifdef HAVE_WINDOW_SYSTEM
962
963 static void update_tool_bar P_ ((struct frame *, int));
964 static void build_desired_tool_bar_string P_ ((struct frame *f));
965 static int redisplay_tool_bar P_ ((struct frame *));
966 static void display_tool_bar_line P_ ((struct it *));
967 static void notice_overwritten_cursor P_ ((struct window *,
968 enum glyph_row_area,
969 int, int, int, int));
970
971
972
973 #endif /* HAVE_WINDOW_SYSTEM */
974
975 \f
976 /***********************************************************************
977 Window display dimensions
978 ***********************************************************************/
979
980 /* Return the bottom boundary y-position for text lines in window W.
981 This is the first y position at which a line cannot start.
982 It is relative to the top of the window.
983
984 This is the height of W minus the height of a mode line, if any. */
985
986 INLINE int
987 window_text_bottom_y (w)
988 struct window *w;
989 {
990 int height = WINDOW_TOTAL_HEIGHT (w);
991
992 if (WINDOW_WANTS_MODELINE_P (w))
993 height -= CURRENT_MODE_LINE_HEIGHT (w);
994 return height;
995 }
996
997 /* Return the pixel width of display area AREA of window W. AREA < 0
998 means return the total width of W, not including fringes to
999 the left and right of the window. */
1000
1001 INLINE int
1002 window_box_width (w, area)
1003 struct window *w;
1004 int area;
1005 {
1006 int cols = XFASTINT (w->total_cols);
1007 int pixels = 0;
1008
1009 if (!w->pseudo_window_p)
1010 {
1011 cols -= WINDOW_SCROLL_BAR_COLS (w);
1012
1013 if (area == TEXT_AREA)
1014 {
1015 if (INTEGERP (w->left_margin_cols))
1016 cols -= XFASTINT (w->left_margin_cols);
1017 if (INTEGERP (w->right_margin_cols))
1018 cols -= XFASTINT (w->right_margin_cols);
1019 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1020 }
1021 else if (area == LEFT_MARGIN_AREA)
1022 {
1023 cols = (INTEGERP (w->left_margin_cols)
1024 ? XFASTINT (w->left_margin_cols) : 0);
1025 pixels = 0;
1026 }
1027 else if (area == RIGHT_MARGIN_AREA)
1028 {
1029 cols = (INTEGERP (w->right_margin_cols)
1030 ? XFASTINT (w->right_margin_cols) : 0);
1031 pixels = 0;
1032 }
1033 }
1034
1035 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1036 }
1037
1038
1039 /* Return the pixel height of the display area of window W, not
1040 including mode lines of W, if any. */
1041
1042 INLINE int
1043 window_box_height (w)
1044 struct window *w;
1045 {
1046 struct frame *f = XFRAME (w->frame);
1047 int height = WINDOW_TOTAL_HEIGHT (w);
1048
1049 xassert (height >= 0);
1050
1051 /* Note: the code below that determines the mode-line/header-line
1052 height is essentially the same as that contained in the macro
1053 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1054 the appropriate glyph row has its `mode_line_p' flag set,
1055 and if it doesn't, uses estimate_mode_line_height instead. */
1056
1057 if (WINDOW_WANTS_MODELINE_P (w))
1058 {
1059 struct glyph_row *ml_row
1060 = (w->current_matrix && w->current_matrix->rows
1061 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1062 : 0);
1063 if (ml_row && ml_row->mode_line_p)
1064 height -= ml_row->height;
1065 else
1066 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1067 }
1068
1069 if (WINDOW_WANTS_HEADER_LINE_P (w))
1070 {
1071 struct glyph_row *hl_row
1072 = (w->current_matrix && w->current_matrix->rows
1073 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1074 : 0);
1075 if (hl_row && hl_row->mode_line_p)
1076 height -= hl_row->height;
1077 else
1078 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1079 }
1080
1081 /* With a very small font and a mode-line that's taller than
1082 default, we might end up with a negative height. */
1083 return max (0, height);
1084 }
1085
1086 /* Return the window-relative coordinate of the left edge of display
1087 area AREA of window W. AREA < 0 means return the left edge of the
1088 whole window, to the right of the left fringe of W. */
1089
1090 INLINE int
1091 window_box_left_offset (w, area)
1092 struct window *w;
1093 int area;
1094 {
1095 int x;
1096
1097 if (w->pseudo_window_p)
1098 return 0;
1099
1100 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1101
1102 if (area == TEXT_AREA)
1103 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1104 + window_box_width (w, LEFT_MARGIN_AREA));
1105 else if (area == RIGHT_MARGIN_AREA)
1106 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1107 + window_box_width (w, LEFT_MARGIN_AREA)
1108 + window_box_width (w, TEXT_AREA)
1109 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1110 ? 0
1111 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1112 else if (area == LEFT_MARGIN_AREA
1113 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1114 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1115
1116 return x;
1117 }
1118
1119
1120 /* Return the window-relative coordinate of the right edge of display
1121 area AREA of window W. AREA < 0 means return the left edge of the
1122 whole window, to the left of the right fringe of W. */
1123
1124 INLINE int
1125 window_box_right_offset (w, area)
1126 struct window *w;
1127 int area;
1128 {
1129 return window_box_left_offset (w, area) + window_box_width (w, area);
1130 }
1131
1132 /* Return the frame-relative coordinate of the left edge of display
1133 area AREA of window W. AREA < 0 means return the left edge of the
1134 whole window, to the right of the left fringe of W. */
1135
1136 INLINE int
1137 window_box_left (w, area)
1138 struct window *w;
1139 int area;
1140 {
1141 struct frame *f = XFRAME (w->frame);
1142 int x;
1143
1144 if (w->pseudo_window_p)
1145 return FRAME_INTERNAL_BORDER_WIDTH (f);
1146
1147 x = (WINDOW_LEFT_EDGE_X (w)
1148 + window_box_left_offset (w, area));
1149
1150 return x;
1151 }
1152
1153
1154 /* Return the frame-relative coordinate of the right edge of display
1155 area AREA of window W. AREA < 0 means return the left edge of the
1156 whole window, to the left of the right fringe of W. */
1157
1158 INLINE int
1159 window_box_right (w, area)
1160 struct window *w;
1161 int area;
1162 {
1163 return window_box_left (w, area) + window_box_width (w, area);
1164 }
1165
1166 /* Get the bounding box of the display area AREA of window W, without
1167 mode lines, in frame-relative coordinates. AREA < 0 means the
1168 whole window, not including the left and right fringes of
1169 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1170 coordinates of the upper-left corner of the box. Return in
1171 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1172
1173 INLINE void
1174 window_box (w, area, box_x, box_y, box_width, box_height)
1175 struct window *w;
1176 int area;
1177 int *box_x, *box_y, *box_width, *box_height;
1178 {
1179 if (box_width)
1180 *box_width = window_box_width (w, area);
1181 if (box_height)
1182 *box_height = window_box_height (w);
1183 if (box_x)
1184 *box_x = window_box_left (w, area);
1185 if (box_y)
1186 {
1187 *box_y = WINDOW_TOP_EDGE_Y (w);
1188 if (WINDOW_WANTS_HEADER_LINE_P (w))
1189 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1190 }
1191 }
1192
1193
1194 /* Get the bounding box of the display area AREA of window W, without
1195 mode lines. AREA < 0 means the whole window, not including the
1196 left and right fringe of the window. Return in *TOP_LEFT_X
1197 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1198 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1199 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1200 box. */
1201
1202 INLINE void
1203 window_box_edges (w, area, top_left_x, top_left_y,
1204 bottom_right_x, bottom_right_y)
1205 struct window *w;
1206 int area;
1207 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1208 {
1209 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1210 bottom_right_y);
1211 *bottom_right_x += *top_left_x;
1212 *bottom_right_y += *top_left_y;
1213 }
1214
1215
1216 \f
1217 /***********************************************************************
1218 Utilities
1219 ***********************************************************************/
1220
1221 /* Return the bottom y-position of the line the iterator IT is in.
1222 This can modify IT's settings. */
1223
1224 int
1225 line_bottom_y (it)
1226 struct it *it;
1227 {
1228 int line_height = it->max_ascent + it->max_descent;
1229 int line_top_y = it->current_y;
1230
1231 if (line_height == 0)
1232 {
1233 if (last_height)
1234 line_height = last_height;
1235 else if (IT_CHARPOS (*it) < ZV)
1236 {
1237 move_it_by_lines (it, 1, 1);
1238 line_height = (it->max_ascent || it->max_descent
1239 ? it->max_ascent + it->max_descent
1240 : last_height);
1241 }
1242 else
1243 {
1244 struct glyph_row *row = it->glyph_row;
1245
1246 /* Use the default character height. */
1247 it->glyph_row = NULL;
1248 it->what = IT_CHARACTER;
1249 it->c = ' ';
1250 it->len = 1;
1251 PRODUCE_GLYPHS (it);
1252 line_height = it->ascent + it->descent;
1253 it->glyph_row = row;
1254 }
1255 }
1256
1257 return line_top_y + line_height;
1258 }
1259
1260
1261 /* Return 1 if position CHARPOS is visible in window W.
1262 If visible, set *X and *Y to pixel coordinates of top left corner.
1263 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1264 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1265 and header-lines heights. */
1266
1267 int
1268 pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1269 struct window *w;
1270 int charpos, *x, *y, *rtop, *rbot, exact_mode_line_heights_p;
1271 {
1272 struct it it;
1273 struct text_pos top;
1274 int visible_p = 0;
1275 struct buffer *old_buffer = NULL;
1276
1277 if (noninteractive)
1278 return visible_p;
1279
1280 if (XBUFFER (w->buffer) != current_buffer)
1281 {
1282 old_buffer = current_buffer;
1283 set_buffer_internal_1 (XBUFFER (w->buffer));
1284 }
1285
1286 SET_TEXT_POS_FROM_MARKER (top, w->start);
1287
1288 /* Compute exact mode line heights, if requested. */
1289 if (exact_mode_line_heights_p)
1290 {
1291 if (WINDOW_WANTS_MODELINE_P (w))
1292 current_mode_line_height
1293 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1294 current_buffer->mode_line_format);
1295
1296 if (WINDOW_WANTS_HEADER_LINE_P (w))
1297 current_header_line_height
1298 = display_mode_line (w, HEADER_LINE_FACE_ID,
1299 current_buffer->header_line_format);
1300 }
1301
1302 start_display (&it, w, top);
1303 move_it_to (&it, charpos, -1, it.last_visible_y, -1,
1304 MOVE_TO_POS | MOVE_TO_Y);
1305
1306 /* Note that we may overshoot because of invisible text. */
1307 if (IT_CHARPOS (it) >= charpos)
1308 {
1309 int top_x = it.current_x;
1310 int top_y = it.current_y;
1311 int bottom_y = (last_height = 0, line_bottom_y (&it));
1312 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1313
1314 if (top_y < window_top_y)
1315 visible_p = bottom_y > window_top_y;
1316 else if (top_y < it.last_visible_y)
1317 visible_p = 1;
1318 if (visible_p)
1319 {
1320 *x = top_x;
1321 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1322 *rtop = max (0, window_top_y - top_y);
1323 *rbot = max (0, bottom_y - it.last_visible_y);
1324 }
1325 }
1326 else
1327 {
1328 struct it it2;
1329
1330 it2 = it;
1331 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1332 move_it_by_lines (&it, 1, 0);
1333 if (charpos < IT_CHARPOS (it))
1334 {
1335 visible_p = 1;
1336 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1337 *x = it2.current_x;
1338 *y = it2.current_y + it2.max_ascent - it2.ascent;
1339 *rtop = max (0, -it2.current_y);
1340 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1341 - it.last_visible_y));
1342 }
1343 }
1344
1345 if (old_buffer)
1346 set_buffer_internal_1 (old_buffer);
1347
1348 current_header_line_height = current_mode_line_height = -1;
1349
1350 if (visible_p && XFASTINT (w->hscroll) > 0)
1351 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1352
1353 return visible_p;
1354 }
1355
1356
1357 /* Return the next character from STR which is MAXLEN bytes long.
1358 Return in *LEN the length of the character. This is like
1359 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1360 we find one, we return a `?', but with the length of the invalid
1361 character. */
1362
1363 static INLINE int
1364 string_char_and_length (str, maxlen, len)
1365 const unsigned char *str;
1366 int maxlen, *len;
1367 {
1368 int c;
1369
1370 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1371 if (!CHAR_VALID_P (c, 1))
1372 /* We may not change the length here because other places in Emacs
1373 don't use this function, i.e. they silently accept invalid
1374 characters. */
1375 c = '?';
1376
1377 return c;
1378 }
1379
1380
1381
1382 /* Given a position POS containing a valid character and byte position
1383 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1384
1385 static struct text_pos
1386 string_pos_nchars_ahead (pos, string, nchars)
1387 struct text_pos pos;
1388 Lisp_Object string;
1389 int nchars;
1390 {
1391 xassert (STRINGP (string) && nchars >= 0);
1392
1393 if (STRING_MULTIBYTE (string))
1394 {
1395 int rest = SBYTES (string) - BYTEPOS (pos);
1396 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1397 int len;
1398
1399 while (nchars--)
1400 {
1401 string_char_and_length (p, rest, &len);
1402 p += len, rest -= len;
1403 xassert (rest >= 0);
1404 CHARPOS (pos) += 1;
1405 BYTEPOS (pos) += len;
1406 }
1407 }
1408 else
1409 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1410
1411 return pos;
1412 }
1413
1414
1415 /* Value is the text position, i.e. character and byte position,
1416 for character position CHARPOS in STRING. */
1417
1418 static INLINE struct text_pos
1419 string_pos (charpos, string)
1420 int charpos;
1421 Lisp_Object string;
1422 {
1423 struct text_pos pos;
1424 xassert (STRINGP (string));
1425 xassert (charpos >= 0);
1426 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1427 return pos;
1428 }
1429
1430
1431 /* Value is a text position, i.e. character and byte position, for
1432 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1433 means recognize multibyte characters. */
1434
1435 static struct text_pos
1436 c_string_pos (charpos, s, multibyte_p)
1437 int charpos;
1438 unsigned char *s;
1439 int multibyte_p;
1440 {
1441 struct text_pos pos;
1442
1443 xassert (s != NULL);
1444 xassert (charpos >= 0);
1445
1446 if (multibyte_p)
1447 {
1448 int rest = strlen (s), len;
1449
1450 SET_TEXT_POS (pos, 0, 0);
1451 while (charpos--)
1452 {
1453 string_char_and_length (s, rest, &len);
1454 s += len, rest -= len;
1455 xassert (rest >= 0);
1456 CHARPOS (pos) += 1;
1457 BYTEPOS (pos) += len;
1458 }
1459 }
1460 else
1461 SET_TEXT_POS (pos, charpos, charpos);
1462
1463 return pos;
1464 }
1465
1466
1467 /* Value is the number of characters in C string S. MULTIBYTE_P
1468 non-zero means recognize multibyte characters. */
1469
1470 static int
1471 number_of_chars (s, multibyte_p)
1472 unsigned char *s;
1473 int multibyte_p;
1474 {
1475 int nchars;
1476
1477 if (multibyte_p)
1478 {
1479 int rest = strlen (s), len;
1480 unsigned char *p = (unsigned char *) s;
1481
1482 for (nchars = 0; rest > 0; ++nchars)
1483 {
1484 string_char_and_length (p, rest, &len);
1485 rest -= len, p += len;
1486 }
1487 }
1488 else
1489 nchars = strlen (s);
1490
1491 return nchars;
1492 }
1493
1494
1495 /* Compute byte position NEWPOS->bytepos corresponding to
1496 NEWPOS->charpos. POS is a known position in string STRING.
1497 NEWPOS->charpos must be >= POS.charpos. */
1498
1499 static void
1500 compute_string_pos (newpos, pos, string)
1501 struct text_pos *newpos, pos;
1502 Lisp_Object string;
1503 {
1504 xassert (STRINGP (string));
1505 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1506
1507 if (STRING_MULTIBYTE (string))
1508 *newpos = string_pos_nchars_ahead (pos, string,
1509 CHARPOS (*newpos) - CHARPOS (pos));
1510 else
1511 BYTEPOS (*newpos) = CHARPOS (*newpos);
1512 }
1513
1514 /* EXPORT:
1515 Return an estimation of the pixel height of mode or top lines on
1516 frame F. FACE_ID specifies what line's height to estimate. */
1517
1518 int
1519 estimate_mode_line_height (f, face_id)
1520 struct frame *f;
1521 enum face_id face_id;
1522 {
1523 #ifdef HAVE_WINDOW_SYSTEM
1524 if (FRAME_WINDOW_P (f))
1525 {
1526 int height = FONT_HEIGHT (FRAME_FONT (f));
1527
1528 /* This function is called so early when Emacs starts that the face
1529 cache and mode line face are not yet initialized. */
1530 if (FRAME_FACE_CACHE (f))
1531 {
1532 struct face *face = FACE_FROM_ID (f, face_id);
1533 if (face)
1534 {
1535 if (face->font)
1536 height = FONT_HEIGHT (face->font);
1537 if (face->box_line_width > 0)
1538 height += 2 * face->box_line_width;
1539 }
1540 }
1541
1542 return height;
1543 }
1544 #endif
1545
1546 return 1;
1547 }
1548
1549 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1550 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1551 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1552 not force the value into range. */
1553
1554 void
1555 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1556 FRAME_PTR f;
1557 register int pix_x, pix_y;
1558 int *x, *y;
1559 NativeRectangle *bounds;
1560 int noclip;
1561 {
1562
1563 #ifdef HAVE_WINDOW_SYSTEM
1564 if (FRAME_WINDOW_P (f))
1565 {
1566 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1567 even for negative values. */
1568 if (pix_x < 0)
1569 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1570 if (pix_y < 0)
1571 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1572
1573 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1574 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1575
1576 if (bounds)
1577 STORE_NATIVE_RECT (*bounds,
1578 FRAME_COL_TO_PIXEL_X (f, pix_x),
1579 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1580 FRAME_COLUMN_WIDTH (f) - 1,
1581 FRAME_LINE_HEIGHT (f) - 1);
1582
1583 if (!noclip)
1584 {
1585 if (pix_x < 0)
1586 pix_x = 0;
1587 else if (pix_x > FRAME_TOTAL_COLS (f))
1588 pix_x = FRAME_TOTAL_COLS (f);
1589
1590 if (pix_y < 0)
1591 pix_y = 0;
1592 else if (pix_y > FRAME_LINES (f))
1593 pix_y = FRAME_LINES (f);
1594 }
1595 }
1596 #endif
1597
1598 *x = pix_x;
1599 *y = pix_y;
1600 }
1601
1602
1603 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1604 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1605 can't tell the positions because W's display is not up to date,
1606 return 0. */
1607
1608 int
1609 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1610 struct window *w;
1611 int hpos, vpos;
1612 int *frame_x, *frame_y;
1613 {
1614 #ifdef HAVE_WINDOW_SYSTEM
1615 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1616 {
1617 int success_p;
1618
1619 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1620 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1621
1622 if (display_completed)
1623 {
1624 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1625 struct glyph *glyph = row->glyphs[TEXT_AREA];
1626 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1627
1628 hpos = row->x;
1629 vpos = row->y;
1630 while (glyph < end)
1631 {
1632 hpos += glyph->pixel_width;
1633 ++glyph;
1634 }
1635
1636 /* If first glyph is partially visible, its first visible position is still 0. */
1637 if (hpos < 0)
1638 hpos = 0;
1639
1640 success_p = 1;
1641 }
1642 else
1643 {
1644 hpos = vpos = 0;
1645 success_p = 0;
1646 }
1647
1648 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1649 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1650 return success_p;
1651 }
1652 #endif
1653
1654 *frame_x = hpos;
1655 *frame_y = vpos;
1656 return 1;
1657 }
1658
1659
1660 #ifdef HAVE_WINDOW_SYSTEM
1661
1662 /* Find the glyph under window-relative coordinates X/Y in window W.
1663 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1664 strings. Return in *HPOS and *VPOS the row and column number of
1665 the glyph found. Return in *AREA the glyph area containing X.
1666 Value is a pointer to the glyph found or null if X/Y is not on
1667 text, or we can't tell because W's current matrix is not up to
1668 date. */
1669
1670 static struct glyph *
1671 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1672 struct window *w;
1673 int x, y;
1674 int *hpos, *vpos, *dx, *dy, *area;
1675 {
1676 struct glyph *glyph, *end;
1677 struct glyph_row *row = NULL;
1678 int x0, i;
1679
1680 /* Find row containing Y. Give up if some row is not enabled. */
1681 for (i = 0; i < w->current_matrix->nrows; ++i)
1682 {
1683 row = MATRIX_ROW (w->current_matrix, i);
1684 if (!row->enabled_p)
1685 return NULL;
1686 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1687 break;
1688 }
1689
1690 *vpos = i;
1691 *hpos = 0;
1692
1693 /* Give up if Y is not in the window. */
1694 if (i == w->current_matrix->nrows)
1695 return NULL;
1696
1697 /* Get the glyph area containing X. */
1698 if (w->pseudo_window_p)
1699 {
1700 *area = TEXT_AREA;
1701 x0 = 0;
1702 }
1703 else
1704 {
1705 if (x < window_box_left_offset (w, TEXT_AREA))
1706 {
1707 *area = LEFT_MARGIN_AREA;
1708 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1709 }
1710 else if (x < window_box_right_offset (w, TEXT_AREA))
1711 {
1712 *area = TEXT_AREA;
1713 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1714 }
1715 else
1716 {
1717 *area = RIGHT_MARGIN_AREA;
1718 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1719 }
1720 }
1721
1722 /* Find glyph containing X. */
1723 glyph = row->glyphs[*area];
1724 end = glyph + row->used[*area];
1725 x -= x0;
1726 while (glyph < end && x >= glyph->pixel_width)
1727 {
1728 x -= glyph->pixel_width;
1729 ++glyph;
1730 }
1731
1732 if (glyph == end)
1733 return NULL;
1734
1735 if (dx)
1736 {
1737 *dx = x;
1738 *dy = y - (row->y + row->ascent - glyph->ascent);
1739 }
1740
1741 *hpos = glyph - row->glyphs[*area];
1742 return glyph;
1743 }
1744
1745
1746 /* EXPORT:
1747 Convert frame-relative x/y to coordinates relative to window W.
1748 Takes pseudo-windows into account. */
1749
1750 void
1751 frame_to_window_pixel_xy (w, x, y)
1752 struct window *w;
1753 int *x, *y;
1754 {
1755 if (w->pseudo_window_p)
1756 {
1757 /* A pseudo-window is always full-width, and starts at the
1758 left edge of the frame, plus a frame border. */
1759 struct frame *f = XFRAME (w->frame);
1760 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1761 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1762 }
1763 else
1764 {
1765 *x -= WINDOW_LEFT_EDGE_X (w);
1766 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1767 }
1768 }
1769
1770 /* EXPORT:
1771 Return in RECTS[] at most N clipping rectangles for glyph string S.
1772 Return the number of stored rectangles. */
1773
1774 int
1775 get_glyph_string_clip_rects (s, rects, n)
1776 struct glyph_string *s;
1777 NativeRectangle *rects;
1778 int n;
1779 {
1780 XRectangle r;
1781
1782 if (n <= 0)
1783 return 0;
1784
1785 if (s->row->full_width_p)
1786 {
1787 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1788 r.x = WINDOW_LEFT_EDGE_X (s->w);
1789 r.width = WINDOW_TOTAL_WIDTH (s->w);
1790
1791 /* Unless displaying a mode or menu bar line, which are always
1792 fully visible, clip to the visible part of the row. */
1793 if (s->w->pseudo_window_p)
1794 r.height = s->row->visible_height;
1795 else
1796 r.height = s->height;
1797 }
1798 else
1799 {
1800 /* This is a text line that may be partially visible. */
1801 r.x = window_box_left (s->w, s->area);
1802 r.width = window_box_width (s->w, s->area);
1803 r.height = s->row->visible_height;
1804 }
1805
1806 if (s->clip_head)
1807 if (r.x < s->clip_head->x)
1808 {
1809 if (r.width >= s->clip_head->x - r.x)
1810 r.width -= s->clip_head->x - r.x;
1811 else
1812 r.width = 0;
1813 r.x = s->clip_head->x;
1814 }
1815 if (s->clip_tail)
1816 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1817 {
1818 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1819 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1820 else
1821 r.width = 0;
1822 }
1823
1824 /* If S draws overlapping rows, it's sufficient to use the top and
1825 bottom of the window for clipping because this glyph string
1826 intentionally draws over other lines. */
1827 if (s->for_overlaps)
1828 {
1829 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1830 r.height = window_text_bottom_y (s->w) - r.y;
1831
1832 /* Alas, the above simple strategy does not work for the
1833 environments with anti-aliased text: if the same text is
1834 drawn onto the same place multiple times, it gets thicker.
1835 If the overlap we are processing is for the erased cursor, we
1836 take the intersection with the rectagle of the cursor. */
1837 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1838 {
1839 XRectangle rc, r_save = r;
1840
1841 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1842 rc.y = s->w->phys_cursor.y;
1843 rc.width = s->w->phys_cursor_width;
1844 rc.height = s->w->phys_cursor_height;
1845
1846 x_intersect_rectangles (&r_save, &rc, &r);
1847 }
1848 }
1849 else
1850 {
1851 /* Don't use S->y for clipping because it doesn't take partially
1852 visible lines into account. For example, it can be negative for
1853 partially visible lines at the top of a window. */
1854 if (!s->row->full_width_p
1855 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1856 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1857 else
1858 r.y = max (0, s->row->y);
1859
1860 /* If drawing a tool-bar window, draw it over the internal border
1861 at the top of the window. */
1862 if (WINDOWP (s->f->tool_bar_window)
1863 && s->w == XWINDOW (s->f->tool_bar_window))
1864 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1865 }
1866
1867 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1868
1869 /* If drawing the cursor, don't let glyph draw outside its
1870 advertised boundaries. Cleartype does this under some circumstances. */
1871 if (s->hl == DRAW_CURSOR)
1872 {
1873 struct glyph *glyph = s->first_glyph;
1874 int height, max_y;
1875
1876 if (s->x > r.x)
1877 {
1878 r.width -= s->x - r.x;
1879 r.x = s->x;
1880 }
1881 r.width = min (r.width, glyph->pixel_width);
1882
1883 /* If r.y is below window bottom, ensure that we still see a cursor. */
1884 height = min (glyph->ascent + glyph->descent,
1885 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1886 max_y = window_text_bottom_y (s->w) - height;
1887 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1888 if (s->ybase - glyph->ascent > max_y)
1889 {
1890 r.y = max_y;
1891 r.height = height;
1892 }
1893 else
1894 {
1895 /* Don't draw cursor glyph taller than our actual glyph. */
1896 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1897 if (height < r.height)
1898 {
1899 max_y = r.y + r.height;
1900 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1901 r.height = min (max_y - r.y, height);
1902 }
1903 }
1904 }
1905
1906 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1907 || (s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1)
1908 {
1909 #ifdef CONVERT_FROM_XRECT
1910 CONVERT_FROM_XRECT (r, *rects);
1911 #else
1912 *rects = r;
1913 #endif
1914 return 1;
1915 }
1916 else
1917 {
1918 /* If we are processing overlapping and allowed to return
1919 multiple clipping rectangles, we exclude the row of the glyph
1920 string from the clipping rectangle. This is to avoid drawing
1921 the same text on the environment with anti-aliasing. */
1922 #ifdef CONVERT_FROM_XRECT
1923 XRectangle rs[2];
1924 #else
1925 XRectangle *rs = rects;
1926 #endif
1927 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1928
1929 if (s->for_overlaps & OVERLAPS_PRED)
1930 {
1931 rs[i] = r;
1932 if (r.y + r.height > row_y)
1933 if (r.y < row_y)
1934 rs[i].height = row_y - r.y;
1935 else
1936 rs[i].height = 0;
1937 i++;
1938 }
1939 if (s->for_overlaps & OVERLAPS_SUCC)
1940 {
1941 rs[i] = r;
1942 if (r.y < row_y + s->row->visible_height)
1943 if (r.y + r.height > row_y + s->row->visible_height)
1944 {
1945 rs[i].y = row_y + s->row->visible_height;
1946 rs[i].height = r.y + r.height - rs[i].y;
1947 }
1948 else
1949 rs[i].height = 0;
1950 i++;
1951 }
1952
1953 n = i;
1954 #ifdef CONVERT_FROM_XRECT
1955 for (i = 0; i < n; i++)
1956 CONVERT_FROM_XRECT (rs[i], rects[i]);
1957 #endif
1958 return n;
1959 }
1960 }
1961
1962 /* EXPORT:
1963 Return in *NR the clipping rectangle for glyph string S. */
1964
1965 void
1966 get_glyph_string_clip_rect (s, nr)
1967 struct glyph_string *s;
1968 NativeRectangle *nr;
1969 {
1970 get_glyph_string_clip_rects (s, nr, 1);
1971 }
1972
1973
1974 /* EXPORT:
1975 Return the position and height of the phys cursor in window W.
1976 Set w->phys_cursor_width to width of phys cursor.
1977 */
1978
1979 int
1980 get_phys_cursor_geometry (w, row, glyph, heightp)
1981 struct window *w;
1982 struct glyph_row *row;
1983 struct glyph *glyph;
1984 int *heightp;
1985 {
1986 struct frame *f = XFRAME (WINDOW_FRAME (w));
1987 int y, wd, h, h0, y0;
1988
1989 /* Compute the width of the rectangle to draw. If on a stretch
1990 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1991 rectangle as wide as the glyph, but use a canonical character
1992 width instead. */
1993 wd = glyph->pixel_width - 1;
1994 #ifdef HAVE_NTGUI
1995 wd++; /* Why? */
1996 #endif
1997 if (glyph->type == STRETCH_GLYPH
1998 && !x_stretch_cursor_p)
1999 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2000 w->phys_cursor_width = wd;
2001
2002 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2003
2004 /* If y is below window bottom, ensure that we still see a cursor. */
2005 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2006
2007 h = max (h0, glyph->ascent + glyph->descent);
2008 h0 = min (h0, glyph->ascent + glyph->descent);
2009
2010 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2011 if (y < y0)
2012 {
2013 h = max (h - (y0 - y) + 1, h0);
2014 y = y0 - 1;
2015 }
2016 else
2017 {
2018 y0 = window_text_bottom_y (w) - h0;
2019 if (y > y0)
2020 {
2021 h += y - y0;
2022 y = y0;
2023 }
2024 }
2025
2026 *heightp = h - 1;
2027 return WINDOW_TO_FRAME_PIXEL_Y (w, y);
2028 }
2029
2030 /*
2031 * Remember which glyph the mouse is over.
2032 */
2033
2034 void
2035 remember_mouse_glyph (f, gx, gy, rect)
2036 struct frame *f;
2037 int gx, gy;
2038 NativeRectangle *rect;
2039 {
2040 Lisp_Object window;
2041 struct window *w;
2042 struct glyph_row *r, *gr, *end_row;
2043 enum window_part part;
2044 enum glyph_row_area area;
2045 int x, y, width, height;
2046
2047 /* Try to determine frame pixel position and size of the glyph under
2048 frame pixel coordinates X/Y on frame F. */
2049
2050 window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0);
2051 if (NILP (window))
2052 {
2053 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2054 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2055 goto virtual_glyph;
2056 }
2057
2058 w = XWINDOW (window);
2059 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2060 height = WINDOW_FRAME_LINE_HEIGHT (w);
2061
2062 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2063 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2064
2065 if (w->pseudo_window_p)
2066 {
2067 area = TEXT_AREA;
2068 part = ON_MODE_LINE; /* Don't adjust margin. */
2069 goto text_glyph;
2070 }
2071
2072 switch (part)
2073 {
2074 case ON_LEFT_MARGIN:
2075 area = LEFT_MARGIN_AREA;
2076 goto text_glyph;
2077
2078 case ON_RIGHT_MARGIN:
2079 area = RIGHT_MARGIN_AREA;
2080 goto text_glyph;
2081
2082 case ON_HEADER_LINE:
2083 case ON_MODE_LINE:
2084 gr = (part == ON_HEADER_LINE
2085 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2086 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2087 gy = gr->y;
2088 area = TEXT_AREA;
2089 goto text_glyph_row_found;
2090
2091 case ON_TEXT:
2092 area = TEXT_AREA;
2093
2094 text_glyph:
2095 gr = 0; gy = 0;
2096 for (; r <= end_row && r->enabled_p; ++r)
2097 if (r->y + r->height > y)
2098 {
2099 gr = r; gy = r->y;
2100 break;
2101 }
2102
2103 text_glyph_row_found:
2104 if (gr && gy <= y)
2105 {
2106 struct glyph *g = gr->glyphs[area];
2107 struct glyph *end = g + gr->used[area];
2108
2109 height = gr->height;
2110 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2111 if (gx + g->pixel_width > x)
2112 break;
2113
2114 if (g < end)
2115 {
2116 if (g->type == IMAGE_GLYPH)
2117 {
2118 /* Don't remember when mouse is over image, as
2119 image may have hot-spots. */
2120 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2121 return;
2122 }
2123 width = g->pixel_width;
2124 }
2125 else
2126 {
2127 /* Use nominal char spacing at end of line. */
2128 x -= gx;
2129 gx += (x / width) * width;
2130 }
2131
2132 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2133 gx += window_box_left_offset (w, area);
2134 }
2135 else
2136 {
2137 /* Use nominal line height at end of window. */
2138 gx = (x / width) * width;
2139 y -= gy;
2140 gy += (y / height) * height;
2141 }
2142 break;
2143
2144 case ON_LEFT_FRINGE:
2145 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2146 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2147 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2148 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2149 goto row_glyph;
2150
2151 case ON_RIGHT_FRINGE:
2152 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2153 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2154 : window_box_right_offset (w, TEXT_AREA));
2155 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2156 goto row_glyph;
2157
2158 case ON_SCROLL_BAR:
2159 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2160 ? 0
2161 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2162 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2163 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2164 : 0)));
2165 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2166
2167 row_glyph:
2168 gr = 0, gy = 0;
2169 for (; r <= end_row && r->enabled_p; ++r)
2170 if (r->y + r->height > y)
2171 {
2172 gr = r; gy = r->y;
2173 break;
2174 }
2175
2176 if (gr && gy <= y)
2177 height = gr->height;
2178 else
2179 {
2180 /* Use nominal line height at end of window. */
2181 y -= gy;
2182 gy += (y / height) * height;
2183 }
2184 break;
2185
2186 default:
2187 ;
2188 virtual_glyph:
2189 /* If there is no glyph under the mouse, then we divide the screen
2190 into a grid of the smallest glyph in the frame, and use that
2191 as our "glyph". */
2192
2193 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2194 round down even for negative values. */
2195 if (gx < 0)
2196 gx -= width - 1;
2197 if (gy < 0)
2198 gy -= height - 1;
2199
2200 gx = (gx / width) * width;
2201 gy = (gy / height) * height;
2202
2203 goto store_rect;
2204 }
2205
2206 gx += WINDOW_LEFT_EDGE_X (w);
2207 gy += WINDOW_TOP_EDGE_Y (w);
2208
2209 store_rect:
2210 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2211
2212 /* Visible feedback for debugging. */
2213 #if 0
2214 #if HAVE_X_WINDOWS
2215 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2216 f->output_data.x->normal_gc,
2217 gx, gy, width, height);
2218 #endif
2219 #endif
2220 }
2221
2222
2223 #endif /* HAVE_WINDOW_SYSTEM */
2224
2225 \f
2226 /***********************************************************************
2227 Lisp form evaluation
2228 ***********************************************************************/
2229
2230 /* Error handler for safe_eval and safe_call. */
2231
2232 static Lisp_Object
2233 safe_eval_handler (arg)
2234 Lisp_Object arg;
2235 {
2236 add_to_log ("Error during redisplay: %s", arg, Qnil);
2237 return Qnil;
2238 }
2239
2240
2241 /* Evaluate SEXPR and return the result, or nil if something went
2242 wrong. Prevent redisplay during the evaluation. */
2243
2244 Lisp_Object
2245 safe_eval (sexpr)
2246 Lisp_Object sexpr;
2247 {
2248 Lisp_Object val;
2249
2250 if (inhibit_eval_during_redisplay)
2251 val = Qnil;
2252 else
2253 {
2254 int count = SPECPDL_INDEX ();
2255 struct gcpro gcpro1;
2256
2257 GCPRO1 (sexpr);
2258 specbind (Qinhibit_redisplay, Qt);
2259 /* Use Qt to ensure debugger does not run,
2260 so there is no possibility of wanting to redisplay. */
2261 val = internal_condition_case_1 (Feval, sexpr, Qt,
2262 safe_eval_handler);
2263 UNGCPRO;
2264 val = unbind_to (count, val);
2265 }
2266
2267 return val;
2268 }
2269
2270
2271 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2272 Return the result, or nil if something went wrong. Prevent
2273 redisplay during the evaluation. */
2274
2275 Lisp_Object
2276 safe_call (nargs, args)
2277 int nargs;
2278 Lisp_Object *args;
2279 {
2280 Lisp_Object val;
2281
2282 if (inhibit_eval_during_redisplay)
2283 val = Qnil;
2284 else
2285 {
2286 int count = SPECPDL_INDEX ();
2287 struct gcpro gcpro1;
2288
2289 GCPRO1 (args[0]);
2290 gcpro1.nvars = nargs;
2291 specbind (Qinhibit_redisplay, Qt);
2292 /* Use Qt to ensure debugger does not run,
2293 so there is no possibility of wanting to redisplay. */
2294 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2295 safe_eval_handler);
2296 UNGCPRO;
2297 val = unbind_to (count, val);
2298 }
2299
2300 return val;
2301 }
2302
2303
2304 /* Call function FN with one argument ARG.
2305 Return the result, or nil if something went wrong. */
2306
2307 Lisp_Object
2308 safe_call1 (fn, arg)
2309 Lisp_Object fn, arg;
2310 {
2311 Lisp_Object args[2];
2312 args[0] = fn;
2313 args[1] = arg;
2314 return safe_call (2, args);
2315 }
2316
2317
2318 \f
2319 /***********************************************************************
2320 Debugging
2321 ***********************************************************************/
2322
2323 #if 0
2324
2325 /* Define CHECK_IT to perform sanity checks on iterators.
2326 This is for debugging. It is too slow to do unconditionally. */
2327
2328 static void
2329 check_it (it)
2330 struct it *it;
2331 {
2332 if (it->method == GET_FROM_STRING)
2333 {
2334 xassert (STRINGP (it->string));
2335 xassert (IT_STRING_CHARPOS (*it) >= 0);
2336 }
2337 else
2338 {
2339 xassert (IT_STRING_CHARPOS (*it) < 0);
2340 if (it->method == GET_FROM_BUFFER)
2341 {
2342 /* Check that character and byte positions agree. */
2343 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2344 }
2345 }
2346
2347 if (it->dpvec)
2348 xassert (it->current.dpvec_index >= 0);
2349 else
2350 xassert (it->current.dpvec_index < 0);
2351 }
2352
2353 #define CHECK_IT(IT) check_it ((IT))
2354
2355 #else /* not 0 */
2356
2357 #define CHECK_IT(IT) (void) 0
2358
2359 #endif /* not 0 */
2360
2361
2362 #if GLYPH_DEBUG
2363
2364 /* Check that the window end of window W is what we expect it
2365 to be---the last row in the current matrix displaying text. */
2366
2367 static void
2368 check_window_end (w)
2369 struct window *w;
2370 {
2371 if (!MINI_WINDOW_P (w)
2372 && !NILP (w->window_end_valid))
2373 {
2374 struct glyph_row *row;
2375 xassert ((row = MATRIX_ROW (w->current_matrix,
2376 XFASTINT (w->window_end_vpos)),
2377 !row->enabled_p
2378 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2379 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2380 }
2381 }
2382
2383 #define CHECK_WINDOW_END(W) check_window_end ((W))
2384
2385 #else /* not GLYPH_DEBUG */
2386
2387 #define CHECK_WINDOW_END(W) (void) 0
2388
2389 #endif /* not GLYPH_DEBUG */
2390
2391
2392 \f
2393 /***********************************************************************
2394 Iterator initialization
2395 ***********************************************************************/
2396
2397 /* Initialize IT for displaying current_buffer in window W, starting
2398 at character position CHARPOS. CHARPOS < 0 means that no buffer
2399 position is specified which is useful when the iterator is assigned
2400 a position later. BYTEPOS is the byte position corresponding to
2401 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2402
2403 If ROW is not null, calls to produce_glyphs with IT as parameter
2404 will produce glyphs in that row.
2405
2406 BASE_FACE_ID is the id of a base face to use. It must be one of
2407 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2408 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2409 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2410
2411 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2412 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2413 will be initialized to use the corresponding mode line glyph row of
2414 the desired matrix of W. */
2415
2416 void
2417 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2418 struct it *it;
2419 struct window *w;
2420 int charpos, bytepos;
2421 struct glyph_row *row;
2422 enum face_id base_face_id;
2423 {
2424 int highlight_region_p;
2425
2426 /* Some precondition checks. */
2427 xassert (w != NULL && it != NULL);
2428 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2429 && charpos <= ZV));
2430
2431 /* If face attributes have been changed since the last redisplay,
2432 free realized faces now because they depend on face definitions
2433 that might have changed. Don't free faces while there might be
2434 desired matrices pending which reference these faces. */
2435 if (face_change_count && !inhibit_free_realized_faces)
2436 {
2437 face_change_count = 0;
2438 free_all_realized_faces (Qnil);
2439 }
2440
2441 /* Use one of the mode line rows of W's desired matrix if
2442 appropriate. */
2443 if (row == NULL)
2444 {
2445 if (base_face_id == MODE_LINE_FACE_ID
2446 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2447 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2448 else if (base_face_id == HEADER_LINE_FACE_ID)
2449 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2450 }
2451
2452 /* Clear IT. */
2453 bzero (it, sizeof *it);
2454 it->current.overlay_string_index = -1;
2455 it->current.dpvec_index = -1;
2456 it->base_face_id = base_face_id;
2457 it->string = Qnil;
2458 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2459
2460 /* The window in which we iterate over current_buffer: */
2461 XSETWINDOW (it->window, w);
2462 it->w = w;
2463 it->f = XFRAME (w->frame);
2464
2465 /* Extra space between lines (on window systems only). */
2466 if (base_face_id == DEFAULT_FACE_ID
2467 && FRAME_WINDOW_P (it->f))
2468 {
2469 if (NATNUMP (current_buffer->extra_line_spacing))
2470 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2471 else if (FLOATP (current_buffer->extra_line_spacing))
2472 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2473 * FRAME_LINE_HEIGHT (it->f));
2474 else if (it->f->extra_line_spacing > 0)
2475 it->extra_line_spacing = it->f->extra_line_spacing;
2476 it->max_extra_line_spacing = 0;
2477 }
2478
2479 /* If realized faces have been removed, e.g. because of face
2480 attribute changes of named faces, recompute them. When running
2481 in batch mode, the face cache of Vterminal_frame is null. If
2482 we happen to get called, make a dummy face cache. */
2483 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2484 init_frame_faces (it->f);
2485 if (FRAME_FACE_CACHE (it->f)->used == 0)
2486 recompute_basic_faces (it->f);
2487
2488 /* Current value of the `slice', `space-width', and 'height' properties. */
2489 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2490 it->space_width = Qnil;
2491 it->font_height = Qnil;
2492 it->override_ascent = -1;
2493
2494 /* Are control characters displayed as `^C'? */
2495 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2496
2497 /* -1 means everything between a CR and the following line end
2498 is invisible. >0 means lines indented more than this value are
2499 invisible. */
2500 it->selective = (INTEGERP (current_buffer->selective_display)
2501 ? XFASTINT (current_buffer->selective_display)
2502 : (!NILP (current_buffer->selective_display)
2503 ? -1 : 0));
2504 it->selective_display_ellipsis_p
2505 = !NILP (current_buffer->selective_display_ellipses);
2506
2507 /* Display table to use. */
2508 it->dp = window_display_table (w);
2509
2510 /* Are multibyte characters enabled in current_buffer? */
2511 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2512
2513 /* Non-zero if we should highlight the region. */
2514 highlight_region_p
2515 = (!NILP (Vtransient_mark_mode)
2516 && !NILP (current_buffer->mark_active)
2517 && XMARKER (current_buffer->mark)->buffer != 0);
2518
2519 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2520 start and end of a visible region in window IT->w. Set both to
2521 -1 to indicate no region. */
2522 if (highlight_region_p
2523 /* Maybe highlight only in selected window. */
2524 && (/* Either show region everywhere. */
2525 highlight_nonselected_windows
2526 /* Or show region in the selected window. */
2527 || w == XWINDOW (selected_window)
2528 /* Or show the region if we are in the mini-buffer and W is
2529 the window the mini-buffer refers to. */
2530 || (MINI_WINDOW_P (XWINDOW (selected_window))
2531 && WINDOWP (minibuf_selected_window)
2532 && w == XWINDOW (minibuf_selected_window))))
2533 {
2534 int charpos = marker_position (current_buffer->mark);
2535 it->region_beg_charpos = min (PT, charpos);
2536 it->region_end_charpos = max (PT, charpos);
2537 }
2538 else
2539 it->region_beg_charpos = it->region_end_charpos = -1;
2540
2541 /* Get the position at which the redisplay_end_trigger hook should
2542 be run, if it is to be run at all. */
2543 if (MARKERP (w->redisplay_end_trigger)
2544 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2545 it->redisplay_end_trigger_charpos
2546 = marker_position (w->redisplay_end_trigger);
2547 else if (INTEGERP (w->redisplay_end_trigger))
2548 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2549
2550 /* Correct bogus values of tab_width. */
2551 it->tab_width = XINT (current_buffer->tab_width);
2552 if (it->tab_width <= 0 || it->tab_width > 1000)
2553 it->tab_width = 8;
2554
2555 /* Are lines in the display truncated? */
2556 it->truncate_lines_p
2557 = (base_face_id != DEFAULT_FACE_ID
2558 || XINT (it->w->hscroll)
2559 || (truncate_partial_width_windows
2560 && !WINDOW_FULL_WIDTH_P (it->w))
2561 || !NILP (current_buffer->truncate_lines));
2562
2563 /* Get dimensions of truncation and continuation glyphs. These are
2564 displayed as fringe bitmaps under X, so we don't need them for such
2565 frames. */
2566 if (!FRAME_WINDOW_P (it->f))
2567 {
2568 if (it->truncate_lines_p)
2569 {
2570 /* We will need the truncation glyph. */
2571 xassert (it->glyph_row == NULL);
2572 produce_special_glyphs (it, IT_TRUNCATION);
2573 it->truncation_pixel_width = it->pixel_width;
2574 }
2575 else
2576 {
2577 /* We will need the continuation glyph. */
2578 xassert (it->glyph_row == NULL);
2579 produce_special_glyphs (it, IT_CONTINUATION);
2580 it->continuation_pixel_width = it->pixel_width;
2581 }
2582
2583 /* Reset these values to zero because the produce_special_glyphs
2584 above has changed them. */
2585 it->pixel_width = it->ascent = it->descent = 0;
2586 it->phys_ascent = it->phys_descent = 0;
2587 }
2588
2589 /* Set this after getting the dimensions of truncation and
2590 continuation glyphs, so that we don't produce glyphs when calling
2591 produce_special_glyphs, above. */
2592 it->glyph_row = row;
2593 it->area = TEXT_AREA;
2594
2595 /* Get the dimensions of the display area. The display area
2596 consists of the visible window area plus a horizontally scrolled
2597 part to the left of the window. All x-values are relative to the
2598 start of this total display area. */
2599 if (base_face_id != DEFAULT_FACE_ID)
2600 {
2601 /* Mode lines, menu bar in terminal frames. */
2602 it->first_visible_x = 0;
2603 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2604 }
2605 else
2606 {
2607 it->first_visible_x
2608 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2609 it->last_visible_x = (it->first_visible_x
2610 + window_box_width (w, TEXT_AREA));
2611
2612 /* If we truncate lines, leave room for the truncator glyph(s) at
2613 the right margin. Otherwise, leave room for the continuation
2614 glyph(s). Truncation and continuation glyphs are not inserted
2615 for window-based redisplay. */
2616 if (!FRAME_WINDOW_P (it->f))
2617 {
2618 if (it->truncate_lines_p)
2619 it->last_visible_x -= it->truncation_pixel_width;
2620 else
2621 it->last_visible_x -= it->continuation_pixel_width;
2622 }
2623
2624 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2625 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2626 }
2627
2628 /* Leave room for a border glyph. */
2629 if (!FRAME_WINDOW_P (it->f)
2630 && !WINDOW_RIGHTMOST_P (it->w))
2631 it->last_visible_x -= 1;
2632
2633 it->last_visible_y = window_text_bottom_y (w);
2634
2635 /* For mode lines and alike, arrange for the first glyph having a
2636 left box line if the face specifies a box. */
2637 if (base_face_id != DEFAULT_FACE_ID)
2638 {
2639 struct face *face;
2640
2641 it->face_id = base_face_id;
2642
2643 /* If we have a boxed mode line, make the first character appear
2644 with a left box line. */
2645 face = FACE_FROM_ID (it->f, base_face_id);
2646 if (face->box != FACE_NO_BOX)
2647 it->start_of_box_run_p = 1;
2648 }
2649
2650 /* If a buffer position was specified, set the iterator there,
2651 getting overlays and face properties from that position. */
2652 if (charpos >= BUF_BEG (current_buffer))
2653 {
2654 it->end_charpos = ZV;
2655 it->face_id = -1;
2656 IT_CHARPOS (*it) = charpos;
2657
2658 /* Compute byte position if not specified. */
2659 if (bytepos < charpos)
2660 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2661 else
2662 IT_BYTEPOS (*it) = bytepos;
2663
2664 it->start = it->current;
2665
2666 /* Compute faces etc. */
2667 reseat (it, it->current.pos, 1);
2668 }
2669
2670 CHECK_IT (it);
2671 }
2672
2673
2674 /* Initialize IT for the display of window W with window start POS. */
2675
2676 void
2677 start_display (it, w, pos)
2678 struct it *it;
2679 struct window *w;
2680 struct text_pos pos;
2681 {
2682 struct glyph_row *row;
2683 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2684
2685 row = w->desired_matrix->rows + first_vpos;
2686 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2687 it->first_vpos = first_vpos;
2688
2689 /* Don't reseat to previous visible line start if current start
2690 position is in a string or image. */
2691 if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p)
2692 {
2693 int start_at_line_beg_p;
2694 int first_y = it->current_y;
2695
2696 /* If window start is not at a line start, skip forward to POS to
2697 get the correct continuation lines width. */
2698 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2699 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2700 if (!start_at_line_beg_p)
2701 {
2702 int new_x;
2703
2704 reseat_at_previous_visible_line_start (it);
2705 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2706
2707 new_x = it->current_x + it->pixel_width;
2708
2709 /* If lines are continued, this line may end in the middle
2710 of a multi-glyph character (e.g. a control character
2711 displayed as \003, or in the middle of an overlay
2712 string). In this case move_it_to above will not have
2713 taken us to the start of the continuation line but to the
2714 end of the continued line. */
2715 if (it->current_x > 0
2716 && !it->truncate_lines_p /* Lines are continued. */
2717 && (/* And glyph doesn't fit on the line. */
2718 new_x > it->last_visible_x
2719 /* Or it fits exactly and we're on a window
2720 system frame. */
2721 || (new_x == it->last_visible_x
2722 && FRAME_WINDOW_P (it->f))))
2723 {
2724 if (it->current.dpvec_index >= 0
2725 || it->current.overlay_string_index >= 0)
2726 {
2727 set_iterator_to_next (it, 1);
2728 move_it_in_display_line_to (it, -1, -1, 0);
2729 }
2730
2731 it->continuation_lines_width += it->current_x;
2732 }
2733
2734 /* We're starting a new display line, not affected by the
2735 height of the continued line, so clear the appropriate
2736 fields in the iterator structure. */
2737 it->max_ascent = it->max_descent = 0;
2738 it->max_phys_ascent = it->max_phys_descent = 0;
2739
2740 it->current_y = first_y;
2741 it->vpos = 0;
2742 it->current_x = it->hpos = 0;
2743 }
2744 }
2745
2746 #if 0 /* Don't assert the following because start_display is sometimes
2747 called intentionally with a window start that is not at a
2748 line start. Please leave this code in as a comment. */
2749
2750 /* Window start should be on a line start, now. */
2751 xassert (it->continuation_lines_width
2752 || IT_CHARPOS (it) == BEGV
2753 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2754 #endif /* 0 */
2755 }
2756
2757
2758 /* Return 1 if POS is a position in ellipses displayed for invisible
2759 text. W is the window we display, for text property lookup. */
2760
2761 static int
2762 in_ellipses_for_invisible_text_p (pos, w)
2763 struct display_pos *pos;
2764 struct window *w;
2765 {
2766 Lisp_Object prop, window;
2767 int ellipses_p = 0;
2768 int charpos = CHARPOS (pos->pos);
2769
2770 /* If POS specifies a position in a display vector, this might
2771 be for an ellipsis displayed for invisible text. We won't
2772 get the iterator set up for delivering that ellipsis unless
2773 we make sure that it gets aware of the invisible text. */
2774 if (pos->dpvec_index >= 0
2775 && pos->overlay_string_index < 0
2776 && CHARPOS (pos->string_pos) < 0
2777 && charpos > BEGV
2778 && (XSETWINDOW (window, w),
2779 prop = Fget_char_property (make_number (charpos),
2780 Qinvisible, window),
2781 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2782 {
2783 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2784 window);
2785 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2786 }
2787
2788 return ellipses_p;
2789 }
2790
2791
2792 /* Initialize IT for stepping through current_buffer in window W,
2793 starting at position POS that includes overlay string and display
2794 vector/ control character translation position information. Value
2795 is zero if there are overlay strings with newlines at POS. */
2796
2797 static int
2798 init_from_display_pos (it, w, pos)
2799 struct it *it;
2800 struct window *w;
2801 struct display_pos *pos;
2802 {
2803 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2804 int i, overlay_strings_with_newlines = 0;
2805
2806 /* If POS specifies a position in a display vector, this might
2807 be for an ellipsis displayed for invisible text. We won't
2808 get the iterator set up for delivering that ellipsis unless
2809 we make sure that it gets aware of the invisible text. */
2810 if (in_ellipses_for_invisible_text_p (pos, w))
2811 {
2812 --charpos;
2813 bytepos = 0;
2814 }
2815
2816 /* Keep in mind: the call to reseat in init_iterator skips invisible
2817 text, so we might end up at a position different from POS. This
2818 is only a problem when POS is a row start after a newline and an
2819 overlay starts there with an after-string, and the overlay has an
2820 invisible property. Since we don't skip invisible text in
2821 display_line and elsewhere immediately after consuming the
2822 newline before the row start, such a POS will not be in a string,
2823 but the call to init_iterator below will move us to the
2824 after-string. */
2825 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2826
2827 /* This only scans the current chunk -- it should scan all chunks.
2828 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2829 to 16 in 22.1 to make this a lesser problem. */
2830 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2831 {
2832 const char *s = SDATA (it->overlay_strings[i]);
2833 const char *e = s + SBYTES (it->overlay_strings[i]);
2834
2835 while (s < e && *s != '\n')
2836 ++s;
2837
2838 if (s < e)
2839 {
2840 overlay_strings_with_newlines = 1;
2841 break;
2842 }
2843 }
2844
2845 /* If position is within an overlay string, set up IT to the right
2846 overlay string. */
2847 if (pos->overlay_string_index >= 0)
2848 {
2849 int relative_index;
2850
2851 /* If the first overlay string happens to have a `display'
2852 property for an image, the iterator will be set up for that
2853 image, and we have to undo that setup first before we can
2854 correct the overlay string index. */
2855 if (it->method == GET_FROM_IMAGE)
2856 pop_it (it);
2857
2858 /* We already have the first chunk of overlay strings in
2859 IT->overlay_strings. Load more until the one for
2860 pos->overlay_string_index is in IT->overlay_strings. */
2861 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2862 {
2863 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2864 it->current.overlay_string_index = 0;
2865 while (n--)
2866 {
2867 load_overlay_strings (it, 0);
2868 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2869 }
2870 }
2871
2872 it->current.overlay_string_index = pos->overlay_string_index;
2873 relative_index = (it->current.overlay_string_index
2874 % OVERLAY_STRING_CHUNK_SIZE);
2875 it->string = it->overlay_strings[relative_index];
2876 xassert (STRINGP (it->string));
2877 it->current.string_pos = pos->string_pos;
2878 it->method = GET_FROM_STRING;
2879 }
2880
2881 #if 0 /* This is bogus because POS not having an overlay string
2882 position does not mean it's after the string. Example: A
2883 line starting with a before-string and initialization of IT
2884 to the previous row's end position. */
2885 else if (it->current.overlay_string_index >= 0)
2886 {
2887 /* If POS says we're already after an overlay string ending at
2888 POS, make sure to pop the iterator because it will be in
2889 front of that overlay string. When POS is ZV, we've thereby
2890 also ``processed'' overlay strings at ZV. */
2891 while (it->sp)
2892 pop_it (it);
2893 it->current.overlay_string_index = -1;
2894 it->method = GET_FROM_BUFFER;
2895 if (CHARPOS (pos->pos) == ZV)
2896 it->overlay_strings_at_end_processed_p = 1;
2897 }
2898 #endif /* 0 */
2899
2900 if (CHARPOS (pos->string_pos) >= 0)
2901 {
2902 /* Recorded position is not in an overlay string, but in another
2903 string. This can only be a string from a `display' property.
2904 IT should already be filled with that string. */
2905 it->current.string_pos = pos->string_pos;
2906 xassert (STRINGP (it->string));
2907 }
2908
2909 /* Restore position in display vector translations, control
2910 character translations or ellipses. */
2911 if (pos->dpvec_index >= 0)
2912 {
2913 if (it->dpvec == NULL)
2914 get_next_display_element (it);
2915 xassert (it->dpvec && it->current.dpvec_index == 0);
2916 it->current.dpvec_index = pos->dpvec_index;
2917 }
2918
2919 CHECK_IT (it);
2920 return !overlay_strings_with_newlines;
2921 }
2922
2923
2924 /* Initialize IT for stepping through current_buffer in window W
2925 starting at ROW->start. */
2926
2927 static void
2928 init_to_row_start (it, w, row)
2929 struct it *it;
2930 struct window *w;
2931 struct glyph_row *row;
2932 {
2933 init_from_display_pos (it, w, &row->start);
2934 it->start = row->start;
2935 it->continuation_lines_width = row->continuation_lines_width;
2936 CHECK_IT (it);
2937 }
2938
2939
2940 /* Initialize IT for stepping through current_buffer in window W
2941 starting in the line following ROW, i.e. starting at ROW->end.
2942 Value is zero if there are overlay strings with newlines at ROW's
2943 end position. */
2944
2945 static int
2946 init_to_row_end (it, w, row)
2947 struct it *it;
2948 struct window *w;
2949 struct glyph_row *row;
2950 {
2951 int success = 0;
2952
2953 if (init_from_display_pos (it, w, &row->end))
2954 {
2955 if (row->continued_p)
2956 it->continuation_lines_width
2957 = row->continuation_lines_width + row->pixel_width;
2958 CHECK_IT (it);
2959 success = 1;
2960 }
2961
2962 return success;
2963 }
2964
2965
2966
2967 \f
2968 /***********************************************************************
2969 Text properties
2970 ***********************************************************************/
2971
2972 /* Called when IT reaches IT->stop_charpos. Handle text property and
2973 overlay changes. Set IT->stop_charpos to the next position where
2974 to stop. */
2975
2976 static void
2977 handle_stop (it)
2978 struct it *it;
2979 {
2980 enum prop_handled handled;
2981 int handle_overlay_change_p;
2982 struct props *p;
2983
2984 it->dpvec = NULL;
2985 it->current.dpvec_index = -1;
2986 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
2987 it->ignore_overlay_strings_at_pos_p = 0;
2988
2989 /* Use face of preceding text for ellipsis (if invisible) */
2990 if (it->selective_display_ellipsis_p)
2991 it->saved_face_id = it->face_id;
2992
2993 do
2994 {
2995 handled = HANDLED_NORMALLY;
2996
2997 /* Call text property handlers. */
2998 for (p = it_props; p->handler; ++p)
2999 {
3000 handled = p->handler (it);
3001
3002 if (handled == HANDLED_RECOMPUTE_PROPS)
3003 break;
3004 else if (handled == HANDLED_RETURN)
3005 return;
3006 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3007 handle_overlay_change_p = 0;
3008 }
3009
3010 if (handled != HANDLED_RECOMPUTE_PROPS)
3011 {
3012 /* Don't check for overlay strings below when set to deliver
3013 characters from a display vector. */
3014 if (it->method == GET_FROM_DISPLAY_VECTOR)
3015 handle_overlay_change_p = 0;
3016
3017 /* Handle overlay changes. */
3018 if (handle_overlay_change_p)
3019 handled = handle_overlay_change (it);
3020
3021 /* Determine where to stop next. */
3022 if (handled == HANDLED_NORMALLY)
3023 compute_stop_pos (it);
3024 }
3025 }
3026 while (handled == HANDLED_RECOMPUTE_PROPS);
3027 }
3028
3029
3030 /* Compute IT->stop_charpos from text property and overlay change
3031 information for IT's current position. */
3032
3033 static void
3034 compute_stop_pos (it)
3035 struct it *it;
3036 {
3037 register INTERVAL iv, next_iv;
3038 Lisp_Object object, limit, position;
3039
3040 /* If nowhere else, stop at the end. */
3041 it->stop_charpos = it->end_charpos;
3042
3043 if (STRINGP (it->string))
3044 {
3045 /* Strings are usually short, so don't limit the search for
3046 properties. */
3047 object = it->string;
3048 limit = Qnil;
3049 position = make_number (IT_STRING_CHARPOS (*it));
3050 }
3051 else
3052 {
3053 int charpos;
3054
3055 /* If next overlay change is in front of the current stop pos
3056 (which is IT->end_charpos), stop there. Note: value of
3057 next_overlay_change is point-max if no overlay change
3058 follows. */
3059 charpos = next_overlay_change (IT_CHARPOS (*it));
3060 if (charpos < it->stop_charpos)
3061 it->stop_charpos = charpos;
3062
3063 /* If showing the region, we have to stop at the region
3064 start or end because the face might change there. */
3065 if (it->region_beg_charpos > 0)
3066 {
3067 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3068 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3069 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3070 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3071 }
3072
3073 /* Set up variables for computing the stop position from text
3074 property changes. */
3075 XSETBUFFER (object, current_buffer);
3076 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3077 position = make_number (IT_CHARPOS (*it));
3078
3079 }
3080
3081 /* Get the interval containing IT's position. Value is a null
3082 interval if there isn't such an interval. */
3083 iv = validate_interval_range (object, &position, &position, 0);
3084 if (!NULL_INTERVAL_P (iv))
3085 {
3086 Lisp_Object values_here[LAST_PROP_IDX];
3087 struct props *p;
3088
3089 /* Get properties here. */
3090 for (p = it_props; p->handler; ++p)
3091 values_here[p->idx] = textget (iv->plist, *p->name);
3092
3093 /* Look for an interval following iv that has different
3094 properties. */
3095 for (next_iv = next_interval (iv);
3096 (!NULL_INTERVAL_P (next_iv)
3097 && (NILP (limit)
3098 || XFASTINT (limit) > next_iv->position));
3099 next_iv = next_interval (next_iv))
3100 {
3101 for (p = it_props; p->handler; ++p)
3102 {
3103 Lisp_Object new_value;
3104
3105 new_value = textget (next_iv->plist, *p->name);
3106 if (!EQ (values_here[p->idx], new_value))
3107 break;
3108 }
3109
3110 if (p->handler)
3111 break;
3112 }
3113
3114 if (!NULL_INTERVAL_P (next_iv))
3115 {
3116 if (INTEGERP (limit)
3117 && next_iv->position >= XFASTINT (limit))
3118 /* No text property change up to limit. */
3119 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3120 else
3121 /* Text properties change in next_iv. */
3122 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3123 }
3124 }
3125
3126 xassert (STRINGP (it->string)
3127 || (it->stop_charpos >= BEGV
3128 && it->stop_charpos >= IT_CHARPOS (*it)));
3129 }
3130
3131
3132 /* Return the position of the next overlay change after POS in
3133 current_buffer. Value is point-max if no overlay change
3134 follows. This is like `next-overlay-change' but doesn't use
3135 xmalloc. */
3136
3137 static int
3138 next_overlay_change (pos)
3139 int pos;
3140 {
3141 int noverlays;
3142 int endpos;
3143 Lisp_Object *overlays;
3144 int i;
3145
3146 /* Get all overlays at the given position. */
3147 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3148
3149 /* If any of these overlays ends before endpos,
3150 use its ending point instead. */
3151 for (i = 0; i < noverlays; ++i)
3152 {
3153 Lisp_Object oend;
3154 int oendpos;
3155
3156 oend = OVERLAY_END (overlays[i]);
3157 oendpos = OVERLAY_POSITION (oend);
3158 endpos = min (endpos, oendpos);
3159 }
3160
3161 return endpos;
3162 }
3163
3164
3165 \f
3166 /***********************************************************************
3167 Fontification
3168 ***********************************************************************/
3169
3170 /* Handle changes in the `fontified' property of the current buffer by
3171 calling hook functions from Qfontification_functions to fontify
3172 regions of text. */
3173
3174 static enum prop_handled
3175 handle_fontified_prop (it)
3176 struct it *it;
3177 {
3178 Lisp_Object prop, pos;
3179 enum prop_handled handled = HANDLED_NORMALLY;
3180
3181 if (!NILP (Vmemory_full))
3182 return handled;
3183
3184 /* Get the value of the `fontified' property at IT's current buffer
3185 position. (The `fontified' property doesn't have a special
3186 meaning in strings.) If the value is nil, call functions from
3187 Qfontification_functions. */
3188 if (!STRINGP (it->string)
3189 && it->s == NULL
3190 && !NILP (Vfontification_functions)
3191 && !NILP (Vrun_hooks)
3192 && (pos = make_number (IT_CHARPOS (*it)),
3193 prop = Fget_char_property (pos, Qfontified, Qnil),
3194 NILP (prop)))
3195 {
3196 int count = SPECPDL_INDEX ();
3197 Lisp_Object val;
3198
3199 val = Vfontification_functions;
3200 specbind (Qfontification_functions, Qnil);
3201
3202 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3203 safe_call1 (val, pos);
3204 else
3205 {
3206 Lisp_Object globals, fn;
3207 struct gcpro gcpro1, gcpro2;
3208
3209 globals = Qnil;
3210 GCPRO2 (val, globals);
3211
3212 for (; CONSP (val); val = XCDR (val))
3213 {
3214 fn = XCAR (val);
3215
3216 if (EQ (fn, Qt))
3217 {
3218 /* A value of t indicates this hook has a local
3219 binding; it means to run the global binding too.
3220 In a global value, t should not occur. If it
3221 does, we must ignore it to avoid an endless
3222 loop. */
3223 for (globals = Fdefault_value (Qfontification_functions);
3224 CONSP (globals);
3225 globals = XCDR (globals))
3226 {
3227 fn = XCAR (globals);
3228 if (!EQ (fn, Qt))
3229 safe_call1 (fn, pos);
3230 }
3231 }
3232 else
3233 safe_call1 (fn, pos);
3234 }
3235
3236 UNGCPRO;
3237 }
3238
3239 unbind_to (count, Qnil);
3240
3241 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3242 something. This avoids an endless loop if they failed to
3243 fontify the text for which reason ever. */
3244 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3245 handled = HANDLED_RECOMPUTE_PROPS;
3246 }
3247
3248 return handled;
3249 }
3250
3251
3252 \f
3253 /***********************************************************************
3254 Faces
3255 ***********************************************************************/
3256
3257 /* Set up iterator IT from face properties at its current position.
3258 Called from handle_stop. */
3259
3260 static enum prop_handled
3261 handle_face_prop (it)
3262 struct it *it;
3263 {
3264 int new_face_id, next_stop;
3265
3266 if (!STRINGP (it->string))
3267 {
3268 new_face_id
3269 = face_at_buffer_position (it->w,
3270 IT_CHARPOS (*it),
3271 it->region_beg_charpos,
3272 it->region_end_charpos,
3273 &next_stop,
3274 (IT_CHARPOS (*it)
3275 + TEXT_PROP_DISTANCE_LIMIT),
3276 0);
3277
3278 /* Is this a start of a run of characters with box face?
3279 Caveat: this can be called for a freshly initialized
3280 iterator; face_id is -1 in this case. We know that the new
3281 face will not change until limit, i.e. if the new face has a
3282 box, all characters up to limit will have one. But, as
3283 usual, we don't know whether limit is really the end. */
3284 if (new_face_id != it->face_id)
3285 {
3286 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3287
3288 /* If new face has a box but old face has not, this is
3289 the start of a run of characters with box, i.e. it has
3290 a shadow on the left side. The value of face_id of the
3291 iterator will be -1 if this is the initial call that gets
3292 the face. In this case, we have to look in front of IT's
3293 position and see whether there is a face != new_face_id. */
3294 it->start_of_box_run_p
3295 = (new_face->box != FACE_NO_BOX
3296 && (it->face_id >= 0
3297 || IT_CHARPOS (*it) == BEG
3298 || new_face_id != face_before_it_pos (it)));
3299 it->face_box_p = new_face->box != FACE_NO_BOX;
3300 }
3301 }
3302 else
3303 {
3304 int base_face_id, bufpos;
3305
3306 if (it->current.overlay_string_index >= 0)
3307 bufpos = IT_CHARPOS (*it);
3308 else
3309 bufpos = 0;
3310
3311 /* For strings from a buffer, i.e. overlay strings or strings
3312 from a `display' property, use the face at IT's current
3313 buffer position as the base face to merge with, so that
3314 overlay strings appear in the same face as surrounding
3315 text, unless they specify their own faces. */
3316 base_face_id = underlying_face_id (it);
3317
3318 new_face_id = face_at_string_position (it->w,
3319 it->string,
3320 IT_STRING_CHARPOS (*it),
3321 bufpos,
3322 it->region_beg_charpos,
3323 it->region_end_charpos,
3324 &next_stop,
3325 base_face_id, 0);
3326
3327 #if 0 /* This shouldn't be neccessary. Let's check it. */
3328 /* If IT is used to display a mode line we would really like to
3329 use the mode line face instead of the frame's default face. */
3330 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3331 && new_face_id == DEFAULT_FACE_ID)
3332 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3333 #endif
3334
3335 /* Is this a start of a run of characters with box? Caveat:
3336 this can be called for a freshly allocated iterator; face_id
3337 is -1 is this case. We know that the new face will not
3338 change until the next check pos, i.e. if the new face has a
3339 box, all characters up to that position will have a
3340 box. But, as usual, we don't know whether that position
3341 is really the end. */
3342 if (new_face_id != it->face_id)
3343 {
3344 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3345 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3346
3347 /* If new face has a box but old face hasn't, this is the
3348 start of a run of characters with box, i.e. it has a
3349 shadow on the left side. */
3350 it->start_of_box_run_p
3351 = new_face->box && (old_face == NULL || !old_face->box);
3352 it->face_box_p = new_face->box != FACE_NO_BOX;
3353 }
3354 }
3355
3356 it->face_id = new_face_id;
3357 return HANDLED_NORMALLY;
3358 }
3359
3360
3361 /* Return the ID of the face ``underlying'' IT's current position,
3362 which is in a string. If the iterator is associated with a
3363 buffer, return the face at IT's current buffer position.
3364 Otherwise, use the iterator's base_face_id. */
3365
3366 static int
3367 underlying_face_id (it)
3368 struct it *it;
3369 {
3370 int face_id = it->base_face_id, i;
3371
3372 xassert (STRINGP (it->string));
3373
3374 for (i = it->sp - 1; i >= 0; --i)
3375 if (NILP (it->stack[i].string))
3376 face_id = it->stack[i].face_id;
3377
3378 return face_id;
3379 }
3380
3381
3382 /* Compute the face one character before or after the current position
3383 of IT. BEFORE_P non-zero means get the face in front of IT's
3384 position. Value is the id of the face. */
3385
3386 static int
3387 face_before_or_after_it_pos (it, before_p)
3388 struct it *it;
3389 int before_p;
3390 {
3391 int face_id, limit;
3392 int next_check_charpos;
3393 struct text_pos pos;
3394
3395 xassert (it->s == NULL);
3396
3397 if (STRINGP (it->string))
3398 {
3399 int bufpos, base_face_id;
3400
3401 /* No face change past the end of the string (for the case
3402 we are padding with spaces). No face change before the
3403 string start. */
3404 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3405 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3406 return it->face_id;
3407
3408 /* Set pos to the position before or after IT's current position. */
3409 if (before_p)
3410 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3411 else
3412 /* For composition, we must check the character after the
3413 composition. */
3414 pos = (it->what == IT_COMPOSITION
3415 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3416 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3417
3418 if (it->current.overlay_string_index >= 0)
3419 bufpos = IT_CHARPOS (*it);
3420 else
3421 bufpos = 0;
3422
3423 base_face_id = underlying_face_id (it);
3424
3425 /* Get the face for ASCII, or unibyte. */
3426 face_id = face_at_string_position (it->w,
3427 it->string,
3428 CHARPOS (pos),
3429 bufpos,
3430 it->region_beg_charpos,
3431 it->region_end_charpos,
3432 &next_check_charpos,
3433 base_face_id, 0);
3434
3435 /* Correct the face for charsets different from ASCII. Do it
3436 for the multibyte case only. The face returned above is
3437 suitable for unibyte text if IT->string is unibyte. */
3438 if (STRING_MULTIBYTE (it->string))
3439 {
3440 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3441 int rest = SBYTES (it->string) - BYTEPOS (pos);
3442 int c, len;
3443 struct face *face = FACE_FROM_ID (it->f, face_id);
3444
3445 c = string_char_and_length (p, rest, &len);
3446 face_id = FACE_FOR_CHAR (it->f, face, c);
3447 }
3448 }
3449 else
3450 {
3451 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3452 || (IT_CHARPOS (*it) <= BEGV && before_p))
3453 return it->face_id;
3454
3455 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3456 pos = it->current.pos;
3457
3458 if (before_p)
3459 DEC_TEXT_POS (pos, it->multibyte_p);
3460 else
3461 {
3462 if (it->what == IT_COMPOSITION)
3463 /* For composition, we must check the position after the
3464 composition. */
3465 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3466 else
3467 INC_TEXT_POS (pos, it->multibyte_p);
3468 }
3469
3470 /* Determine face for CHARSET_ASCII, or unibyte. */
3471 face_id = face_at_buffer_position (it->w,
3472 CHARPOS (pos),
3473 it->region_beg_charpos,
3474 it->region_end_charpos,
3475 &next_check_charpos,
3476 limit, 0);
3477
3478 /* Correct the face for charsets different from ASCII. Do it
3479 for the multibyte case only. The face returned above is
3480 suitable for unibyte text if current_buffer is unibyte. */
3481 if (it->multibyte_p)
3482 {
3483 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3484 struct face *face = FACE_FROM_ID (it->f, face_id);
3485 face_id = FACE_FOR_CHAR (it->f, face, c);
3486 }
3487 }
3488
3489 return face_id;
3490 }
3491
3492
3493 \f
3494 /***********************************************************************
3495 Invisible text
3496 ***********************************************************************/
3497
3498 /* Set up iterator IT from invisible properties at its current
3499 position. Called from handle_stop. */
3500
3501 static enum prop_handled
3502 handle_invisible_prop (it)
3503 struct it *it;
3504 {
3505 enum prop_handled handled = HANDLED_NORMALLY;
3506
3507 if (STRINGP (it->string))
3508 {
3509 extern Lisp_Object Qinvisible;
3510 Lisp_Object prop, end_charpos, limit, charpos;
3511
3512 /* Get the value of the invisible text property at the
3513 current position. Value will be nil if there is no such
3514 property. */
3515 charpos = make_number (IT_STRING_CHARPOS (*it));
3516 prop = Fget_text_property (charpos, Qinvisible, it->string);
3517
3518 if (!NILP (prop)
3519 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3520 {
3521 handled = HANDLED_RECOMPUTE_PROPS;
3522
3523 /* Get the position at which the next change of the
3524 invisible text property can be found in IT->string.
3525 Value will be nil if the property value is the same for
3526 all the rest of IT->string. */
3527 XSETINT (limit, SCHARS (it->string));
3528 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3529 it->string, limit);
3530
3531 /* Text at current position is invisible. The next
3532 change in the property is at position end_charpos.
3533 Move IT's current position to that position. */
3534 if (INTEGERP (end_charpos)
3535 && XFASTINT (end_charpos) < XFASTINT (limit))
3536 {
3537 struct text_pos old;
3538 old = it->current.string_pos;
3539 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3540 compute_string_pos (&it->current.string_pos, old, it->string);
3541 }
3542 else
3543 {
3544 /* The rest of the string is invisible. If this is an
3545 overlay string, proceed with the next overlay string
3546 or whatever comes and return a character from there. */
3547 if (it->current.overlay_string_index >= 0)
3548 {
3549 next_overlay_string (it);
3550 /* Don't check for overlay strings when we just
3551 finished processing them. */
3552 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3553 }
3554 else
3555 {
3556 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3557 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3558 }
3559 }
3560 }
3561 }
3562 else
3563 {
3564 int invis_p, newpos, next_stop, start_charpos;
3565 Lisp_Object pos, prop, overlay;
3566
3567 /* First of all, is there invisible text at this position? */
3568 start_charpos = IT_CHARPOS (*it);
3569 pos = make_number (IT_CHARPOS (*it));
3570 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3571 &overlay);
3572 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3573
3574 /* If we are on invisible text, skip over it. */
3575 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3576 {
3577 /* Record whether we have to display an ellipsis for the
3578 invisible text. */
3579 int display_ellipsis_p = invis_p == 2;
3580
3581 handled = HANDLED_RECOMPUTE_PROPS;
3582
3583 /* Loop skipping over invisible text. The loop is left at
3584 ZV or with IT on the first char being visible again. */
3585 do
3586 {
3587 /* Try to skip some invisible text. Return value is the
3588 position reached which can be equal to IT's position
3589 if there is nothing invisible here. This skips both
3590 over invisible text properties and overlays with
3591 invisible property. */
3592 newpos = skip_invisible (IT_CHARPOS (*it),
3593 &next_stop, ZV, it->window);
3594
3595 /* If we skipped nothing at all we weren't at invisible
3596 text in the first place. If everything to the end of
3597 the buffer was skipped, end the loop. */
3598 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3599 invis_p = 0;
3600 else
3601 {
3602 /* We skipped some characters but not necessarily
3603 all there are. Check if we ended up on visible
3604 text. Fget_char_property returns the property of
3605 the char before the given position, i.e. if we
3606 get invis_p = 0, this means that the char at
3607 newpos is visible. */
3608 pos = make_number (newpos);
3609 prop = Fget_char_property (pos, Qinvisible, it->window);
3610 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3611 }
3612
3613 /* If we ended up on invisible text, proceed to
3614 skip starting with next_stop. */
3615 if (invis_p)
3616 IT_CHARPOS (*it) = next_stop;
3617
3618 /* If there are adjacent invisible texts, don't lose the
3619 second one's ellipsis. */
3620 if (invis_p == 2)
3621 display_ellipsis_p = 1;
3622 }
3623 while (invis_p);
3624
3625 /* The position newpos is now either ZV or on visible text. */
3626 IT_CHARPOS (*it) = newpos;
3627 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3628
3629 /* If there are before-strings at the start of invisible
3630 text, and the text is invisible because of a text
3631 property, arrange to show before-strings because 20.x did
3632 it that way. (If the text is invisible because of an
3633 overlay property instead of a text property, this is
3634 already handled in the overlay code.) */
3635 if (NILP (overlay)
3636 && get_overlay_strings (it, start_charpos))
3637 {
3638 handled = HANDLED_RECOMPUTE_PROPS;
3639 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3640 }
3641 else if (display_ellipsis_p)
3642 {
3643 /* Make sure that the glyphs of the ellipsis will get
3644 correct `charpos' values. If we would not update
3645 it->position here, the glyphs would belong to the
3646 last visible character _before_ the invisible
3647 text, which confuses `set_cursor_from_row'.
3648
3649 We use the last invisible position instead of the
3650 first because this way the cursor is always drawn on
3651 the first "." of the ellipsis, whenever PT is inside
3652 the invisible text. Otherwise the cursor would be
3653 placed _after_ the ellipsis when the point is after the
3654 first invisible character. */
3655 it->position.charpos = IT_CHARPOS (*it) - 1;
3656 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3657 setup_for_ellipsis (it, 0);
3658 }
3659 }
3660 }
3661
3662 return handled;
3663 }
3664
3665
3666 /* Make iterator IT return `...' next.
3667 Replaces LEN characters from buffer. */
3668
3669 static void
3670 setup_for_ellipsis (it, len)
3671 struct it *it;
3672 int len;
3673 {
3674 /* Use the display table definition for `...'. Invalid glyphs
3675 will be handled by the method returning elements from dpvec. */
3676 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3677 {
3678 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3679 it->dpvec = v->contents;
3680 it->dpend = v->contents + v->size;
3681 }
3682 else
3683 {
3684 /* Default `...'. */
3685 it->dpvec = default_invis_vector;
3686 it->dpend = default_invis_vector + 3;
3687 }
3688
3689 it->dpvec_char_len = len;
3690 it->current.dpvec_index = 0;
3691 it->dpvec_face_id = -1;
3692
3693 /* Remember the current face id in case glyphs specify faces.
3694 IT's face is restored in set_iterator_to_next.
3695 saved_face_id was set to preceding char's face in handle_stop. */
3696 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3697 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3698
3699 it->method = GET_FROM_DISPLAY_VECTOR;
3700 it->ellipsis_p = 1;
3701 }
3702
3703
3704 \f
3705 /***********************************************************************
3706 'display' property
3707 ***********************************************************************/
3708
3709 /* Set up iterator IT from `display' property at its current position.
3710 Called from handle_stop.
3711 We return HANDLED_RETURN if some part of the display property
3712 overrides the display of the buffer text itself.
3713 Otherwise we return HANDLED_NORMALLY. */
3714
3715 static enum prop_handled
3716 handle_display_prop (it)
3717 struct it *it;
3718 {
3719 Lisp_Object prop, object;
3720 struct text_pos *position;
3721 /* Nonzero if some property replaces the display of the text itself. */
3722 int display_replaced_p = 0;
3723
3724 if (STRINGP (it->string))
3725 {
3726 object = it->string;
3727 position = &it->current.string_pos;
3728 }
3729 else
3730 {
3731 XSETWINDOW (object, it->w);
3732 position = &it->current.pos;
3733 }
3734
3735 /* Reset those iterator values set from display property values. */
3736 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3737 it->space_width = Qnil;
3738 it->font_height = Qnil;
3739 it->voffset = 0;
3740
3741 /* We don't support recursive `display' properties, i.e. string
3742 values that have a string `display' property, that have a string
3743 `display' property etc. */
3744 if (!it->string_from_display_prop_p)
3745 it->area = TEXT_AREA;
3746
3747 prop = Fget_char_property (make_number (position->charpos),
3748 Qdisplay, object);
3749 if (NILP (prop))
3750 return HANDLED_NORMALLY;
3751
3752 if (!STRINGP (it->string))
3753 object = it->w->buffer;
3754
3755 if (CONSP (prop)
3756 /* Simple properties. */
3757 && !EQ (XCAR (prop), Qimage)
3758 && !EQ (XCAR (prop), Qspace)
3759 && !EQ (XCAR (prop), Qwhen)
3760 && !EQ (XCAR (prop), Qslice)
3761 && !EQ (XCAR (prop), Qspace_width)
3762 && !EQ (XCAR (prop), Qheight)
3763 && !EQ (XCAR (prop), Qraise)
3764 /* Marginal area specifications. */
3765 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3766 && !EQ (XCAR (prop), Qleft_fringe)
3767 && !EQ (XCAR (prop), Qright_fringe)
3768 && !NILP (XCAR (prop)))
3769 {
3770 for (; CONSP (prop); prop = XCDR (prop))
3771 {
3772 if (handle_single_display_spec (it, XCAR (prop), object,
3773 position, display_replaced_p))
3774 display_replaced_p = 1;
3775 }
3776 }
3777 else if (VECTORP (prop))
3778 {
3779 int i;
3780 for (i = 0; i < ASIZE (prop); ++i)
3781 if (handle_single_display_spec (it, AREF (prop, i), object,
3782 position, display_replaced_p))
3783 display_replaced_p = 1;
3784 }
3785 else
3786 {
3787 int ret = handle_single_display_spec (it, prop, object, position, 0);
3788 if (ret < 0) /* Replaced by "", i.e. nothing. */
3789 return HANDLED_RECOMPUTE_PROPS;
3790 if (ret)
3791 display_replaced_p = 1;
3792 }
3793
3794 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3795 }
3796
3797
3798 /* Value is the position of the end of the `display' property starting
3799 at START_POS in OBJECT. */
3800
3801 static struct text_pos
3802 display_prop_end (it, object, start_pos)
3803 struct it *it;
3804 Lisp_Object object;
3805 struct text_pos start_pos;
3806 {
3807 Lisp_Object end;
3808 struct text_pos end_pos;
3809
3810 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3811 Qdisplay, object, Qnil);
3812 CHARPOS (end_pos) = XFASTINT (end);
3813 if (STRINGP (object))
3814 compute_string_pos (&end_pos, start_pos, it->string);
3815 else
3816 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3817
3818 return end_pos;
3819 }
3820
3821
3822 /* Set up IT from a single `display' specification PROP. OBJECT
3823 is the object in which the `display' property was found. *POSITION
3824 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3825 means that we previously saw a display specification which already
3826 replaced text display with something else, for example an image;
3827 we ignore such properties after the first one has been processed.
3828
3829 If PROP is a `space' or `image' specification, and in some other
3830 cases too, set *POSITION to the position where the `display'
3831 property ends.
3832
3833 Value is non-zero if something was found which replaces the display
3834 of buffer or string text. Specifically, the value is -1 if that
3835 "something" is "nothing". */
3836
3837 static int
3838 handle_single_display_spec (it, spec, object, position,
3839 display_replaced_before_p)
3840 struct it *it;
3841 Lisp_Object spec;
3842 Lisp_Object object;
3843 struct text_pos *position;
3844 int display_replaced_before_p;
3845 {
3846 Lisp_Object form;
3847 Lisp_Object location, value;
3848 struct text_pos start_pos;
3849 int valid_p;
3850
3851 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3852 If the result is non-nil, use VALUE instead of SPEC. */
3853 form = Qt;
3854 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3855 {
3856 spec = XCDR (spec);
3857 if (!CONSP (spec))
3858 return 0;
3859 form = XCAR (spec);
3860 spec = XCDR (spec);
3861 }
3862
3863 if (!NILP (form) && !EQ (form, Qt))
3864 {
3865 int count = SPECPDL_INDEX ();
3866 struct gcpro gcpro1;
3867
3868 /* Bind `object' to the object having the `display' property, a
3869 buffer or string. Bind `position' to the position in the
3870 object where the property was found, and `buffer-position'
3871 to the current position in the buffer. */
3872 specbind (Qobject, object);
3873 specbind (Qposition, make_number (CHARPOS (*position)));
3874 specbind (Qbuffer_position,
3875 make_number (STRINGP (object)
3876 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3877 GCPRO1 (form);
3878 form = safe_eval (form);
3879 UNGCPRO;
3880 unbind_to (count, Qnil);
3881 }
3882
3883 if (NILP (form))
3884 return 0;
3885
3886 /* Handle `(height HEIGHT)' specifications. */
3887 if (CONSP (spec)
3888 && EQ (XCAR (spec), Qheight)
3889 && CONSP (XCDR (spec)))
3890 {
3891 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3892 return 0;
3893
3894 it->font_height = XCAR (XCDR (spec));
3895 if (!NILP (it->font_height))
3896 {
3897 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3898 int new_height = -1;
3899
3900 if (CONSP (it->font_height)
3901 && (EQ (XCAR (it->font_height), Qplus)
3902 || EQ (XCAR (it->font_height), Qminus))
3903 && CONSP (XCDR (it->font_height))
3904 && INTEGERP (XCAR (XCDR (it->font_height))))
3905 {
3906 /* `(+ N)' or `(- N)' where N is an integer. */
3907 int steps = XINT (XCAR (XCDR (it->font_height)));
3908 if (EQ (XCAR (it->font_height), Qplus))
3909 steps = - steps;
3910 it->face_id = smaller_face (it->f, it->face_id, steps);
3911 }
3912 else if (FUNCTIONP (it->font_height))
3913 {
3914 /* Call function with current height as argument.
3915 Value is the new height. */
3916 Lisp_Object height;
3917 height = safe_call1 (it->font_height,
3918 face->lface[LFACE_HEIGHT_INDEX]);
3919 if (NUMBERP (height))
3920 new_height = XFLOATINT (height);
3921 }
3922 else if (NUMBERP (it->font_height))
3923 {
3924 /* Value is a multiple of the canonical char height. */
3925 struct face *face;
3926
3927 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3928 new_height = (XFLOATINT (it->font_height)
3929 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3930 }
3931 else
3932 {
3933 /* Evaluate IT->font_height with `height' bound to the
3934 current specified height to get the new height. */
3935 int count = SPECPDL_INDEX ();
3936
3937 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3938 value = safe_eval (it->font_height);
3939 unbind_to (count, Qnil);
3940
3941 if (NUMBERP (value))
3942 new_height = XFLOATINT (value);
3943 }
3944
3945 if (new_height > 0)
3946 it->face_id = face_with_height (it->f, it->face_id, new_height);
3947 }
3948
3949 return 0;
3950 }
3951
3952 /* Handle `(space_width WIDTH)'. */
3953 if (CONSP (spec)
3954 && EQ (XCAR (spec), Qspace_width)
3955 && CONSP (XCDR (spec)))
3956 {
3957 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3958 return 0;
3959
3960 value = XCAR (XCDR (spec));
3961 if (NUMBERP (value) && XFLOATINT (value) > 0)
3962 it->space_width = value;
3963
3964 return 0;
3965 }
3966
3967 /* Handle `(slice X Y WIDTH HEIGHT)'. */
3968 if (CONSP (spec)
3969 && EQ (XCAR (spec), Qslice))
3970 {
3971 Lisp_Object tem;
3972
3973 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3974 return 0;
3975
3976 if (tem = XCDR (spec), CONSP (tem))
3977 {
3978 it->slice.x = XCAR (tem);
3979 if (tem = XCDR (tem), CONSP (tem))
3980 {
3981 it->slice.y = XCAR (tem);
3982 if (tem = XCDR (tem), CONSP (tem))
3983 {
3984 it->slice.width = XCAR (tem);
3985 if (tem = XCDR (tem), CONSP (tem))
3986 it->slice.height = XCAR (tem);
3987 }
3988 }
3989 }
3990
3991 return 0;
3992 }
3993
3994 /* Handle `(raise FACTOR)'. */
3995 if (CONSP (spec)
3996 && EQ (XCAR (spec), Qraise)
3997 && CONSP (XCDR (spec)))
3998 {
3999 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
4000 return 0;
4001
4002 #ifdef HAVE_WINDOW_SYSTEM
4003 value = XCAR (XCDR (spec));
4004 if (NUMBERP (value))
4005 {
4006 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4007 it->voffset = - (XFLOATINT (value)
4008 * (FONT_HEIGHT (face->font)));
4009 }
4010 #endif /* HAVE_WINDOW_SYSTEM */
4011
4012 return 0;
4013 }
4014
4015 /* Don't handle the other kinds of display specifications
4016 inside a string that we got from a `display' property. */
4017 if (it->string_from_display_prop_p)
4018 return 0;
4019
4020 /* Characters having this form of property are not displayed, so
4021 we have to find the end of the property. */
4022 start_pos = *position;
4023 *position = display_prop_end (it, object, start_pos);
4024 value = Qnil;
4025
4026 /* Stop the scan at that end position--we assume that all
4027 text properties change there. */
4028 it->stop_charpos = position->charpos;
4029
4030 /* Handle `(left-fringe BITMAP [FACE])'
4031 and `(right-fringe BITMAP [FACE])'. */
4032 if (CONSP (spec)
4033 && (EQ (XCAR (spec), Qleft_fringe)
4034 || EQ (XCAR (spec), Qright_fringe))
4035 && CONSP (XCDR (spec)))
4036 {
4037 int face_id = DEFAULT_FACE_ID;
4038 int fringe_bitmap;
4039
4040 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
4041 /* If we return here, POSITION has been advanced
4042 across the text with this property. */
4043 return 0;
4044
4045 #ifdef HAVE_WINDOW_SYSTEM
4046 value = XCAR (XCDR (spec));
4047 if (!SYMBOLP (value)
4048 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4049 /* If we return here, POSITION has been advanced
4050 across the text with this property. */
4051 return 0;
4052
4053 if (CONSP (XCDR (XCDR (spec))))
4054 {
4055 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4056 int face_id2 = lookup_derived_face (it->f, face_name,
4057 'A', FRINGE_FACE_ID, 0);
4058 if (face_id2 >= 0)
4059 face_id = face_id2;
4060 }
4061
4062 /* Save current settings of IT so that we can restore them
4063 when we are finished with the glyph property value. */
4064
4065 push_it (it);
4066
4067 it->area = TEXT_AREA;
4068 it->what = IT_IMAGE;
4069 it->image_id = -1; /* no image */
4070 it->position = start_pos;
4071 it->object = NILP (object) ? it->w->buffer : object;
4072 it->method = GET_FROM_IMAGE;
4073 it->face_id = face_id;
4074
4075 /* Say that we haven't consumed the characters with
4076 `display' property yet. The call to pop_it in
4077 set_iterator_to_next will clean this up. */
4078 *position = start_pos;
4079
4080 if (EQ (XCAR (spec), Qleft_fringe))
4081 {
4082 it->left_user_fringe_bitmap = fringe_bitmap;
4083 it->left_user_fringe_face_id = face_id;
4084 }
4085 else
4086 {
4087 it->right_user_fringe_bitmap = fringe_bitmap;
4088 it->right_user_fringe_face_id = face_id;
4089 }
4090 #endif /* HAVE_WINDOW_SYSTEM */
4091 return 1;
4092 }
4093
4094 /* Prepare to handle `((margin left-margin) ...)',
4095 `((margin right-margin) ...)' and `((margin nil) ...)'
4096 prefixes for display specifications. */
4097 location = Qunbound;
4098 if (CONSP (spec) && CONSP (XCAR (spec)))
4099 {
4100 Lisp_Object tem;
4101
4102 value = XCDR (spec);
4103 if (CONSP (value))
4104 value = XCAR (value);
4105
4106 tem = XCAR (spec);
4107 if (EQ (XCAR (tem), Qmargin)
4108 && (tem = XCDR (tem),
4109 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4110 (NILP (tem)
4111 || EQ (tem, Qleft_margin)
4112 || EQ (tem, Qright_margin))))
4113 location = tem;
4114 }
4115
4116 if (EQ (location, Qunbound))
4117 {
4118 location = Qnil;
4119 value = spec;
4120 }
4121
4122 /* After this point, VALUE is the property after any
4123 margin prefix has been stripped. It must be a string,
4124 an image specification, or `(space ...)'.
4125
4126 LOCATION specifies where to display: `left-margin',
4127 `right-margin' or nil. */
4128
4129 valid_p = (STRINGP (value)
4130 #ifdef HAVE_WINDOW_SYSTEM
4131 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
4132 #endif /* not HAVE_WINDOW_SYSTEM */
4133 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4134
4135 if (valid_p && !display_replaced_before_p)
4136 {
4137 /* Save current settings of IT so that we can restore them
4138 when we are finished with the glyph property value. */
4139 push_it (it);
4140
4141 if (NILP (location))
4142 it->area = TEXT_AREA;
4143 else if (EQ (location, Qleft_margin))
4144 it->area = LEFT_MARGIN_AREA;
4145 else
4146 it->area = RIGHT_MARGIN_AREA;
4147
4148 if (STRINGP (value))
4149 {
4150 if (SCHARS (value) == 0)
4151 {
4152 pop_it (it);
4153 return -1; /* Replaced by "", i.e. nothing. */
4154 }
4155 it->string = value;
4156 it->multibyte_p = STRING_MULTIBYTE (it->string);
4157 it->current.overlay_string_index = -1;
4158 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4159 it->end_charpos = it->string_nchars = SCHARS (it->string);
4160 it->method = GET_FROM_STRING;
4161 it->stop_charpos = 0;
4162 it->string_from_display_prop_p = 1;
4163 /* Say that we haven't consumed the characters with
4164 `display' property yet. The call to pop_it in
4165 set_iterator_to_next will clean this up. */
4166 *position = start_pos;
4167 }
4168 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4169 {
4170 it->method = GET_FROM_STRETCH;
4171 it->object = value;
4172 *position = it->position = start_pos;
4173 }
4174 #ifdef HAVE_WINDOW_SYSTEM
4175 else
4176 {
4177 it->what = IT_IMAGE;
4178 it->image_id = lookup_image (it->f, value);
4179 it->position = start_pos;
4180 it->object = NILP (object) ? it->w->buffer : object;
4181 it->method = GET_FROM_IMAGE;
4182
4183 /* Say that we haven't consumed the characters with
4184 `display' property yet. The call to pop_it in
4185 set_iterator_to_next will clean this up. */
4186 *position = start_pos;
4187 }
4188 #endif /* HAVE_WINDOW_SYSTEM */
4189
4190 return 1;
4191 }
4192
4193 /* Invalid property or property not supported. Restore
4194 POSITION to what it was before. */
4195 *position = start_pos;
4196 return 0;
4197 }
4198
4199
4200 /* Check if SPEC is a display specification value whose text should be
4201 treated as intangible. */
4202
4203 static int
4204 single_display_spec_intangible_p (prop)
4205 Lisp_Object prop;
4206 {
4207 /* Skip over `when FORM'. */
4208 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4209 {
4210 prop = XCDR (prop);
4211 if (!CONSP (prop))
4212 return 0;
4213 prop = XCDR (prop);
4214 }
4215
4216 if (STRINGP (prop))
4217 return 1;
4218
4219 if (!CONSP (prop))
4220 return 0;
4221
4222 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4223 we don't need to treat text as intangible. */
4224 if (EQ (XCAR (prop), Qmargin))
4225 {
4226 prop = XCDR (prop);
4227 if (!CONSP (prop))
4228 return 0;
4229
4230 prop = XCDR (prop);
4231 if (!CONSP (prop)
4232 || EQ (XCAR (prop), Qleft_margin)
4233 || EQ (XCAR (prop), Qright_margin))
4234 return 0;
4235 }
4236
4237 return (CONSP (prop)
4238 && (EQ (XCAR (prop), Qimage)
4239 || EQ (XCAR (prop), Qspace)));
4240 }
4241
4242
4243 /* Check if PROP is a display property value whose text should be
4244 treated as intangible. */
4245
4246 int
4247 display_prop_intangible_p (prop)
4248 Lisp_Object prop;
4249 {
4250 if (CONSP (prop)
4251 && CONSP (XCAR (prop))
4252 && !EQ (Qmargin, XCAR (XCAR (prop))))
4253 {
4254 /* A list of sub-properties. */
4255 while (CONSP (prop))
4256 {
4257 if (single_display_spec_intangible_p (XCAR (prop)))
4258 return 1;
4259 prop = XCDR (prop);
4260 }
4261 }
4262 else if (VECTORP (prop))
4263 {
4264 /* A vector of sub-properties. */
4265 int i;
4266 for (i = 0; i < ASIZE (prop); ++i)
4267 if (single_display_spec_intangible_p (AREF (prop, i)))
4268 return 1;
4269 }
4270 else
4271 return single_display_spec_intangible_p (prop);
4272
4273 return 0;
4274 }
4275
4276
4277 /* Return 1 if PROP is a display sub-property value containing STRING. */
4278
4279 static int
4280 single_display_spec_string_p (prop, string)
4281 Lisp_Object prop, string;
4282 {
4283 if (EQ (string, prop))
4284 return 1;
4285
4286 /* Skip over `when FORM'. */
4287 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4288 {
4289 prop = XCDR (prop);
4290 if (!CONSP (prop))
4291 return 0;
4292 prop = XCDR (prop);
4293 }
4294
4295 if (CONSP (prop))
4296 /* Skip over `margin LOCATION'. */
4297 if (EQ (XCAR (prop), Qmargin))
4298 {
4299 prop = XCDR (prop);
4300 if (!CONSP (prop))
4301 return 0;
4302
4303 prop = XCDR (prop);
4304 if (!CONSP (prop))
4305 return 0;
4306 }
4307
4308 return CONSP (prop) && EQ (XCAR (prop), string);
4309 }
4310
4311
4312 /* Return 1 if STRING appears in the `display' property PROP. */
4313
4314 static int
4315 display_prop_string_p (prop, string)
4316 Lisp_Object prop, string;
4317 {
4318 if (CONSP (prop)
4319 && CONSP (XCAR (prop))
4320 && !EQ (Qmargin, XCAR (XCAR (prop))))
4321 {
4322 /* A list of sub-properties. */
4323 while (CONSP (prop))
4324 {
4325 if (single_display_spec_string_p (XCAR (prop), string))
4326 return 1;
4327 prop = XCDR (prop);
4328 }
4329 }
4330 else if (VECTORP (prop))
4331 {
4332 /* A vector of sub-properties. */
4333 int i;
4334 for (i = 0; i < ASIZE (prop); ++i)
4335 if (single_display_spec_string_p (AREF (prop, i), string))
4336 return 1;
4337 }
4338 else
4339 return single_display_spec_string_p (prop, string);
4340
4341 return 0;
4342 }
4343
4344
4345 /* Determine from which buffer position in W's buffer STRING comes
4346 from. AROUND_CHARPOS is an approximate position where it could
4347 be from. Value is the buffer position or 0 if it couldn't be
4348 determined.
4349
4350 W's buffer must be current.
4351
4352 This function is necessary because we don't record buffer positions
4353 in glyphs generated from strings (to keep struct glyph small).
4354 This function may only use code that doesn't eval because it is
4355 called asynchronously from note_mouse_highlight. */
4356
4357 int
4358 string_buffer_position (w, string, around_charpos)
4359 struct window *w;
4360 Lisp_Object string;
4361 int around_charpos;
4362 {
4363 Lisp_Object limit, prop, pos;
4364 const int MAX_DISTANCE = 1000;
4365 int found = 0;
4366
4367 pos = make_number (around_charpos);
4368 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4369 while (!found && !EQ (pos, limit))
4370 {
4371 prop = Fget_char_property (pos, Qdisplay, Qnil);
4372 if (!NILP (prop) && display_prop_string_p (prop, string))
4373 found = 1;
4374 else
4375 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4376 }
4377
4378 if (!found)
4379 {
4380 pos = make_number (around_charpos);
4381 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4382 while (!found && !EQ (pos, limit))
4383 {
4384 prop = Fget_char_property (pos, Qdisplay, Qnil);
4385 if (!NILP (prop) && display_prop_string_p (prop, string))
4386 found = 1;
4387 else
4388 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4389 limit);
4390 }
4391 }
4392
4393 return found ? XINT (pos) : 0;
4394 }
4395
4396
4397 \f
4398 /***********************************************************************
4399 `composition' property
4400 ***********************************************************************/
4401
4402 /* Set up iterator IT from `composition' property at its current
4403 position. Called from handle_stop. */
4404
4405 static enum prop_handled
4406 handle_composition_prop (it)
4407 struct it *it;
4408 {
4409 Lisp_Object prop, string;
4410 int pos, pos_byte, end;
4411 enum prop_handled handled = HANDLED_NORMALLY;
4412
4413 if (STRINGP (it->string))
4414 {
4415 pos = IT_STRING_CHARPOS (*it);
4416 pos_byte = IT_STRING_BYTEPOS (*it);
4417 string = it->string;
4418 }
4419 else
4420 {
4421 pos = IT_CHARPOS (*it);
4422 pos_byte = IT_BYTEPOS (*it);
4423 string = Qnil;
4424 }
4425
4426 /* If there's a valid composition and point is not inside of the
4427 composition (in the case that the composition is from the current
4428 buffer), draw a glyph composed from the composition components. */
4429 if (find_composition (pos, -1, &pos, &end, &prop, string)
4430 && COMPOSITION_VALID_P (pos, end, prop)
4431 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4432 {
4433 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4434
4435 if (id >= 0)
4436 {
4437 it->method = GET_FROM_COMPOSITION;
4438 it->cmp_id = id;
4439 it->cmp_len = COMPOSITION_LENGTH (prop);
4440 /* For a terminal, draw only the first character of the
4441 components. */
4442 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4443 it->len = (STRINGP (it->string)
4444 ? string_char_to_byte (it->string, end)
4445 : CHAR_TO_BYTE (end)) - pos_byte;
4446 it->stop_charpos = end;
4447 handled = HANDLED_RETURN;
4448 }
4449 }
4450
4451 return handled;
4452 }
4453
4454
4455 \f
4456 /***********************************************************************
4457 Overlay strings
4458 ***********************************************************************/
4459
4460 /* The following structure is used to record overlay strings for
4461 later sorting in load_overlay_strings. */
4462
4463 struct overlay_entry
4464 {
4465 Lisp_Object overlay;
4466 Lisp_Object string;
4467 int priority;
4468 int after_string_p;
4469 };
4470
4471
4472 /* Set up iterator IT from overlay strings at its current position.
4473 Called from handle_stop. */
4474
4475 static enum prop_handled
4476 handle_overlay_change (it)
4477 struct it *it;
4478 {
4479 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4480 return HANDLED_RECOMPUTE_PROPS;
4481 else
4482 return HANDLED_NORMALLY;
4483 }
4484
4485
4486 /* Set up the next overlay string for delivery by IT, if there is an
4487 overlay string to deliver. Called by set_iterator_to_next when the
4488 end of the current overlay string is reached. If there are more
4489 overlay strings to display, IT->string and
4490 IT->current.overlay_string_index are set appropriately here.
4491 Otherwise IT->string is set to nil. */
4492
4493 static void
4494 next_overlay_string (it)
4495 struct it *it;
4496 {
4497 ++it->current.overlay_string_index;
4498 if (it->current.overlay_string_index == it->n_overlay_strings)
4499 {
4500 /* No more overlay strings. Restore IT's settings to what
4501 they were before overlay strings were processed, and
4502 continue to deliver from current_buffer. */
4503 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4504
4505 pop_it (it);
4506 xassert (it->stop_charpos >= BEGV
4507 && it->stop_charpos <= it->end_charpos);
4508 it->string = Qnil;
4509 it->current.overlay_string_index = -1;
4510 SET_TEXT_POS (it->current.string_pos, -1, -1);
4511 it->n_overlay_strings = 0;
4512 it->method = GET_FROM_BUFFER;
4513
4514 /* If we're at the end of the buffer, record that we have
4515 processed the overlay strings there already, so that
4516 next_element_from_buffer doesn't try it again. */
4517 if (IT_CHARPOS (*it) >= it->end_charpos)
4518 it->overlay_strings_at_end_processed_p = 1;
4519
4520 /* If we have to display `...' for invisible text, set
4521 the iterator up for that. */
4522 if (display_ellipsis_p)
4523 setup_for_ellipsis (it, 0);
4524 }
4525 else
4526 {
4527 /* There are more overlay strings to process. If
4528 IT->current.overlay_string_index has advanced to a position
4529 where we must load IT->overlay_strings with more strings, do
4530 it. */
4531 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4532
4533 if (it->current.overlay_string_index && i == 0)
4534 load_overlay_strings (it, 0);
4535
4536 /* Initialize IT to deliver display elements from the overlay
4537 string. */
4538 it->string = it->overlay_strings[i];
4539 it->multibyte_p = STRING_MULTIBYTE (it->string);
4540 SET_TEXT_POS (it->current.string_pos, 0, 0);
4541 it->method = GET_FROM_STRING;
4542 it->stop_charpos = 0;
4543 }
4544
4545 CHECK_IT (it);
4546 }
4547
4548
4549 /* Compare two overlay_entry structures E1 and E2. Used as a
4550 comparison function for qsort in load_overlay_strings. Overlay
4551 strings for the same position are sorted so that
4552
4553 1. All after-strings come in front of before-strings, except
4554 when they come from the same overlay.
4555
4556 2. Within after-strings, strings are sorted so that overlay strings
4557 from overlays with higher priorities come first.
4558
4559 2. Within before-strings, strings are sorted so that overlay
4560 strings from overlays with higher priorities come last.
4561
4562 Value is analogous to strcmp. */
4563
4564
4565 static int
4566 compare_overlay_entries (e1, e2)
4567 void *e1, *e2;
4568 {
4569 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4570 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4571 int result;
4572
4573 if (entry1->after_string_p != entry2->after_string_p)
4574 {
4575 /* Let after-strings appear in front of before-strings if
4576 they come from different overlays. */
4577 if (EQ (entry1->overlay, entry2->overlay))
4578 result = entry1->after_string_p ? 1 : -1;
4579 else
4580 result = entry1->after_string_p ? -1 : 1;
4581 }
4582 else if (entry1->after_string_p)
4583 /* After-strings sorted in order of decreasing priority. */
4584 result = entry2->priority - entry1->priority;
4585 else
4586 /* Before-strings sorted in order of increasing priority. */
4587 result = entry1->priority - entry2->priority;
4588
4589 return result;
4590 }
4591
4592
4593 /* Load the vector IT->overlay_strings with overlay strings from IT's
4594 current buffer position, or from CHARPOS if that is > 0. Set
4595 IT->n_overlays to the total number of overlay strings found.
4596
4597 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4598 a time. On entry into load_overlay_strings,
4599 IT->current.overlay_string_index gives the number of overlay
4600 strings that have already been loaded by previous calls to this
4601 function.
4602
4603 IT->add_overlay_start contains an additional overlay start
4604 position to consider for taking overlay strings from, if non-zero.
4605 This position comes into play when the overlay has an `invisible'
4606 property, and both before and after-strings. When we've skipped to
4607 the end of the overlay, because of its `invisible' property, we
4608 nevertheless want its before-string to appear.
4609 IT->add_overlay_start will contain the overlay start position
4610 in this case.
4611
4612 Overlay strings are sorted so that after-string strings come in
4613 front of before-string strings. Within before and after-strings,
4614 strings are sorted by overlay priority. See also function
4615 compare_overlay_entries. */
4616
4617 static void
4618 load_overlay_strings (it, charpos)
4619 struct it *it;
4620 int charpos;
4621 {
4622 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4623 Lisp_Object overlay, window, str, invisible;
4624 struct Lisp_Overlay *ov;
4625 int start, end;
4626 int size = 20;
4627 int n = 0, i, j, invis_p;
4628 struct overlay_entry *entries
4629 = (struct overlay_entry *) alloca (size * sizeof *entries);
4630
4631 if (charpos <= 0)
4632 charpos = IT_CHARPOS (*it);
4633
4634 /* Append the overlay string STRING of overlay OVERLAY to vector
4635 `entries' which has size `size' and currently contains `n'
4636 elements. AFTER_P non-zero means STRING is an after-string of
4637 OVERLAY. */
4638 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4639 do \
4640 { \
4641 Lisp_Object priority; \
4642 \
4643 if (n == size) \
4644 { \
4645 int new_size = 2 * size; \
4646 struct overlay_entry *old = entries; \
4647 entries = \
4648 (struct overlay_entry *) alloca (new_size \
4649 * sizeof *entries); \
4650 bcopy (old, entries, size * sizeof *entries); \
4651 size = new_size; \
4652 } \
4653 \
4654 entries[n].string = (STRING); \
4655 entries[n].overlay = (OVERLAY); \
4656 priority = Foverlay_get ((OVERLAY), Qpriority); \
4657 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4658 entries[n].after_string_p = (AFTER_P); \
4659 ++n; \
4660 } \
4661 while (0)
4662
4663 /* Process overlay before the overlay center. */
4664 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4665 {
4666 XSETMISC (overlay, ov);
4667 xassert (OVERLAYP (overlay));
4668 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4669 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4670
4671 if (end < charpos)
4672 break;
4673
4674 /* Skip this overlay if it doesn't start or end at IT's current
4675 position. */
4676 if (end != charpos && start != charpos)
4677 continue;
4678
4679 /* Skip this overlay if it doesn't apply to IT->w. */
4680 window = Foverlay_get (overlay, Qwindow);
4681 if (WINDOWP (window) && XWINDOW (window) != it->w)
4682 continue;
4683
4684 /* If the text ``under'' the overlay is invisible, both before-
4685 and after-strings from this overlay are visible; start and
4686 end position are indistinguishable. */
4687 invisible = Foverlay_get (overlay, Qinvisible);
4688 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4689
4690 /* If overlay has a non-empty before-string, record it. */
4691 if ((start == charpos || (end == charpos && invis_p))
4692 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4693 && SCHARS (str))
4694 RECORD_OVERLAY_STRING (overlay, str, 0);
4695
4696 /* If overlay has a non-empty after-string, record it. */
4697 if ((end == charpos || (start == charpos && invis_p))
4698 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4699 && SCHARS (str))
4700 RECORD_OVERLAY_STRING (overlay, str, 1);
4701 }
4702
4703 /* Process overlays after the overlay center. */
4704 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4705 {
4706 XSETMISC (overlay, ov);
4707 xassert (OVERLAYP (overlay));
4708 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4709 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4710
4711 if (start > charpos)
4712 break;
4713
4714 /* Skip this overlay if it doesn't start or end at IT's current
4715 position. */
4716 if (end != charpos && start != charpos)
4717 continue;
4718
4719 /* Skip this overlay if it doesn't apply to IT->w. */
4720 window = Foverlay_get (overlay, Qwindow);
4721 if (WINDOWP (window) && XWINDOW (window) != it->w)
4722 continue;
4723
4724 /* If the text ``under'' the overlay is invisible, it has a zero
4725 dimension, and both before- and after-strings apply. */
4726 invisible = Foverlay_get (overlay, Qinvisible);
4727 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4728
4729 /* If overlay has a non-empty before-string, record it. */
4730 if ((start == charpos || (end == charpos && invis_p))
4731 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4732 && SCHARS (str))
4733 RECORD_OVERLAY_STRING (overlay, str, 0);
4734
4735 /* If overlay has a non-empty after-string, record it. */
4736 if ((end == charpos || (start == charpos && invis_p))
4737 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4738 && SCHARS (str))
4739 RECORD_OVERLAY_STRING (overlay, str, 1);
4740 }
4741
4742 #undef RECORD_OVERLAY_STRING
4743
4744 /* Sort entries. */
4745 if (n > 1)
4746 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4747
4748 /* Record the total number of strings to process. */
4749 it->n_overlay_strings = n;
4750
4751 /* IT->current.overlay_string_index is the number of overlay strings
4752 that have already been consumed by IT. Copy some of the
4753 remaining overlay strings to IT->overlay_strings. */
4754 i = 0;
4755 j = it->current.overlay_string_index;
4756 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4757 it->overlay_strings[i++] = entries[j++].string;
4758
4759 CHECK_IT (it);
4760 }
4761
4762
4763 /* Get the first chunk of overlay strings at IT's current buffer
4764 position, or at CHARPOS if that is > 0. Value is non-zero if at
4765 least one overlay string was found. */
4766
4767 static int
4768 get_overlay_strings (it, charpos)
4769 struct it *it;
4770 int charpos;
4771 {
4772 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4773 process. This fills IT->overlay_strings with strings, and sets
4774 IT->n_overlay_strings to the total number of strings to process.
4775 IT->pos.overlay_string_index has to be set temporarily to zero
4776 because load_overlay_strings needs this; it must be set to -1
4777 when no overlay strings are found because a zero value would
4778 indicate a position in the first overlay string. */
4779 it->current.overlay_string_index = 0;
4780 load_overlay_strings (it, charpos);
4781
4782 /* If we found overlay strings, set up IT to deliver display
4783 elements from the first one. Otherwise set up IT to deliver
4784 from current_buffer. */
4785 if (it->n_overlay_strings)
4786 {
4787 /* Make sure we know settings in current_buffer, so that we can
4788 restore meaningful values when we're done with the overlay
4789 strings. */
4790 compute_stop_pos (it);
4791 xassert (it->face_id >= 0);
4792
4793 /* Save IT's settings. They are restored after all overlay
4794 strings have been processed. */
4795 xassert (it->sp == 0);
4796 push_it (it);
4797
4798 /* Set up IT to deliver display elements from the first overlay
4799 string. */
4800 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4801 it->string = it->overlay_strings[0];
4802 it->stop_charpos = 0;
4803 xassert (STRINGP (it->string));
4804 it->end_charpos = SCHARS (it->string);
4805 it->multibyte_p = STRING_MULTIBYTE (it->string);
4806 it->method = GET_FROM_STRING;
4807 }
4808 else
4809 {
4810 it->string = Qnil;
4811 it->current.overlay_string_index = -1;
4812 it->method = GET_FROM_BUFFER;
4813 }
4814
4815 CHECK_IT (it);
4816
4817 /* Value is non-zero if we found at least one overlay string. */
4818 return STRINGP (it->string);
4819 }
4820
4821
4822 \f
4823 /***********************************************************************
4824 Saving and restoring state
4825 ***********************************************************************/
4826
4827 /* Save current settings of IT on IT->stack. Called, for example,
4828 before setting up IT for an overlay string, to be able to restore
4829 IT's settings to what they were after the overlay string has been
4830 processed. */
4831
4832 static void
4833 push_it (it)
4834 struct it *it;
4835 {
4836 struct iterator_stack_entry *p;
4837
4838 xassert (it->sp < 2);
4839 p = it->stack + it->sp;
4840
4841 p->stop_charpos = it->stop_charpos;
4842 xassert (it->face_id >= 0);
4843 p->face_id = it->face_id;
4844 p->string = it->string;
4845 p->pos = it->current;
4846 p->end_charpos = it->end_charpos;
4847 p->string_nchars = it->string_nchars;
4848 p->area = it->area;
4849 p->multibyte_p = it->multibyte_p;
4850 p->slice = it->slice;
4851 p->space_width = it->space_width;
4852 p->font_height = it->font_height;
4853 p->voffset = it->voffset;
4854 p->string_from_display_prop_p = it->string_from_display_prop_p;
4855 p->display_ellipsis_p = 0;
4856 ++it->sp;
4857 }
4858
4859
4860 /* Restore IT's settings from IT->stack. Called, for example, when no
4861 more overlay strings must be processed, and we return to delivering
4862 display elements from a buffer, or when the end of a string from a
4863 `display' property is reached and we return to delivering display
4864 elements from an overlay string, or from a buffer. */
4865
4866 static void
4867 pop_it (it)
4868 struct it *it;
4869 {
4870 struct iterator_stack_entry *p;
4871
4872 xassert (it->sp > 0);
4873 --it->sp;
4874 p = it->stack + it->sp;
4875 it->stop_charpos = p->stop_charpos;
4876 it->face_id = p->face_id;
4877 it->string = p->string;
4878 it->current = p->pos;
4879 it->end_charpos = p->end_charpos;
4880 it->string_nchars = p->string_nchars;
4881 it->area = p->area;
4882 it->multibyte_p = p->multibyte_p;
4883 it->slice = p->slice;
4884 it->space_width = p->space_width;
4885 it->font_height = p->font_height;
4886 it->voffset = p->voffset;
4887 it->string_from_display_prop_p = p->string_from_display_prop_p;
4888 }
4889
4890
4891 \f
4892 /***********************************************************************
4893 Moving over lines
4894 ***********************************************************************/
4895
4896 /* Set IT's current position to the previous line start. */
4897
4898 static void
4899 back_to_previous_line_start (it)
4900 struct it *it;
4901 {
4902 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4903 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4904 }
4905
4906
4907 /* Move IT to the next line start.
4908
4909 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4910 we skipped over part of the text (as opposed to moving the iterator
4911 continuously over the text). Otherwise, don't change the value
4912 of *SKIPPED_P.
4913
4914 Newlines may come from buffer text, overlay strings, or strings
4915 displayed via the `display' property. That's the reason we can't
4916 simply use find_next_newline_no_quit.
4917
4918 Note that this function may not skip over invisible text that is so
4919 because of text properties and immediately follows a newline. If
4920 it would, function reseat_at_next_visible_line_start, when called
4921 from set_iterator_to_next, would effectively make invisible
4922 characters following a newline part of the wrong glyph row, which
4923 leads to wrong cursor motion. */
4924
4925 static int
4926 forward_to_next_line_start (it, skipped_p)
4927 struct it *it;
4928 int *skipped_p;
4929 {
4930 int old_selective, newline_found_p, n;
4931 const int MAX_NEWLINE_DISTANCE = 500;
4932
4933 /* If already on a newline, just consume it to avoid unintended
4934 skipping over invisible text below. */
4935 if (it->what == IT_CHARACTER
4936 && it->c == '\n'
4937 && CHARPOS (it->position) == IT_CHARPOS (*it))
4938 {
4939 set_iterator_to_next (it, 0);
4940 it->c = 0;
4941 return 1;
4942 }
4943
4944 /* Don't handle selective display in the following. It's (a)
4945 unnecessary because it's done by the caller, and (b) leads to an
4946 infinite recursion because next_element_from_ellipsis indirectly
4947 calls this function. */
4948 old_selective = it->selective;
4949 it->selective = 0;
4950
4951 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4952 from buffer text. */
4953 for (n = newline_found_p = 0;
4954 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4955 n += STRINGP (it->string) ? 0 : 1)
4956 {
4957 if (!get_next_display_element (it))
4958 return 0;
4959 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4960 set_iterator_to_next (it, 0);
4961 }
4962
4963 /* If we didn't find a newline near enough, see if we can use a
4964 short-cut. */
4965 if (!newline_found_p)
4966 {
4967 int start = IT_CHARPOS (*it);
4968 int limit = find_next_newline_no_quit (start, 1);
4969 Lisp_Object pos;
4970
4971 xassert (!STRINGP (it->string));
4972
4973 /* If there isn't any `display' property in sight, and no
4974 overlays, we can just use the position of the newline in
4975 buffer text. */
4976 if (it->stop_charpos >= limit
4977 || ((pos = Fnext_single_property_change (make_number (start),
4978 Qdisplay,
4979 Qnil, make_number (limit)),
4980 NILP (pos))
4981 && next_overlay_change (start) == ZV))
4982 {
4983 IT_CHARPOS (*it) = limit;
4984 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4985 *skipped_p = newline_found_p = 1;
4986 }
4987 else
4988 {
4989 while (get_next_display_element (it)
4990 && !newline_found_p)
4991 {
4992 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4993 set_iterator_to_next (it, 0);
4994 }
4995 }
4996 }
4997
4998 it->selective = old_selective;
4999 return newline_found_p;
5000 }
5001
5002
5003 /* Set IT's current position to the previous visible line start. Skip
5004 invisible text that is so either due to text properties or due to
5005 selective display. Caution: this does not change IT->current_x and
5006 IT->hpos. */
5007
5008 static void
5009 back_to_previous_visible_line_start (it)
5010 struct it *it;
5011 {
5012 while (IT_CHARPOS (*it) > BEGV)
5013 {
5014 back_to_previous_line_start (it);
5015 if (IT_CHARPOS (*it) <= BEGV)
5016 break;
5017
5018 /* If selective > 0, then lines indented more than that values
5019 are invisible. */
5020 if (it->selective > 0
5021 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5022 (double) it->selective)) /* iftc */
5023 continue;
5024
5025 /* Check the newline before point for invisibility. */
5026 {
5027 Lisp_Object prop;
5028 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5029 Qinvisible, it->window);
5030 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5031 continue;
5032 }
5033
5034 /* If newline has a display property that replaces the newline with something
5035 else (image or text), find start of overlay or interval and continue search
5036 from that point. */
5037 if (IT_CHARPOS (*it) > BEGV)
5038 {
5039 struct it it2 = *it;
5040 int pos;
5041 int beg, end;
5042 Lisp_Object val, overlay;
5043
5044 pos = --IT_CHARPOS (it2);
5045 --IT_BYTEPOS (it2);
5046 it2.sp = 0;
5047 if (handle_display_prop (&it2) == HANDLED_RETURN
5048 && !NILP (val = get_char_property_and_overlay
5049 (make_number (pos), Qdisplay, Qnil, &overlay))
5050 && (OVERLAYP (overlay)
5051 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5052 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5053 {
5054 if (beg < BEGV)
5055 beg = BEGV;
5056 IT_CHARPOS (*it) = beg;
5057 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5058 continue;
5059 }
5060 }
5061
5062 break;
5063 }
5064
5065 xassert (IT_CHARPOS (*it) >= BEGV);
5066 xassert (IT_CHARPOS (*it) == BEGV
5067 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5068 CHECK_IT (it);
5069 }
5070
5071
5072 /* Reseat iterator IT at the previous visible line start. Skip
5073 invisible text that is so either due to text properties or due to
5074 selective display. At the end, update IT's overlay information,
5075 face information etc. */
5076
5077 void
5078 reseat_at_previous_visible_line_start (it)
5079 struct it *it;
5080 {
5081 back_to_previous_visible_line_start (it);
5082 reseat (it, it->current.pos, 1);
5083 CHECK_IT (it);
5084 }
5085
5086
5087 /* Reseat iterator IT on the next visible line start in the current
5088 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5089 preceding the line start. Skip over invisible text that is so
5090 because of selective display. Compute faces, overlays etc at the
5091 new position. Note that this function does not skip over text that
5092 is invisible because of text properties. */
5093
5094 static void
5095 reseat_at_next_visible_line_start (it, on_newline_p)
5096 struct it *it;
5097 int on_newline_p;
5098 {
5099 int newline_found_p, skipped_p = 0;
5100
5101 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5102
5103 /* Skip over lines that are invisible because they are indented
5104 more than the value of IT->selective. */
5105 if (it->selective > 0)
5106 while (IT_CHARPOS (*it) < ZV
5107 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5108 (double) it->selective)) /* iftc */
5109 {
5110 xassert (IT_BYTEPOS (*it) == BEGV
5111 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5112 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5113 }
5114
5115 /* Position on the newline if that's what's requested. */
5116 if (on_newline_p && newline_found_p)
5117 {
5118 if (STRINGP (it->string))
5119 {
5120 if (IT_STRING_CHARPOS (*it) > 0)
5121 {
5122 --IT_STRING_CHARPOS (*it);
5123 --IT_STRING_BYTEPOS (*it);
5124 }
5125 }
5126 else if (IT_CHARPOS (*it) > BEGV)
5127 {
5128 --IT_CHARPOS (*it);
5129 --IT_BYTEPOS (*it);
5130 reseat (it, it->current.pos, 0);
5131 }
5132 }
5133 else if (skipped_p)
5134 reseat (it, it->current.pos, 0);
5135
5136 CHECK_IT (it);
5137 }
5138
5139
5140 \f
5141 /***********************************************************************
5142 Changing an iterator's position
5143 ***********************************************************************/
5144
5145 /* Change IT's current position to POS in current_buffer. If FORCE_P
5146 is non-zero, always check for text properties at the new position.
5147 Otherwise, text properties are only looked up if POS >=
5148 IT->check_charpos of a property. */
5149
5150 static void
5151 reseat (it, pos, force_p)
5152 struct it *it;
5153 struct text_pos pos;
5154 int force_p;
5155 {
5156 int original_pos = IT_CHARPOS (*it);
5157
5158 reseat_1 (it, pos, 0);
5159
5160 /* Determine where to check text properties. Avoid doing it
5161 where possible because text property lookup is very expensive. */
5162 if (force_p
5163 || CHARPOS (pos) > it->stop_charpos
5164 || CHARPOS (pos) < original_pos)
5165 handle_stop (it);
5166
5167 CHECK_IT (it);
5168 }
5169
5170
5171 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5172 IT->stop_pos to POS, also. */
5173
5174 static void
5175 reseat_1 (it, pos, set_stop_p)
5176 struct it *it;
5177 struct text_pos pos;
5178 int set_stop_p;
5179 {
5180 /* Don't call this function when scanning a C string. */
5181 xassert (it->s == NULL);
5182
5183 /* POS must be a reasonable value. */
5184 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5185
5186 it->current.pos = it->position = pos;
5187 XSETBUFFER (it->object, current_buffer);
5188 it->end_charpos = ZV;
5189 it->dpvec = NULL;
5190 it->current.dpvec_index = -1;
5191 it->current.overlay_string_index = -1;
5192 IT_STRING_CHARPOS (*it) = -1;
5193 IT_STRING_BYTEPOS (*it) = -1;
5194 it->string = Qnil;
5195 it->method = GET_FROM_BUFFER;
5196 /* RMS: I added this to fix a bug in move_it_vertically_backward
5197 where it->area continued to relate to the starting point
5198 for the backward motion. Bug report from
5199 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
5200 However, I am not sure whether reseat still does the right thing
5201 in general after this change. */
5202 it->area = TEXT_AREA;
5203 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5204 it->sp = 0;
5205 it->face_before_selective_p = 0;
5206
5207 if (set_stop_p)
5208 it->stop_charpos = CHARPOS (pos);
5209 }
5210
5211
5212 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5213 If S is non-null, it is a C string to iterate over. Otherwise,
5214 STRING gives a Lisp string to iterate over.
5215
5216 If PRECISION > 0, don't return more then PRECISION number of
5217 characters from the string.
5218
5219 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5220 characters have been returned. FIELD_WIDTH < 0 means an infinite
5221 field width.
5222
5223 MULTIBYTE = 0 means disable processing of multibyte characters,
5224 MULTIBYTE > 0 means enable it,
5225 MULTIBYTE < 0 means use IT->multibyte_p.
5226
5227 IT must be initialized via a prior call to init_iterator before
5228 calling this function. */
5229
5230 static void
5231 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5232 struct it *it;
5233 unsigned char *s;
5234 Lisp_Object string;
5235 int charpos;
5236 int precision, field_width, multibyte;
5237 {
5238 /* No region in strings. */
5239 it->region_beg_charpos = it->region_end_charpos = -1;
5240
5241 /* No text property checks performed by default, but see below. */
5242 it->stop_charpos = -1;
5243
5244 /* Set iterator position and end position. */
5245 bzero (&it->current, sizeof it->current);
5246 it->current.overlay_string_index = -1;
5247 it->current.dpvec_index = -1;
5248 xassert (charpos >= 0);
5249
5250 /* If STRING is specified, use its multibyteness, otherwise use the
5251 setting of MULTIBYTE, if specified. */
5252 if (multibyte >= 0)
5253 it->multibyte_p = multibyte > 0;
5254
5255 if (s == NULL)
5256 {
5257 xassert (STRINGP (string));
5258 it->string = string;
5259 it->s = NULL;
5260 it->end_charpos = it->string_nchars = SCHARS (string);
5261 it->method = GET_FROM_STRING;
5262 it->current.string_pos = string_pos (charpos, string);
5263 }
5264 else
5265 {
5266 it->s = s;
5267 it->string = Qnil;
5268
5269 /* Note that we use IT->current.pos, not it->current.string_pos,
5270 for displaying C strings. */
5271 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5272 if (it->multibyte_p)
5273 {
5274 it->current.pos = c_string_pos (charpos, s, 1);
5275 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5276 }
5277 else
5278 {
5279 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5280 it->end_charpos = it->string_nchars = strlen (s);
5281 }
5282
5283 it->method = GET_FROM_C_STRING;
5284 }
5285
5286 /* PRECISION > 0 means don't return more than PRECISION characters
5287 from the string. */
5288 if (precision > 0 && it->end_charpos - charpos > precision)
5289 it->end_charpos = it->string_nchars = charpos + precision;
5290
5291 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5292 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5293 FIELD_WIDTH < 0 means infinite field width. This is useful for
5294 padding with `-' at the end of a mode line. */
5295 if (field_width < 0)
5296 field_width = INFINITY;
5297 if (field_width > it->end_charpos - charpos)
5298 it->end_charpos = charpos + field_width;
5299
5300 /* Use the standard display table for displaying strings. */
5301 if (DISP_TABLE_P (Vstandard_display_table))
5302 it->dp = XCHAR_TABLE (Vstandard_display_table);
5303
5304 it->stop_charpos = charpos;
5305 CHECK_IT (it);
5306 }
5307
5308
5309 \f
5310 /***********************************************************************
5311 Iteration
5312 ***********************************************************************/
5313
5314 /* Map enum it_method value to corresponding next_element_from_* function. */
5315
5316 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5317 {
5318 next_element_from_buffer,
5319 next_element_from_display_vector,
5320 next_element_from_composition,
5321 next_element_from_string,
5322 next_element_from_c_string,
5323 next_element_from_image,
5324 next_element_from_stretch
5325 };
5326
5327
5328 /* Load IT's display element fields with information about the next
5329 display element from the current position of IT. Value is zero if
5330 end of buffer (or C string) is reached. */
5331
5332 int
5333 get_next_display_element (it)
5334 struct it *it;
5335 {
5336 /* Non-zero means that we found a display element. Zero means that
5337 we hit the end of what we iterate over. Performance note: the
5338 function pointer `method' used here turns out to be faster than
5339 using a sequence of if-statements. */
5340 int success_p;
5341
5342 get_next:
5343 success_p = (*get_next_element[it->method]) (it);
5344
5345 if (it->what == IT_CHARACTER)
5346 {
5347 /* Map via display table or translate control characters.
5348 IT->c, IT->len etc. have been set to the next character by
5349 the function call above. If we have a display table, and it
5350 contains an entry for IT->c, translate it. Don't do this if
5351 IT->c itself comes from a display table, otherwise we could
5352 end up in an infinite recursion. (An alternative could be to
5353 count the recursion depth of this function and signal an
5354 error when a certain maximum depth is reached.) Is it worth
5355 it? */
5356 if (success_p && it->dpvec == NULL)
5357 {
5358 Lisp_Object dv;
5359
5360 if (it->dp
5361 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5362 VECTORP (dv)))
5363 {
5364 struct Lisp_Vector *v = XVECTOR (dv);
5365
5366 /* Return the first character from the display table
5367 entry, if not empty. If empty, don't display the
5368 current character. */
5369 if (v->size)
5370 {
5371 it->dpvec_char_len = it->len;
5372 it->dpvec = v->contents;
5373 it->dpend = v->contents + v->size;
5374 it->current.dpvec_index = 0;
5375 it->dpvec_face_id = -1;
5376 it->saved_face_id = it->face_id;
5377 it->method = GET_FROM_DISPLAY_VECTOR;
5378 it->ellipsis_p = 0;
5379 }
5380 else
5381 {
5382 set_iterator_to_next (it, 0);
5383 }
5384 goto get_next;
5385 }
5386
5387 /* Translate control characters into `\003' or `^C' form.
5388 Control characters coming from a display table entry are
5389 currently not translated because we use IT->dpvec to hold
5390 the translation. This could easily be changed but I
5391 don't believe that it is worth doing.
5392
5393 If it->multibyte_p is nonzero, eight-bit characters and
5394 non-printable multibyte characters are also translated to
5395 octal form.
5396
5397 If it->multibyte_p is zero, eight-bit characters that
5398 don't have corresponding multibyte char code are also
5399 translated to octal form. */
5400 else if ((it->c < ' '
5401 && (it->area != TEXT_AREA
5402 /* In mode line, treat \n like other crl chars. */
5403 || (it->c != '\t'
5404 && it->glyph_row && it->glyph_row->mode_line_p)
5405 || (it->c != '\n' && it->c != '\t')))
5406 || (it->multibyte_p
5407 ? ((it->c >= 127
5408 && it->len == 1)
5409 || !CHAR_PRINTABLE_P (it->c)
5410 || (!NILP (Vnobreak_char_display)
5411 && (it->c == 0x8a0 || it->c == 0x8ad
5412 || it->c == 0x920 || it->c == 0x92d
5413 || it->c == 0xe20 || it->c == 0xe2d
5414 || it->c == 0xf20 || it->c == 0xf2d)))
5415 : (it->c >= 127
5416 && (!unibyte_display_via_language_environment
5417 || it->c == unibyte_char_to_multibyte (it->c)))))
5418 {
5419 /* IT->c is a control character which must be displayed
5420 either as '\003' or as `^C' where the '\\' and '^'
5421 can be defined in the display table. Fill
5422 IT->ctl_chars with glyphs for what we have to
5423 display. Then, set IT->dpvec to these glyphs. */
5424 GLYPH g;
5425 int ctl_len;
5426 int face_id, lface_id = 0 ;
5427 GLYPH escape_glyph;
5428
5429 /* Handle control characters with ^. */
5430
5431 if (it->c < 128 && it->ctl_arrow_p)
5432 {
5433 g = '^'; /* default glyph for Control */
5434 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5435 if (it->dp
5436 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5437 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5438 {
5439 g = XINT (DISP_CTRL_GLYPH (it->dp));
5440 lface_id = FAST_GLYPH_FACE (g);
5441 }
5442 if (lface_id)
5443 {
5444 g = FAST_GLYPH_CHAR (g);
5445 face_id = merge_faces (it->f, Qt, lface_id,
5446 it->face_id);
5447 }
5448 else
5449 {
5450 /* Merge the escape-glyph face into the current face. */
5451 face_id = merge_faces (it->f, Qescape_glyph, 0,
5452 it->face_id);
5453 }
5454
5455 XSETINT (it->ctl_chars[0], g);
5456 g = it->c ^ 0100;
5457 XSETINT (it->ctl_chars[1], g);
5458 ctl_len = 2;
5459 goto display_control;
5460 }
5461
5462 /* Handle non-break space in the mode where it only gets
5463 highlighting. */
5464
5465 if (EQ (Vnobreak_char_display, Qt)
5466 && (it->c == 0x8a0 || it->c == 0x920
5467 || it->c == 0xe20 || it->c == 0xf20))
5468 {
5469 /* Merge the no-break-space face into the current face. */
5470 face_id = merge_faces (it->f, Qnobreak_space, 0,
5471 it->face_id);
5472
5473 g = it->c = ' ';
5474 XSETINT (it->ctl_chars[0], g);
5475 ctl_len = 1;
5476 goto display_control;
5477 }
5478
5479 /* Handle sequences that start with the "escape glyph". */
5480
5481 /* the default escape glyph is \. */
5482 escape_glyph = '\\';
5483
5484 if (it->dp
5485 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5486 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5487 {
5488 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5489 lface_id = FAST_GLYPH_FACE (escape_glyph);
5490 }
5491 if (lface_id)
5492 {
5493 /* The display table specified a face.
5494 Merge it into face_id and also into escape_glyph. */
5495 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5496 face_id = merge_faces (it->f, Qt, lface_id,
5497 it->face_id);
5498 }
5499 else
5500 {
5501 /* Merge the escape-glyph face into the current face. */
5502 face_id = merge_faces (it->f, Qescape_glyph, 0,
5503 it->face_id);
5504 }
5505
5506 /* Handle soft hyphens in the mode where they only get
5507 highlighting. */
5508
5509 if (EQ (Vnobreak_char_display, Qt)
5510 && (it->c == 0x8ad || it->c == 0x92d
5511 || it->c == 0xe2d || it->c == 0xf2d))
5512 {
5513 g = it->c = '-';
5514 XSETINT (it->ctl_chars[0], g);
5515 ctl_len = 1;
5516 goto display_control;
5517 }
5518
5519 /* Handle non-break space and soft hyphen
5520 with the escape glyph. */
5521
5522 if (it->c == 0x8a0 || it->c == 0x8ad
5523 || it->c == 0x920 || it->c == 0x92d
5524 || it->c == 0xe20 || it->c == 0xe2d
5525 || it->c == 0xf20 || it->c == 0xf2d)
5526 {
5527 XSETINT (it->ctl_chars[0], escape_glyph);
5528 g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-');
5529 XSETINT (it->ctl_chars[1], g);
5530 ctl_len = 2;
5531 goto display_control;
5532 }
5533
5534 {
5535 unsigned char str[MAX_MULTIBYTE_LENGTH];
5536 int len;
5537 int i;
5538
5539 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5540 if (SINGLE_BYTE_CHAR_P (it->c))
5541 str[0] = it->c, len = 1;
5542 else
5543 {
5544 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5545 if (len < 0)
5546 {
5547 /* It's an invalid character, which shouldn't
5548 happen actually, but due to bugs it may
5549 happen. Let's print the char as is, there's
5550 not much meaningful we can do with it. */
5551 str[0] = it->c;
5552 str[1] = it->c >> 8;
5553 str[2] = it->c >> 16;
5554 str[3] = it->c >> 24;
5555 len = 4;
5556 }
5557 }
5558
5559 for (i = 0; i < len; i++)
5560 {
5561 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5562 /* Insert three more glyphs into IT->ctl_chars for
5563 the octal display of the character. */
5564 g = ((str[i] >> 6) & 7) + '0';
5565 XSETINT (it->ctl_chars[i * 4 + 1], g);
5566 g = ((str[i] >> 3) & 7) + '0';
5567 XSETINT (it->ctl_chars[i * 4 + 2], g);
5568 g = (str[i] & 7) + '0';
5569 XSETINT (it->ctl_chars[i * 4 + 3], g);
5570 }
5571 ctl_len = len * 4;
5572 }
5573
5574 display_control:
5575 /* Set up IT->dpvec and return first character from it. */
5576 it->dpvec_char_len = it->len;
5577 it->dpvec = it->ctl_chars;
5578 it->dpend = it->dpvec + ctl_len;
5579 it->current.dpvec_index = 0;
5580 it->dpvec_face_id = face_id;
5581 it->saved_face_id = it->face_id;
5582 it->method = GET_FROM_DISPLAY_VECTOR;
5583 it->ellipsis_p = 0;
5584 goto get_next;
5585 }
5586 }
5587
5588 /* Adjust face id for a multibyte character. There are no
5589 multibyte character in unibyte text. */
5590 if (it->multibyte_p
5591 && success_p
5592 && FRAME_WINDOW_P (it->f))
5593 {
5594 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5595 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5596 }
5597 }
5598
5599 /* Is this character the last one of a run of characters with
5600 box? If yes, set IT->end_of_box_run_p to 1. */
5601 if (it->face_box_p
5602 && it->s == NULL)
5603 {
5604 int face_id;
5605 struct face *face;
5606
5607 it->end_of_box_run_p
5608 = ((face_id = face_after_it_pos (it),
5609 face_id != it->face_id)
5610 && (face = FACE_FROM_ID (it->f, face_id),
5611 face->box == FACE_NO_BOX));
5612 }
5613
5614 /* Value is 0 if end of buffer or string reached. */
5615 return success_p;
5616 }
5617
5618
5619 /* Move IT to the next display element.
5620
5621 RESEAT_P non-zero means if called on a newline in buffer text,
5622 skip to the next visible line start.
5623
5624 Functions get_next_display_element and set_iterator_to_next are
5625 separate because I find this arrangement easier to handle than a
5626 get_next_display_element function that also increments IT's
5627 position. The way it is we can first look at an iterator's current
5628 display element, decide whether it fits on a line, and if it does,
5629 increment the iterator position. The other way around we probably
5630 would either need a flag indicating whether the iterator has to be
5631 incremented the next time, or we would have to implement a
5632 decrement position function which would not be easy to write. */
5633
5634 void
5635 set_iterator_to_next (it, reseat_p)
5636 struct it *it;
5637 int reseat_p;
5638 {
5639 /* Reset flags indicating start and end of a sequence of characters
5640 with box. Reset them at the start of this function because
5641 moving the iterator to a new position might set them. */
5642 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5643
5644 switch (it->method)
5645 {
5646 case GET_FROM_BUFFER:
5647 /* The current display element of IT is a character from
5648 current_buffer. Advance in the buffer, and maybe skip over
5649 invisible lines that are so because of selective display. */
5650 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5651 reseat_at_next_visible_line_start (it, 0);
5652 else
5653 {
5654 xassert (it->len != 0);
5655 IT_BYTEPOS (*it) += it->len;
5656 IT_CHARPOS (*it) += 1;
5657 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5658 }
5659 break;
5660
5661 case GET_FROM_COMPOSITION:
5662 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5663 if (STRINGP (it->string))
5664 {
5665 IT_STRING_BYTEPOS (*it) += it->len;
5666 IT_STRING_CHARPOS (*it) += it->cmp_len;
5667 it->method = GET_FROM_STRING;
5668 goto consider_string_end;
5669 }
5670 else
5671 {
5672 IT_BYTEPOS (*it) += it->len;
5673 IT_CHARPOS (*it) += it->cmp_len;
5674 it->method = GET_FROM_BUFFER;
5675 }
5676 break;
5677
5678 case GET_FROM_C_STRING:
5679 /* Current display element of IT is from a C string. */
5680 IT_BYTEPOS (*it) += it->len;
5681 IT_CHARPOS (*it) += 1;
5682 break;
5683
5684 case GET_FROM_DISPLAY_VECTOR:
5685 /* Current display element of IT is from a display table entry.
5686 Advance in the display table definition. Reset it to null if
5687 end reached, and continue with characters from buffers/
5688 strings. */
5689 ++it->current.dpvec_index;
5690
5691 /* Restore face of the iterator to what they were before the
5692 display vector entry (these entries may contain faces). */
5693 it->face_id = it->saved_face_id;
5694
5695 if (it->dpvec + it->current.dpvec_index == it->dpend)
5696 {
5697 if (it->s)
5698 it->method = GET_FROM_C_STRING;
5699 else if (STRINGP (it->string))
5700 it->method = GET_FROM_STRING;
5701 else
5702 it->method = GET_FROM_BUFFER;
5703
5704 it->dpvec = NULL;
5705 it->current.dpvec_index = -1;
5706
5707 /* Skip over characters which were displayed via IT->dpvec. */
5708 if (it->dpvec_char_len < 0)
5709 reseat_at_next_visible_line_start (it, 1);
5710 else if (it->dpvec_char_len > 0)
5711 {
5712 if (it->method == GET_FROM_STRING
5713 && it->n_overlay_strings > 0)
5714 it->ignore_overlay_strings_at_pos_p = 1;
5715 it->len = it->dpvec_char_len;
5716 set_iterator_to_next (it, reseat_p);
5717 }
5718
5719 /* Recheck faces after display vector */
5720 it->stop_charpos = IT_CHARPOS (*it);
5721 }
5722 break;
5723
5724 case GET_FROM_STRING:
5725 /* Current display element is a character from a Lisp string. */
5726 xassert (it->s == NULL && STRINGP (it->string));
5727 IT_STRING_BYTEPOS (*it) += it->len;
5728 IT_STRING_CHARPOS (*it) += 1;
5729
5730 consider_string_end:
5731
5732 if (it->current.overlay_string_index >= 0)
5733 {
5734 /* IT->string is an overlay string. Advance to the
5735 next, if there is one. */
5736 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5737 next_overlay_string (it);
5738 }
5739 else
5740 {
5741 /* IT->string is not an overlay string. If we reached
5742 its end, and there is something on IT->stack, proceed
5743 with what is on the stack. This can be either another
5744 string, this time an overlay string, or a buffer. */
5745 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5746 && it->sp > 0)
5747 {
5748 pop_it (it);
5749 if (STRINGP (it->string))
5750 goto consider_string_end;
5751 it->method = GET_FROM_BUFFER;
5752 }
5753 }
5754 break;
5755
5756 case GET_FROM_IMAGE:
5757 case GET_FROM_STRETCH:
5758 /* The position etc with which we have to proceed are on
5759 the stack. The position may be at the end of a string,
5760 if the `display' property takes up the whole string. */
5761 xassert (it->sp > 0);
5762 pop_it (it);
5763 it->image_id = 0;
5764 if (STRINGP (it->string))
5765 {
5766 it->method = GET_FROM_STRING;
5767 goto consider_string_end;
5768 }
5769 it->method = GET_FROM_BUFFER;
5770 break;
5771
5772 default:
5773 /* There are no other methods defined, so this should be a bug. */
5774 abort ();
5775 }
5776
5777 xassert (it->method != GET_FROM_STRING
5778 || (STRINGP (it->string)
5779 && IT_STRING_CHARPOS (*it) >= 0));
5780 }
5781
5782 /* Load IT's display element fields with information about the next
5783 display element which comes from a display table entry or from the
5784 result of translating a control character to one of the forms `^C'
5785 or `\003'.
5786
5787 IT->dpvec holds the glyphs to return as characters.
5788 IT->saved_face_id holds the face id before the display vector--
5789 it is restored into IT->face_idin set_iterator_to_next. */
5790
5791 static int
5792 next_element_from_display_vector (it)
5793 struct it *it;
5794 {
5795 /* Precondition. */
5796 xassert (it->dpvec && it->current.dpvec_index >= 0);
5797
5798 it->face_id = it->saved_face_id;
5799
5800 if (INTEGERP (*it->dpvec)
5801 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5802 {
5803 GLYPH g;
5804
5805 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5806 it->c = FAST_GLYPH_CHAR (g);
5807 it->len = CHAR_BYTES (it->c);
5808
5809 /* The entry may contain a face id to use. Such a face id is
5810 the id of a Lisp face, not a realized face. A face id of
5811 zero means no face is specified. */
5812 if (it->dpvec_face_id >= 0)
5813 it->face_id = it->dpvec_face_id;
5814 else
5815 {
5816 int lface_id = FAST_GLYPH_FACE (g);
5817 if (lface_id > 0)
5818 it->face_id = merge_faces (it->f, Qt, lface_id,
5819 it->saved_face_id);
5820 }
5821 }
5822 else
5823 /* Display table entry is invalid. Return a space. */
5824 it->c = ' ', it->len = 1;
5825
5826 /* Don't change position and object of the iterator here. They are
5827 still the values of the character that had this display table
5828 entry or was translated, and that's what we want. */
5829 it->what = IT_CHARACTER;
5830 return 1;
5831 }
5832
5833
5834 /* Load IT with the next display element from Lisp string IT->string.
5835 IT->current.string_pos is the current position within the string.
5836 If IT->current.overlay_string_index >= 0, the Lisp string is an
5837 overlay string. */
5838
5839 static int
5840 next_element_from_string (it)
5841 struct it *it;
5842 {
5843 struct text_pos position;
5844
5845 xassert (STRINGP (it->string));
5846 xassert (IT_STRING_CHARPOS (*it) >= 0);
5847 position = it->current.string_pos;
5848
5849 /* Time to check for invisible text? */
5850 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5851 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5852 {
5853 handle_stop (it);
5854
5855 /* Since a handler may have changed IT->method, we must
5856 recurse here. */
5857 return get_next_display_element (it);
5858 }
5859
5860 if (it->current.overlay_string_index >= 0)
5861 {
5862 /* Get the next character from an overlay string. In overlay
5863 strings, There is no field width or padding with spaces to
5864 do. */
5865 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5866 {
5867 it->what = IT_EOB;
5868 return 0;
5869 }
5870 else if (STRING_MULTIBYTE (it->string))
5871 {
5872 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5873 const unsigned char *s = (SDATA (it->string)
5874 + IT_STRING_BYTEPOS (*it));
5875 it->c = string_char_and_length (s, remaining, &it->len);
5876 }
5877 else
5878 {
5879 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5880 it->len = 1;
5881 }
5882 }
5883 else
5884 {
5885 /* Get the next character from a Lisp string that is not an
5886 overlay string. Such strings come from the mode line, for
5887 example. We may have to pad with spaces, or truncate the
5888 string. See also next_element_from_c_string. */
5889 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5890 {
5891 it->what = IT_EOB;
5892 return 0;
5893 }
5894 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5895 {
5896 /* Pad with spaces. */
5897 it->c = ' ', it->len = 1;
5898 CHARPOS (position) = BYTEPOS (position) = -1;
5899 }
5900 else if (STRING_MULTIBYTE (it->string))
5901 {
5902 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5903 const unsigned char *s = (SDATA (it->string)
5904 + IT_STRING_BYTEPOS (*it));
5905 it->c = string_char_and_length (s, maxlen, &it->len);
5906 }
5907 else
5908 {
5909 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5910 it->len = 1;
5911 }
5912 }
5913
5914 /* Record what we have and where it came from. Note that we store a
5915 buffer position in IT->position although it could arguably be a
5916 string position. */
5917 it->what = IT_CHARACTER;
5918 it->object = it->string;
5919 it->position = position;
5920 return 1;
5921 }
5922
5923
5924 /* Load IT with next display element from C string IT->s.
5925 IT->string_nchars is the maximum number of characters to return
5926 from the string. IT->end_charpos may be greater than
5927 IT->string_nchars when this function is called, in which case we
5928 may have to return padding spaces. Value is zero if end of string
5929 reached, including padding spaces. */
5930
5931 static int
5932 next_element_from_c_string (it)
5933 struct it *it;
5934 {
5935 int success_p = 1;
5936
5937 xassert (it->s);
5938 it->what = IT_CHARACTER;
5939 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5940 it->object = Qnil;
5941
5942 /* IT's position can be greater IT->string_nchars in case a field
5943 width or precision has been specified when the iterator was
5944 initialized. */
5945 if (IT_CHARPOS (*it) >= it->end_charpos)
5946 {
5947 /* End of the game. */
5948 it->what = IT_EOB;
5949 success_p = 0;
5950 }
5951 else if (IT_CHARPOS (*it) >= it->string_nchars)
5952 {
5953 /* Pad with spaces. */
5954 it->c = ' ', it->len = 1;
5955 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5956 }
5957 else if (it->multibyte_p)
5958 {
5959 /* Implementation note: The calls to strlen apparently aren't a
5960 performance problem because there is no noticeable performance
5961 difference between Emacs running in unibyte or multibyte mode. */
5962 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5963 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5964 maxlen, &it->len);
5965 }
5966 else
5967 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5968
5969 return success_p;
5970 }
5971
5972
5973 /* Set up IT to return characters from an ellipsis, if appropriate.
5974 The definition of the ellipsis glyphs may come from a display table
5975 entry. This function Fills IT with the first glyph from the
5976 ellipsis if an ellipsis is to be displayed. */
5977
5978 static int
5979 next_element_from_ellipsis (it)
5980 struct it *it;
5981 {
5982 if (it->selective_display_ellipsis_p)
5983 setup_for_ellipsis (it, it->len);
5984 else
5985 {
5986 /* The face at the current position may be different from the
5987 face we find after the invisible text. Remember what it
5988 was in IT->saved_face_id, and signal that it's there by
5989 setting face_before_selective_p. */
5990 it->saved_face_id = it->face_id;
5991 it->method = GET_FROM_BUFFER;
5992 reseat_at_next_visible_line_start (it, 1);
5993 it->face_before_selective_p = 1;
5994 }
5995
5996 return get_next_display_element (it);
5997 }
5998
5999
6000 /* Deliver an image display element. The iterator IT is already
6001 filled with image information (done in handle_display_prop). Value
6002 is always 1. */
6003
6004
6005 static int
6006 next_element_from_image (it)
6007 struct it *it;
6008 {
6009 it->what = IT_IMAGE;
6010 return 1;
6011 }
6012
6013
6014 /* Fill iterator IT with next display element from a stretch glyph
6015 property. IT->object is the value of the text property. Value is
6016 always 1. */
6017
6018 static int
6019 next_element_from_stretch (it)
6020 struct it *it;
6021 {
6022 it->what = IT_STRETCH;
6023 return 1;
6024 }
6025
6026
6027 /* Load IT with the next display element from current_buffer. Value
6028 is zero if end of buffer reached. IT->stop_charpos is the next
6029 position at which to stop and check for text properties or buffer
6030 end. */
6031
6032 static int
6033 next_element_from_buffer (it)
6034 struct it *it;
6035 {
6036 int success_p = 1;
6037
6038 /* Check this assumption, otherwise, we would never enter the
6039 if-statement, below. */
6040 xassert (IT_CHARPOS (*it) >= BEGV
6041 && IT_CHARPOS (*it) <= it->stop_charpos);
6042
6043 if (IT_CHARPOS (*it) >= it->stop_charpos)
6044 {
6045 if (IT_CHARPOS (*it) >= it->end_charpos)
6046 {
6047 int overlay_strings_follow_p;
6048
6049 /* End of the game, except when overlay strings follow that
6050 haven't been returned yet. */
6051 if (it->overlay_strings_at_end_processed_p)
6052 overlay_strings_follow_p = 0;
6053 else
6054 {
6055 it->overlay_strings_at_end_processed_p = 1;
6056 overlay_strings_follow_p = get_overlay_strings (it, 0);
6057 }
6058
6059 if (overlay_strings_follow_p)
6060 success_p = get_next_display_element (it);
6061 else
6062 {
6063 it->what = IT_EOB;
6064 it->position = it->current.pos;
6065 success_p = 0;
6066 }
6067 }
6068 else
6069 {
6070 handle_stop (it);
6071 return get_next_display_element (it);
6072 }
6073 }
6074 else
6075 {
6076 /* No face changes, overlays etc. in sight, so just return a
6077 character from current_buffer. */
6078 unsigned char *p;
6079
6080 /* Maybe run the redisplay end trigger hook. Performance note:
6081 This doesn't seem to cost measurable time. */
6082 if (it->redisplay_end_trigger_charpos
6083 && it->glyph_row
6084 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6085 run_redisplay_end_trigger_hook (it);
6086
6087 /* Get the next character, maybe multibyte. */
6088 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6089 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6090 {
6091 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
6092 - IT_BYTEPOS (*it));
6093 it->c = string_char_and_length (p, maxlen, &it->len);
6094 }
6095 else
6096 it->c = *p, it->len = 1;
6097
6098 /* Record what we have and where it came from. */
6099 it->what = IT_CHARACTER;;
6100 it->object = it->w->buffer;
6101 it->position = it->current.pos;
6102
6103 /* Normally we return the character found above, except when we
6104 really want to return an ellipsis for selective display. */
6105 if (it->selective)
6106 {
6107 if (it->c == '\n')
6108 {
6109 /* A value of selective > 0 means hide lines indented more
6110 than that number of columns. */
6111 if (it->selective > 0
6112 && IT_CHARPOS (*it) + 1 < ZV
6113 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6114 IT_BYTEPOS (*it) + 1,
6115 (double) it->selective)) /* iftc */
6116 {
6117 success_p = next_element_from_ellipsis (it);
6118 it->dpvec_char_len = -1;
6119 }
6120 }
6121 else if (it->c == '\r' && it->selective == -1)
6122 {
6123 /* A value of selective == -1 means that everything from the
6124 CR to the end of the line is invisible, with maybe an
6125 ellipsis displayed for it. */
6126 success_p = next_element_from_ellipsis (it);
6127 it->dpvec_char_len = -1;
6128 }
6129 }
6130 }
6131
6132 /* Value is zero if end of buffer reached. */
6133 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6134 return success_p;
6135 }
6136
6137
6138 /* Run the redisplay end trigger hook for IT. */
6139
6140 static void
6141 run_redisplay_end_trigger_hook (it)
6142 struct it *it;
6143 {
6144 Lisp_Object args[3];
6145
6146 /* IT->glyph_row should be non-null, i.e. we should be actually
6147 displaying something, or otherwise we should not run the hook. */
6148 xassert (it->glyph_row);
6149
6150 /* Set up hook arguments. */
6151 args[0] = Qredisplay_end_trigger_functions;
6152 args[1] = it->window;
6153 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6154 it->redisplay_end_trigger_charpos = 0;
6155
6156 /* Since we are *trying* to run these functions, don't try to run
6157 them again, even if they get an error. */
6158 it->w->redisplay_end_trigger = Qnil;
6159 Frun_hook_with_args (3, args);
6160
6161 /* Notice if it changed the face of the character we are on. */
6162 handle_face_prop (it);
6163 }
6164
6165
6166 /* Deliver a composition display element. The iterator IT is already
6167 filled with composition information (done in
6168 handle_composition_prop). Value is always 1. */
6169
6170 static int
6171 next_element_from_composition (it)
6172 struct it *it;
6173 {
6174 it->what = IT_COMPOSITION;
6175 it->position = (STRINGP (it->string)
6176 ? it->current.string_pos
6177 : it->current.pos);
6178 return 1;
6179 }
6180
6181
6182 \f
6183 /***********************************************************************
6184 Moving an iterator without producing glyphs
6185 ***********************************************************************/
6186
6187 /* Check if iterator is at a position corresponding to a valid buffer
6188 position after some move_it_ call. */
6189
6190 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6191 ((it)->method == GET_FROM_STRING \
6192 ? IT_STRING_CHARPOS (*it) == 0 \
6193 : 1)
6194
6195
6196 /* Move iterator IT to a specified buffer or X position within one
6197 line on the display without producing glyphs.
6198
6199 OP should be a bit mask including some or all of these bits:
6200 MOVE_TO_X: Stop on reaching x-position TO_X.
6201 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
6202 Regardless of OP's value, stop in reaching the end of the display line.
6203
6204 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6205 This means, in particular, that TO_X includes window's horizontal
6206 scroll amount.
6207
6208 The return value has several possible values that
6209 say what condition caused the scan to stop:
6210
6211 MOVE_POS_MATCH_OR_ZV
6212 - when TO_POS or ZV was reached.
6213
6214 MOVE_X_REACHED
6215 -when TO_X was reached before TO_POS or ZV were reached.
6216
6217 MOVE_LINE_CONTINUED
6218 - when we reached the end of the display area and the line must
6219 be continued.
6220
6221 MOVE_LINE_TRUNCATED
6222 - when we reached the end of the display area and the line is
6223 truncated.
6224
6225 MOVE_NEWLINE_OR_CR
6226 - when we stopped at a line end, i.e. a newline or a CR and selective
6227 display is on. */
6228
6229 static enum move_it_result
6230 move_it_in_display_line_to (it, to_charpos, to_x, op)
6231 struct it *it;
6232 int to_charpos, to_x, op;
6233 {
6234 enum move_it_result result = MOVE_UNDEFINED;
6235 struct glyph_row *saved_glyph_row;
6236
6237 /* Don't produce glyphs in produce_glyphs. */
6238 saved_glyph_row = it->glyph_row;
6239 it->glyph_row = NULL;
6240
6241 #define BUFFER_POS_REACHED_P() \
6242 ((op & MOVE_TO_POS) != 0 \
6243 && BUFFERP (it->object) \
6244 && IT_CHARPOS (*it) >= to_charpos \
6245 && (it->method == GET_FROM_BUFFER \
6246 || (it->method == GET_FROM_DISPLAY_VECTOR \
6247 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6248
6249
6250 while (1)
6251 {
6252 int x, i, ascent = 0, descent = 0;
6253
6254 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
6255 if ((op & MOVE_TO_POS) != 0
6256 && BUFFERP (it->object)
6257 && it->method == GET_FROM_BUFFER
6258 && IT_CHARPOS (*it) > to_charpos)
6259 {
6260 result = MOVE_POS_MATCH_OR_ZV;
6261 break;
6262 }
6263
6264 /* Stop when ZV reached.
6265 We used to stop here when TO_CHARPOS reached as well, but that is
6266 too soon if this glyph does not fit on this line. So we handle it
6267 explicitly below. */
6268 if (!get_next_display_element (it)
6269 || (it->truncate_lines_p
6270 && BUFFER_POS_REACHED_P ()))
6271 {
6272 result = MOVE_POS_MATCH_OR_ZV;
6273 break;
6274 }
6275
6276 /* The call to produce_glyphs will get the metrics of the
6277 display element IT is loaded with. We record in x the
6278 x-position before this display element in case it does not
6279 fit on the line. */
6280 x = it->current_x;
6281
6282 /* Remember the line height so far in case the next element doesn't
6283 fit on the line. */
6284 if (!it->truncate_lines_p)
6285 {
6286 ascent = it->max_ascent;
6287 descent = it->max_descent;
6288 }
6289
6290 PRODUCE_GLYPHS (it);
6291
6292 if (it->area != TEXT_AREA)
6293 {
6294 set_iterator_to_next (it, 1);
6295 continue;
6296 }
6297
6298 /* The number of glyphs we get back in IT->nglyphs will normally
6299 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
6300 character on a terminal frame, or (iii) a line end. For the
6301 second case, IT->nglyphs - 1 padding glyphs will be present
6302 (on X frames, there is only one glyph produced for a
6303 composite character.
6304
6305 The behavior implemented below means, for continuation lines,
6306 that as many spaces of a TAB as fit on the current line are
6307 displayed there. For terminal frames, as many glyphs of a
6308 multi-glyph character are displayed in the current line, too.
6309 This is what the old redisplay code did, and we keep it that
6310 way. Under X, the whole shape of a complex character must
6311 fit on the line or it will be completely displayed in the
6312 next line.
6313
6314 Note that both for tabs and padding glyphs, all glyphs have
6315 the same width. */
6316 if (it->nglyphs)
6317 {
6318 /* More than one glyph or glyph doesn't fit on line. All
6319 glyphs have the same width. */
6320 int single_glyph_width = it->pixel_width / it->nglyphs;
6321 int new_x;
6322 int x_before_this_char = x;
6323 int hpos_before_this_char = it->hpos;
6324
6325 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6326 {
6327 new_x = x + single_glyph_width;
6328
6329 /* We want to leave anything reaching TO_X to the caller. */
6330 if ((op & MOVE_TO_X) && new_x > to_x)
6331 {
6332 if (BUFFER_POS_REACHED_P ())
6333 goto buffer_pos_reached;
6334 it->current_x = x;
6335 result = MOVE_X_REACHED;
6336 break;
6337 }
6338 else if (/* Lines are continued. */
6339 !it->truncate_lines_p
6340 && (/* And glyph doesn't fit on the line. */
6341 new_x > it->last_visible_x
6342 /* Or it fits exactly and we're on a window
6343 system frame. */
6344 || (new_x == it->last_visible_x
6345 && FRAME_WINDOW_P (it->f))))
6346 {
6347 if (/* IT->hpos == 0 means the very first glyph
6348 doesn't fit on the line, e.g. a wide image. */
6349 it->hpos == 0
6350 || (new_x == it->last_visible_x
6351 && FRAME_WINDOW_P (it->f)))
6352 {
6353 ++it->hpos;
6354 it->current_x = new_x;
6355
6356 /* The character's last glyph just barely fits
6357 in this row. */
6358 if (i == it->nglyphs - 1)
6359 {
6360 /* If this is the destination position,
6361 return a position *before* it in this row,
6362 now that we know it fits in this row. */
6363 if (BUFFER_POS_REACHED_P ())
6364 {
6365 it->hpos = hpos_before_this_char;
6366 it->current_x = x_before_this_char;
6367 result = MOVE_POS_MATCH_OR_ZV;
6368 break;
6369 }
6370
6371 set_iterator_to_next (it, 1);
6372 #ifdef HAVE_WINDOW_SYSTEM
6373 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6374 {
6375 if (!get_next_display_element (it))
6376 {
6377 result = MOVE_POS_MATCH_OR_ZV;
6378 break;
6379 }
6380 if (BUFFER_POS_REACHED_P ())
6381 {
6382 if (ITERATOR_AT_END_OF_LINE_P (it))
6383 result = MOVE_POS_MATCH_OR_ZV;
6384 else
6385 result = MOVE_LINE_CONTINUED;
6386 break;
6387 }
6388 if (ITERATOR_AT_END_OF_LINE_P (it))
6389 {
6390 result = MOVE_NEWLINE_OR_CR;
6391 break;
6392 }
6393 }
6394 #endif /* HAVE_WINDOW_SYSTEM */
6395 }
6396 }
6397 else
6398 {
6399 it->current_x = x;
6400 it->max_ascent = ascent;
6401 it->max_descent = descent;
6402 }
6403
6404 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6405 IT_CHARPOS (*it)));
6406 result = MOVE_LINE_CONTINUED;
6407 break;
6408 }
6409 else if (BUFFER_POS_REACHED_P ())
6410 goto buffer_pos_reached;
6411 else if (new_x > it->first_visible_x)
6412 {
6413 /* Glyph is visible. Increment number of glyphs that
6414 would be displayed. */
6415 ++it->hpos;
6416 }
6417 else
6418 {
6419 /* Glyph is completely off the left margin of the display
6420 area. Nothing to do. */
6421 }
6422 }
6423
6424 if (result != MOVE_UNDEFINED)
6425 break;
6426 }
6427 else if (BUFFER_POS_REACHED_P ())
6428 {
6429 buffer_pos_reached:
6430 it->current_x = x;
6431 it->max_ascent = ascent;
6432 it->max_descent = descent;
6433 result = MOVE_POS_MATCH_OR_ZV;
6434 break;
6435 }
6436 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6437 {
6438 /* Stop when TO_X specified and reached. This check is
6439 necessary here because of lines consisting of a line end,
6440 only. The line end will not produce any glyphs and we
6441 would never get MOVE_X_REACHED. */
6442 xassert (it->nglyphs == 0);
6443 result = MOVE_X_REACHED;
6444 break;
6445 }
6446
6447 /* Is this a line end? If yes, we're done. */
6448 if (ITERATOR_AT_END_OF_LINE_P (it))
6449 {
6450 result = MOVE_NEWLINE_OR_CR;
6451 break;
6452 }
6453
6454 /* The current display element has been consumed. Advance
6455 to the next. */
6456 set_iterator_to_next (it, 1);
6457
6458 /* Stop if lines are truncated and IT's current x-position is
6459 past the right edge of the window now. */
6460 if (it->truncate_lines_p
6461 && it->current_x >= it->last_visible_x)
6462 {
6463 #ifdef HAVE_WINDOW_SYSTEM
6464 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6465 {
6466 if (!get_next_display_element (it)
6467 || BUFFER_POS_REACHED_P ())
6468 {
6469 result = MOVE_POS_MATCH_OR_ZV;
6470 break;
6471 }
6472 if (ITERATOR_AT_END_OF_LINE_P (it))
6473 {
6474 result = MOVE_NEWLINE_OR_CR;
6475 break;
6476 }
6477 }
6478 #endif /* HAVE_WINDOW_SYSTEM */
6479 result = MOVE_LINE_TRUNCATED;
6480 break;
6481 }
6482 }
6483
6484 #undef BUFFER_POS_REACHED_P
6485
6486 /* Restore the iterator settings altered at the beginning of this
6487 function. */
6488 it->glyph_row = saved_glyph_row;
6489 return result;
6490 }
6491
6492
6493 /* Move IT forward until it satisfies one or more of the criteria in
6494 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6495
6496 OP is a bit-mask that specifies where to stop, and in particular,
6497 which of those four position arguments makes a difference. See the
6498 description of enum move_operation_enum.
6499
6500 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6501 screen line, this function will set IT to the next position >
6502 TO_CHARPOS. */
6503
6504 void
6505 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6506 struct it *it;
6507 int to_charpos, to_x, to_y, to_vpos;
6508 int op;
6509 {
6510 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6511 int line_height;
6512 int reached = 0;
6513
6514 for (;;)
6515 {
6516 if (op & MOVE_TO_VPOS)
6517 {
6518 /* If no TO_CHARPOS and no TO_X specified, stop at the
6519 start of the line TO_VPOS. */
6520 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6521 {
6522 if (it->vpos == to_vpos)
6523 {
6524 reached = 1;
6525 break;
6526 }
6527 else
6528 skip = move_it_in_display_line_to (it, -1, -1, 0);
6529 }
6530 else
6531 {
6532 /* TO_VPOS >= 0 means stop at TO_X in the line at
6533 TO_VPOS, or at TO_POS, whichever comes first. */
6534 if (it->vpos == to_vpos)
6535 {
6536 reached = 2;
6537 break;
6538 }
6539
6540 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6541
6542 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6543 {
6544 reached = 3;
6545 break;
6546 }
6547 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6548 {
6549 /* We have reached TO_X but not in the line we want. */
6550 skip = move_it_in_display_line_to (it, to_charpos,
6551 -1, MOVE_TO_POS);
6552 if (skip == MOVE_POS_MATCH_OR_ZV)
6553 {
6554 reached = 4;
6555 break;
6556 }
6557 }
6558 }
6559 }
6560 else if (op & MOVE_TO_Y)
6561 {
6562 struct it it_backup;
6563
6564 /* TO_Y specified means stop at TO_X in the line containing
6565 TO_Y---or at TO_CHARPOS if this is reached first. The
6566 problem is that we can't really tell whether the line
6567 contains TO_Y before we have completely scanned it, and
6568 this may skip past TO_X. What we do is to first scan to
6569 TO_X.
6570
6571 If TO_X is not specified, use a TO_X of zero. The reason
6572 is to make the outcome of this function more predictable.
6573 If we didn't use TO_X == 0, we would stop at the end of
6574 the line which is probably not what a caller would expect
6575 to happen. */
6576 skip = move_it_in_display_line_to (it, to_charpos,
6577 ((op & MOVE_TO_X)
6578 ? to_x : 0),
6579 (MOVE_TO_X
6580 | (op & MOVE_TO_POS)));
6581
6582 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6583 if (skip == MOVE_POS_MATCH_OR_ZV)
6584 {
6585 reached = 5;
6586 break;
6587 }
6588
6589 /* If TO_X was reached, we would like to know whether TO_Y
6590 is in the line. This can only be said if we know the
6591 total line height which requires us to scan the rest of
6592 the line. */
6593 if (skip == MOVE_X_REACHED)
6594 {
6595 it_backup = *it;
6596 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6597 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6598 op & MOVE_TO_POS);
6599 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6600 }
6601
6602 /* Now, decide whether TO_Y is in this line. */
6603 line_height = it->max_ascent + it->max_descent;
6604 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6605
6606 if (to_y >= it->current_y
6607 && to_y < it->current_y + line_height)
6608 {
6609 if (skip == MOVE_X_REACHED)
6610 /* If TO_Y is in this line and TO_X was reached above,
6611 we scanned too far. We have to restore IT's settings
6612 to the ones before skipping. */
6613 *it = it_backup;
6614 reached = 6;
6615 }
6616 else if (skip == MOVE_X_REACHED)
6617 {
6618 skip = skip2;
6619 if (skip == MOVE_POS_MATCH_OR_ZV)
6620 reached = 7;
6621 }
6622
6623 if (reached)
6624 break;
6625 }
6626 else
6627 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6628
6629 switch (skip)
6630 {
6631 case MOVE_POS_MATCH_OR_ZV:
6632 reached = 8;
6633 goto out;
6634
6635 case MOVE_NEWLINE_OR_CR:
6636 set_iterator_to_next (it, 1);
6637 it->continuation_lines_width = 0;
6638 break;
6639
6640 case MOVE_LINE_TRUNCATED:
6641 it->continuation_lines_width = 0;
6642 reseat_at_next_visible_line_start (it, 0);
6643 if ((op & MOVE_TO_POS) != 0
6644 && IT_CHARPOS (*it) > to_charpos)
6645 {
6646 reached = 9;
6647 goto out;
6648 }
6649 break;
6650
6651 case MOVE_LINE_CONTINUED:
6652 it->continuation_lines_width += it->current_x;
6653 break;
6654
6655 default:
6656 abort ();
6657 }
6658
6659 /* Reset/increment for the next run. */
6660 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6661 it->current_x = it->hpos = 0;
6662 it->current_y += it->max_ascent + it->max_descent;
6663 ++it->vpos;
6664 last_height = it->max_ascent + it->max_descent;
6665 last_max_ascent = it->max_ascent;
6666 it->max_ascent = it->max_descent = 0;
6667 }
6668
6669 out:
6670
6671 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6672 }
6673
6674
6675 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6676
6677 If DY > 0, move IT backward at least that many pixels. DY = 0
6678 means move IT backward to the preceding line start or BEGV. This
6679 function may move over more than DY pixels if IT->current_y - DY
6680 ends up in the middle of a line; in this case IT->current_y will be
6681 set to the top of the line moved to. */
6682
6683 void
6684 move_it_vertically_backward (it, dy)
6685 struct it *it;
6686 int dy;
6687 {
6688 int nlines, h;
6689 struct it it2, it3;
6690 int start_pos;
6691
6692 move_further_back:
6693 xassert (dy >= 0);
6694
6695 start_pos = IT_CHARPOS (*it);
6696
6697 /* Estimate how many newlines we must move back. */
6698 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6699
6700 /* Set the iterator's position that many lines back. */
6701 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6702 back_to_previous_visible_line_start (it);
6703
6704 /* Reseat the iterator here. When moving backward, we don't want
6705 reseat to skip forward over invisible text, set up the iterator
6706 to deliver from overlay strings at the new position etc. So,
6707 use reseat_1 here. */
6708 reseat_1 (it, it->current.pos, 1);
6709
6710 /* We are now surely at a line start. */
6711 it->current_x = it->hpos = 0;
6712 it->continuation_lines_width = 0;
6713
6714 /* Move forward and see what y-distance we moved. First move to the
6715 start of the next line so that we get its height. We need this
6716 height to be able to tell whether we reached the specified
6717 y-distance. */
6718 it2 = *it;
6719 it2.max_ascent = it2.max_descent = 0;
6720 do
6721 {
6722 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6723 MOVE_TO_POS | MOVE_TO_VPOS);
6724 }
6725 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
6726 xassert (IT_CHARPOS (*it) >= BEGV);
6727 it3 = it2;
6728
6729 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6730 xassert (IT_CHARPOS (*it) >= BEGV);
6731 /* H is the actual vertical distance from the position in *IT
6732 and the starting position. */
6733 h = it2.current_y - it->current_y;
6734 /* NLINES is the distance in number of lines. */
6735 nlines = it2.vpos - it->vpos;
6736
6737 /* Correct IT's y and vpos position
6738 so that they are relative to the starting point. */
6739 it->vpos -= nlines;
6740 it->current_y -= h;
6741
6742 if (dy == 0)
6743 {
6744 /* DY == 0 means move to the start of the screen line. The
6745 value of nlines is > 0 if continuation lines were involved. */
6746 if (nlines > 0)
6747 move_it_by_lines (it, nlines, 1);
6748 #if 0
6749 /* I think this assert is bogus if buffer contains
6750 invisible text or images. KFS. */
6751 xassert (IT_CHARPOS (*it) <= start_pos);
6752 #endif
6753 }
6754 else
6755 {
6756 /* The y-position we try to reach, relative to *IT.
6757 Note that H has been subtracted in front of the if-statement. */
6758 int target_y = it->current_y + h - dy;
6759 int y0 = it3.current_y;
6760 int y1 = line_bottom_y (&it3);
6761 int line_height = y1 - y0;
6762
6763 /* If we did not reach target_y, try to move further backward if
6764 we can. If we moved too far backward, try to move forward. */
6765 if (target_y < it->current_y
6766 /* This is heuristic. In a window that's 3 lines high, with
6767 a line height of 13 pixels each, recentering with point
6768 on the bottom line will try to move -39/2 = 19 pixels
6769 backward. Try to avoid moving into the first line. */
6770 && (it->current_y - target_y
6771 > min (window_box_height (it->w), line_height * 2 / 3))
6772 && IT_CHARPOS (*it) > BEGV)
6773 {
6774 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6775 target_y - it->current_y));
6776 dy = it->current_y - target_y;
6777 goto move_further_back;
6778 }
6779 else if (target_y >= it->current_y + line_height
6780 && IT_CHARPOS (*it) < ZV)
6781 {
6782 /* Should move forward by at least one line, maybe more.
6783
6784 Note: Calling move_it_by_lines can be expensive on
6785 terminal frames, where compute_motion is used (via
6786 vmotion) to do the job, when there are very long lines
6787 and truncate-lines is nil. That's the reason for
6788 treating terminal frames specially here. */
6789
6790 if (!FRAME_WINDOW_P (it->f))
6791 move_it_vertically (it, target_y - (it->current_y + line_height));
6792 else
6793 {
6794 do
6795 {
6796 move_it_by_lines (it, 1, 1);
6797 }
6798 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6799 }
6800
6801 #if 0
6802 /* I think this assert is bogus if buffer contains
6803 invisible text or images. KFS. */
6804 xassert (IT_CHARPOS (*it) >= BEGV);
6805 #endif
6806 }
6807 }
6808 }
6809
6810
6811 /* Move IT by a specified amount of pixel lines DY. DY negative means
6812 move backwards. DY = 0 means move to start of screen line. At the
6813 end, IT will be on the start of a screen line. */
6814
6815 void
6816 move_it_vertically (it, dy)
6817 struct it *it;
6818 int dy;
6819 {
6820 if (dy <= 0)
6821 move_it_vertically_backward (it, -dy);
6822 else
6823 {
6824 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6825 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6826 MOVE_TO_POS | MOVE_TO_Y);
6827 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6828
6829 /* If buffer ends in ZV without a newline, move to the start of
6830 the line to satisfy the post-condition. */
6831 if (IT_CHARPOS (*it) == ZV
6832 && ZV > BEGV
6833 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6834 move_it_by_lines (it, 0, 0);
6835 }
6836 }
6837
6838
6839 /* Move iterator IT past the end of the text line it is in. */
6840
6841 void
6842 move_it_past_eol (it)
6843 struct it *it;
6844 {
6845 enum move_it_result rc;
6846
6847 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6848 if (rc == MOVE_NEWLINE_OR_CR)
6849 set_iterator_to_next (it, 0);
6850 }
6851
6852
6853 #if 0 /* Currently not used. */
6854
6855 /* Return non-zero if some text between buffer positions START_CHARPOS
6856 and END_CHARPOS is invisible. IT->window is the window for text
6857 property lookup. */
6858
6859 static int
6860 invisible_text_between_p (it, start_charpos, end_charpos)
6861 struct it *it;
6862 int start_charpos, end_charpos;
6863 {
6864 Lisp_Object prop, limit;
6865 int invisible_found_p;
6866
6867 xassert (it != NULL && start_charpos <= end_charpos);
6868
6869 /* Is text at START invisible? */
6870 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6871 it->window);
6872 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6873 invisible_found_p = 1;
6874 else
6875 {
6876 limit = Fnext_single_char_property_change (make_number (start_charpos),
6877 Qinvisible, Qnil,
6878 make_number (end_charpos));
6879 invisible_found_p = XFASTINT (limit) < end_charpos;
6880 }
6881
6882 return invisible_found_p;
6883 }
6884
6885 #endif /* 0 */
6886
6887
6888 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6889 negative means move up. DVPOS == 0 means move to the start of the
6890 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6891 NEED_Y_P is zero, IT->current_y will be left unchanged.
6892
6893 Further optimization ideas: If we would know that IT->f doesn't use
6894 a face with proportional font, we could be faster for
6895 truncate-lines nil. */
6896
6897 void
6898 move_it_by_lines (it, dvpos, need_y_p)
6899 struct it *it;
6900 int dvpos, need_y_p;
6901 {
6902 struct position pos;
6903
6904 if (!FRAME_WINDOW_P (it->f))
6905 {
6906 struct text_pos textpos;
6907
6908 /* We can use vmotion on frames without proportional fonts. */
6909 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6910 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6911 reseat (it, textpos, 1);
6912 it->vpos += pos.vpos;
6913 it->current_y += pos.vpos;
6914 }
6915 else if (dvpos == 0)
6916 {
6917 /* DVPOS == 0 means move to the start of the screen line. */
6918 move_it_vertically_backward (it, 0);
6919 xassert (it->current_x == 0 && it->hpos == 0);
6920 /* Let next call to line_bottom_y calculate real line height */
6921 last_height = 0;
6922 }
6923 else if (dvpos > 0)
6924 {
6925 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6926 if (!IT_POS_VALID_AFTER_MOVE_P (it))
6927 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
6928 }
6929 else
6930 {
6931 struct it it2;
6932 int start_charpos, i;
6933
6934 /* Start at the beginning of the screen line containing IT's
6935 position. This may actually move vertically backwards,
6936 in case of overlays, so adjust dvpos accordingly. */
6937 dvpos += it->vpos;
6938 move_it_vertically_backward (it, 0);
6939 dvpos -= it->vpos;
6940
6941 /* Go back -DVPOS visible lines and reseat the iterator there. */
6942 start_charpos = IT_CHARPOS (*it);
6943 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
6944 back_to_previous_visible_line_start (it);
6945 reseat (it, it->current.pos, 1);
6946
6947 /* Move further back if we end up in a string or an image. */
6948 while (!IT_POS_VALID_AFTER_MOVE_P (it))
6949 {
6950 /* First try to move to start of display line. */
6951 dvpos += it->vpos;
6952 move_it_vertically_backward (it, 0);
6953 dvpos -= it->vpos;
6954 if (IT_POS_VALID_AFTER_MOVE_P (it))
6955 break;
6956 /* If start of line is still in string or image,
6957 move further back. */
6958 back_to_previous_visible_line_start (it);
6959 reseat (it, it->current.pos, 1);
6960 dvpos--;
6961 }
6962
6963 it->current_x = it->hpos = 0;
6964
6965 /* Above call may have moved too far if continuation lines
6966 are involved. Scan forward and see if it did. */
6967 it2 = *it;
6968 it2.vpos = it2.current_y = 0;
6969 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6970 it->vpos -= it2.vpos;
6971 it->current_y -= it2.current_y;
6972 it->current_x = it->hpos = 0;
6973
6974 /* If we moved too far back, move IT some lines forward. */
6975 if (it2.vpos > -dvpos)
6976 {
6977 int delta = it2.vpos + dvpos;
6978 it2 = *it;
6979 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6980 /* Move back again if we got too far ahead. */
6981 if (IT_CHARPOS (*it) >= start_charpos)
6982 *it = it2;
6983 }
6984 }
6985 }
6986
6987 /* Return 1 if IT points into the middle of a display vector. */
6988
6989 int
6990 in_display_vector_p (it)
6991 struct it *it;
6992 {
6993 return (it->method == GET_FROM_DISPLAY_VECTOR
6994 && it->current.dpvec_index > 0
6995 && it->dpvec + it->current.dpvec_index != it->dpend);
6996 }
6997
6998 \f
6999 /***********************************************************************
7000 Messages
7001 ***********************************************************************/
7002
7003
7004 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7005 to *Messages*. */
7006
7007 void
7008 add_to_log (format, arg1, arg2)
7009 char *format;
7010 Lisp_Object arg1, arg2;
7011 {
7012 Lisp_Object args[3];
7013 Lisp_Object msg, fmt;
7014 char *buffer;
7015 int len;
7016 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7017 USE_SAFE_ALLOCA;
7018
7019 /* Do nothing if called asynchronously. Inserting text into
7020 a buffer may call after-change-functions and alike and
7021 that would means running Lisp asynchronously. */
7022 if (handling_signal)
7023 return;
7024
7025 fmt = msg = Qnil;
7026 GCPRO4 (fmt, msg, arg1, arg2);
7027
7028 args[0] = fmt = build_string (format);
7029 args[1] = arg1;
7030 args[2] = arg2;
7031 msg = Fformat (3, args);
7032
7033 len = SBYTES (msg) + 1;
7034 SAFE_ALLOCA (buffer, char *, len);
7035 bcopy (SDATA (msg), buffer, len);
7036
7037 message_dolog (buffer, len - 1, 1, 0);
7038 SAFE_FREE ();
7039
7040 UNGCPRO;
7041 }
7042
7043
7044 /* Output a newline in the *Messages* buffer if "needs" one. */
7045
7046 void
7047 message_log_maybe_newline ()
7048 {
7049 if (message_log_need_newline)
7050 message_dolog ("", 0, 1, 0);
7051 }
7052
7053
7054 /* Add a string M of length NBYTES to the message log, optionally
7055 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7056 nonzero, means interpret the contents of M as multibyte. This
7057 function calls low-level routines in order to bypass text property
7058 hooks, etc. which might not be safe to run.
7059
7060 This may GC (insert may run before/after change hooks),
7061 so the buffer M must NOT point to a Lisp string. */
7062
7063 void
7064 message_dolog (m, nbytes, nlflag, multibyte)
7065 const char *m;
7066 int nbytes, nlflag, multibyte;
7067 {
7068 if (!NILP (Vmemory_full))
7069 return;
7070
7071 if (!NILP (Vmessage_log_max))
7072 {
7073 struct buffer *oldbuf;
7074 Lisp_Object oldpoint, oldbegv, oldzv;
7075 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7076 int point_at_end = 0;
7077 int zv_at_end = 0;
7078 Lisp_Object old_deactivate_mark, tem;
7079 struct gcpro gcpro1;
7080
7081 old_deactivate_mark = Vdeactivate_mark;
7082 oldbuf = current_buffer;
7083 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7084 current_buffer->undo_list = Qt;
7085
7086 oldpoint = message_dolog_marker1;
7087 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7088 oldbegv = message_dolog_marker2;
7089 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7090 oldzv = message_dolog_marker3;
7091 set_marker_restricted (oldzv, make_number (ZV), Qnil);
7092 GCPRO1 (old_deactivate_mark);
7093
7094 if (PT == Z)
7095 point_at_end = 1;
7096 if (ZV == Z)
7097 zv_at_end = 1;
7098
7099 BEGV = BEG;
7100 BEGV_BYTE = BEG_BYTE;
7101 ZV = Z;
7102 ZV_BYTE = Z_BYTE;
7103 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7104
7105 /* Insert the string--maybe converting multibyte to single byte
7106 or vice versa, so that all the text fits the buffer. */
7107 if (multibyte
7108 && NILP (current_buffer->enable_multibyte_characters))
7109 {
7110 int i, c, char_bytes;
7111 unsigned char work[1];
7112
7113 /* Convert a multibyte string to single-byte
7114 for the *Message* buffer. */
7115 for (i = 0; i < nbytes; i += char_bytes)
7116 {
7117 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
7118 work[0] = (SINGLE_BYTE_CHAR_P (c)
7119 ? c
7120 : multibyte_char_to_unibyte (c, Qnil));
7121 insert_1_both (work, 1, 1, 1, 0, 0);
7122 }
7123 }
7124 else if (! multibyte
7125 && ! NILP (current_buffer->enable_multibyte_characters))
7126 {
7127 int i, c, char_bytes;
7128 unsigned char *msg = (unsigned char *) m;
7129 unsigned char str[MAX_MULTIBYTE_LENGTH];
7130 /* Convert a single-byte string to multibyte
7131 for the *Message* buffer. */
7132 for (i = 0; i < nbytes; i++)
7133 {
7134 c = unibyte_char_to_multibyte (msg[i]);
7135 char_bytes = CHAR_STRING (c, str);
7136 insert_1_both (str, 1, char_bytes, 1, 0, 0);
7137 }
7138 }
7139 else if (nbytes)
7140 insert_1 (m, nbytes, 1, 0, 0);
7141
7142 if (nlflag)
7143 {
7144 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
7145 insert_1 ("\n", 1, 1, 0, 0);
7146
7147 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
7148 this_bol = PT;
7149 this_bol_byte = PT_BYTE;
7150
7151 /* See if this line duplicates the previous one.
7152 If so, combine duplicates. */
7153 if (this_bol > BEG)
7154 {
7155 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
7156 prev_bol = PT;
7157 prev_bol_byte = PT_BYTE;
7158
7159 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
7160 this_bol, this_bol_byte);
7161 if (dup)
7162 {
7163 del_range_both (prev_bol, prev_bol_byte,
7164 this_bol, this_bol_byte, 0);
7165 if (dup > 1)
7166 {
7167 char dupstr[40];
7168 int duplen;
7169
7170 /* If you change this format, don't forget to also
7171 change message_log_check_duplicate. */
7172 sprintf (dupstr, " [%d times]", dup);
7173 duplen = strlen (dupstr);
7174 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
7175 insert_1 (dupstr, duplen, 1, 0, 1);
7176 }
7177 }
7178 }
7179
7180 /* If we have more than the desired maximum number of lines
7181 in the *Messages* buffer now, delete the oldest ones.
7182 This is safe because we don't have undo in this buffer. */
7183
7184 if (NATNUMP (Vmessage_log_max))
7185 {
7186 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
7187 -XFASTINT (Vmessage_log_max) - 1, 0);
7188 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
7189 }
7190 }
7191 BEGV = XMARKER (oldbegv)->charpos;
7192 BEGV_BYTE = marker_byte_position (oldbegv);
7193
7194 if (zv_at_end)
7195 {
7196 ZV = Z;
7197 ZV_BYTE = Z_BYTE;
7198 }
7199 else
7200 {
7201 ZV = XMARKER (oldzv)->charpos;
7202 ZV_BYTE = marker_byte_position (oldzv);
7203 }
7204
7205 if (point_at_end)
7206 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7207 else
7208 /* We can't do Fgoto_char (oldpoint) because it will run some
7209 Lisp code. */
7210 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
7211 XMARKER (oldpoint)->bytepos);
7212
7213 UNGCPRO;
7214 unchain_marker (XMARKER (oldpoint));
7215 unchain_marker (XMARKER (oldbegv));
7216 unchain_marker (XMARKER (oldzv));
7217
7218 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
7219 set_buffer_internal (oldbuf);
7220 if (NILP (tem))
7221 windows_or_buffers_changed = old_windows_or_buffers_changed;
7222 message_log_need_newline = !nlflag;
7223 Vdeactivate_mark = old_deactivate_mark;
7224 }
7225 }
7226
7227
7228 /* We are at the end of the buffer after just having inserted a newline.
7229 (Note: We depend on the fact we won't be crossing the gap.)
7230 Check to see if the most recent message looks a lot like the previous one.
7231 Return 0 if different, 1 if the new one should just replace it, or a
7232 value N > 1 if we should also append " [N times]". */
7233
7234 static int
7235 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
7236 int prev_bol, this_bol;
7237 int prev_bol_byte, this_bol_byte;
7238 {
7239 int i;
7240 int len = Z_BYTE - 1 - this_bol_byte;
7241 int seen_dots = 0;
7242 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
7243 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
7244
7245 for (i = 0; i < len; i++)
7246 {
7247 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
7248 seen_dots = 1;
7249 if (p1[i] != p2[i])
7250 return seen_dots;
7251 }
7252 p1 += len;
7253 if (*p1 == '\n')
7254 return 2;
7255 if (*p1++ == ' ' && *p1++ == '[')
7256 {
7257 int n = 0;
7258 while (*p1 >= '0' && *p1 <= '9')
7259 n = n * 10 + *p1++ - '0';
7260 if (strncmp (p1, " times]\n", 8) == 0)
7261 return n+1;
7262 }
7263 return 0;
7264 }
7265 \f
7266
7267 /* Display an echo area message M with a specified length of NBYTES
7268 bytes. The string may include null characters. If M is 0, clear
7269 out any existing message, and let the mini-buffer text show
7270 through.
7271
7272 This may GC, so the buffer M must NOT point to a Lisp string. */
7273
7274 void
7275 message2 (m, nbytes, multibyte)
7276 const char *m;
7277 int nbytes;
7278 int multibyte;
7279 {
7280 /* First flush out any partial line written with print. */
7281 message_log_maybe_newline ();
7282 if (m)
7283 message_dolog (m, nbytes, 1, multibyte);
7284 message2_nolog (m, nbytes, multibyte);
7285 }
7286
7287
7288 /* The non-logging counterpart of message2. */
7289
7290 void
7291 message2_nolog (m, nbytes, multibyte)
7292 const char *m;
7293 int nbytes, multibyte;
7294 {
7295 struct frame *sf = SELECTED_FRAME ();
7296 message_enable_multibyte = multibyte;
7297
7298 if (noninteractive)
7299 {
7300 if (noninteractive_need_newline)
7301 putc ('\n', stderr);
7302 noninteractive_need_newline = 0;
7303 if (m)
7304 fwrite (m, nbytes, 1, stderr);
7305 if (cursor_in_echo_area == 0)
7306 fprintf (stderr, "\n");
7307 fflush (stderr);
7308 }
7309 /* A null message buffer means that the frame hasn't really been
7310 initialized yet. Error messages get reported properly by
7311 cmd_error, so this must be just an informative message; toss it. */
7312 else if (INTERACTIVE
7313 && sf->glyphs_initialized_p
7314 && FRAME_MESSAGE_BUF (sf))
7315 {
7316 Lisp_Object mini_window;
7317 struct frame *f;
7318
7319 /* Get the frame containing the mini-buffer
7320 that the selected frame is using. */
7321 mini_window = FRAME_MINIBUF_WINDOW (sf);
7322 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7323
7324 FRAME_SAMPLE_VISIBILITY (f);
7325 if (FRAME_VISIBLE_P (sf)
7326 && ! FRAME_VISIBLE_P (f))
7327 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
7328
7329 if (m)
7330 {
7331 set_message (m, Qnil, nbytes, multibyte);
7332 if (minibuffer_auto_raise)
7333 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7334 }
7335 else
7336 clear_message (1, 1);
7337
7338 do_pending_window_change (0);
7339 echo_area_display (1);
7340 do_pending_window_change (0);
7341 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
7342 (*frame_up_to_date_hook) (f);
7343 }
7344 }
7345
7346
7347 /* Display an echo area message M with a specified length of NBYTES
7348 bytes. The string may include null characters. If M is not a
7349 string, clear out any existing message, and let the mini-buffer
7350 text show through.
7351
7352 This function cancels echoing. */
7353
7354 void
7355 message3 (m, nbytes, multibyte)
7356 Lisp_Object m;
7357 int nbytes;
7358 int multibyte;
7359 {
7360 struct gcpro gcpro1;
7361
7362 GCPRO1 (m);
7363 clear_message (1,1);
7364 cancel_echoing ();
7365
7366 /* First flush out any partial line written with print. */
7367 message_log_maybe_newline ();
7368 if (STRINGP (m))
7369 {
7370 char *buffer;
7371 USE_SAFE_ALLOCA;
7372
7373 SAFE_ALLOCA (buffer, char *, nbytes);
7374 bcopy (SDATA (m), buffer, nbytes);
7375 message_dolog (buffer, nbytes, 1, multibyte);
7376 SAFE_FREE ();
7377 }
7378 message3_nolog (m, nbytes, multibyte);
7379
7380 UNGCPRO;
7381 }
7382
7383
7384 /* The non-logging version of message3.
7385 This does not cancel echoing, because it is used for echoing.
7386 Perhaps we need to make a separate function for echoing
7387 and make this cancel echoing. */
7388
7389 void
7390 message3_nolog (m, nbytes, multibyte)
7391 Lisp_Object m;
7392 int nbytes, multibyte;
7393 {
7394 struct frame *sf = SELECTED_FRAME ();
7395 message_enable_multibyte = multibyte;
7396
7397 if (noninteractive)
7398 {
7399 if (noninteractive_need_newline)
7400 putc ('\n', stderr);
7401 noninteractive_need_newline = 0;
7402 if (STRINGP (m))
7403 fwrite (SDATA (m), nbytes, 1, stderr);
7404 if (cursor_in_echo_area == 0)
7405 fprintf (stderr, "\n");
7406 fflush (stderr);
7407 }
7408 /* A null message buffer means that the frame hasn't really been
7409 initialized yet. Error messages get reported properly by
7410 cmd_error, so this must be just an informative message; toss it. */
7411 else if (INTERACTIVE
7412 && sf->glyphs_initialized_p
7413 && FRAME_MESSAGE_BUF (sf))
7414 {
7415 Lisp_Object mini_window;
7416 Lisp_Object frame;
7417 struct frame *f;
7418
7419 /* Get the frame containing the mini-buffer
7420 that the selected frame is using. */
7421 mini_window = FRAME_MINIBUF_WINDOW (sf);
7422 frame = XWINDOW (mini_window)->frame;
7423 f = XFRAME (frame);
7424
7425 FRAME_SAMPLE_VISIBILITY (f);
7426 if (FRAME_VISIBLE_P (sf)
7427 && !FRAME_VISIBLE_P (f))
7428 Fmake_frame_visible (frame);
7429
7430 if (STRINGP (m) && SCHARS (m) > 0)
7431 {
7432 set_message (NULL, m, nbytes, multibyte);
7433 if (minibuffer_auto_raise)
7434 Fraise_frame (frame);
7435 /* Assume we are not echoing.
7436 (If we are, echo_now will override this.) */
7437 echo_message_buffer = Qnil;
7438 }
7439 else
7440 clear_message (1, 1);
7441
7442 do_pending_window_change (0);
7443 echo_area_display (1);
7444 do_pending_window_change (0);
7445 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
7446 (*frame_up_to_date_hook) (f);
7447 }
7448 }
7449
7450
7451 /* Display a null-terminated echo area message M. If M is 0, clear
7452 out any existing message, and let the mini-buffer text show through.
7453
7454 The buffer M must continue to exist until after the echo area gets
7455 cleared or some other message gets displayed there. Do not pass
7456 text that is stored in a Lisp string. Do not pass text in a buffer
7457 that was alloca'd. */
7458
7459 void
7460 message1 (m)
7461 char *m;
7462 {
7463 message2 (m, (m ? strlen (m) : 0), 0);
7464 }
7465
7466
7467 /* The non-logging counterpart of message1. */
7468
7469 void
7470 message1_nolog (m)
7471 char *m;
7472 {
7473 message2_nolog (m, (m ? strlen (m) : 0), 0);
7474 }
7475
7476 /* Display a message M which contains a single %s
7477 which gets replaced with STRING. */
7478
7479 void
7480 message_with_string (m, string, log)
7481 char *m;
7482 Lisp_Object string;
7483 int log;
7484 {
7485 CHECK_STRING (string);
7486
7487 if (noninteractive)
7488 {
7489 if (m)
7490 {
7491 if (noninteractive_need_newline)
7492 putc ('\n', stderr);
7493 noninteractive_need_newline = 0;
7494 fprintf (stderr, m, SDATA (string));
7495 if (cursor_in_echo_area == 0)
7496 fprintf (stderr, "\n");
7497 fflush (stderr);
7498 }
7499 }
7500 else if (INTERACTIVE)
7501 {
7502 /* The frame whose minibuffer we're going to display the message on.
7503 It may be larger than the selected frame, so we need
7504 to use its buffer, not the selected frame's buffer. */
7505 Lisp_Object mini_window;
7506 struct frame *f, *sf = SELECTED_FRAME ();
7507
7508 /* Get the frame containing the minibuffer
7509 that the selected frame is using. */
7510 mini_window = FRAME_MINIBUF_WINDOW (sf);
7511 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7512
7513 /* A null message buffer means that the frame hasn't really been
7514 initialized yet. Error messages get reported properly by
7515 cmd_error, so this must be just an informative message; toss it. */
7516 if (FRAME_MESSAGE_BUF (f))
7517 {
7518 Lisp_Object args[2], message;
7519 struct gcpro gcpro1, gcpro2;
7520
7521 args[0] = build_string (m);
7522 args[1] = message = string;
7523 GCPRO2 (args[0], message);
7524 gcpro1.nvars = 2;
7525
7526 message = Fformat (2, args);
7527
7528 if (log)
7529 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7530 else
7531 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7532
7533 UNGCPRO;
7534
7535 /* Print should start at the beginning of the message
7536 buffer next time. */
7537 message_buf_print = 0;
7538 }
7539 }
7540 }
7541
7542
7543 /* Dump an informative message to the minibuf. If M is 0, clear out
7544 any existing message, and let the mini-buffer text show through. */
7545
7546 /* VARARGS 1 */
7547 void
7548 message (m, a1, a2, a3)
7549 char *m;
7550 EMACS_INT a1, a2, a3;
7551 {
7552 if (noninteractive)
7553 {
7554 if (m)
7555 {
7556 if (noninteractive_need_newline)
7557 putc ('\n', stderr);
7558 noninteractive_need_newline = 0;
7559 fprintf (stderr, m, a1, a2, a3);
7560 if (cursor_in_echo_area == 0)
7561 fprintf (stderr, "\n");
7562 fflush (stderr);
7563 }
7564 }
7565 else if (INTERACTIVE)
7566 {
7567 /* The frame whose mini-buffer we're going to display the message
7568 on. It may be larger than the selected frame, so we need to
7569 use its buffer, not the selected frame's buffer. */
7570 Lisp_Object mini_window;
7571 struct frame *f, *sf = SELECTED_FRAME ();
7572
7573 /* Get the frame containing the mini-buffer
7574 that the selected frame is using. */
7575 mini_window = FRAME_MINIBUF_WINDOW (sf);
7576 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7577
7578 /* A null message buffer means that the frame hasn't really been
7579 initialized yet. Error messages get reported properly by
7580 cmd_error, so this must be just an informative message; toss
7581 it. */
7582 if (FRAME_MESSAGE_BUF (f))
7583 {
7584 if (m)
7585 {
7586 int len;
7587 #ifdef NO_ARG_ARRAY
7588 char *a[3];
7589 a[0] = (char *) a1;
7590 a[1] = (char *) a2;
7591 a[2] = (char *) a3;
7592
7593 len = doprnt (FRAME_MESSAGE_BUF (f),
7594 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7595 #else
7596 len = doprnt (FRAME_MESSAGE_BUF (f),
7597 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7598 (char **) &a1);
7599 #endif /* NO_ARG_ARRAY */
7600
7601 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7602 }
7603 else
7604 message1 (0);
7605
7606 /* Print should start at the beginning of the message
7607 buffer next time. */
7608 message_buf_print = 0;
7609 }
7610 }
7611 }
7612
7613
7614 /* The non-logging version of message. */
7615
7616 void
7617 message_nolog (m, a1, a2, a3)
7618 char *m;
7619 EMACS_INT a1, a2, a3;
7620 {
7621 Lisp_Object old_log_max;
7622 old_log_max = Vmessage_log_max;
7623 Vmessage_log_max = Qnil;
7624 message (m, a1, a2, a3);
7625 Vmessage_log_max = old_log_max;
7626 }
7627
7628
7629 /* Display the current message in the current mini-buffer. This is
7630 only called from error handlers in process.c, and is not time
7631 critical. */
7632
7633 void
7634 update_echo_area ()
7635 {
7636 if (!NILP (echo_area_buffer[0]))
7637 {
7638 Lisp_Object string;
7639 string = Fcurrent_message ();
7640 message3 (string, SBYTES (string),
7641 !NILP (current_buffer->enable_multibyte_characters));
7642 }
7643 }
7644
7645
7646 /* Make sure echo area buffers in `echo_buffers' are live.
7647 If they aren't, make new ones. */
7648
7649 static void
7650 ensure_echo_area_buffers ()
7651 {
7652 int i;
7653
7654 for (i = 0; i < 2; ++i)
7655 if (!BUFFERP (echo_buffer[i])
7656 || NILP (XBUFFER (echo_buffer[i])->name))
7657 {
7658 char name[30];
7659 Lisp_Object old_buffer;
7660 int j;
7661
7662 old_buffer = echo_buffer[i];
7663 sprintf (name, " *Echo Area %d*", i);
7664 echo_buffer[i] = Fget_buffer_create (build_string (name));
7665 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7666
7667 for (j = 0; j < 2; ++j)
7668 if (EQ (old_buffer, echo_area_buffer[j]))
7669 echo_area_buffer[j] = echo_buffer[i];
7670 }
7671 }
7672
7673
7674 /* Call FN with args A1..A4 with either the current or last displayed
7675 echo_area_buffer as current buffer.
7676
7677 WHICH zero means use the current message buffer
7678 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7679 from echo_buffer[] and clear it.
7680
7681 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7682 suitable buffer from echo_buffer[] and clear it.
7683
7684 Value is what FN returns. */
7685
7686 static int
7687 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7688 struct window *w;
7689 int which;
7690 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7691 EMACS_INT a1;
7692 Lisp_Object a2;
7693 EMACS_INT a3, a4;
7694 {
7695 Lisp_Object buffer;
7696 int this_one, the_other, clear_buffer_p, rc;
7697 int count = SPECPDL_INDEX ();
7698
7699 /* If buffers aren't live, make new ones. */
7700 ensure_echo_area_buffers ();
7701
7702 clear_buffer_p = 0;
7703
7704 if (which == 0)
7705 this_one = 0, the_other = 1;
7706 else if (which > 0)
7707 this_one = 1, the_other = 0;
7708
7709 /* Choose a suitable buffer from echo_buffer[] is we don't
7710 have one. */
7711 if (NILP (echo_area_buffer[this_one]))
7712 {
7713 echo_area_buffer[this_one]
7714 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7715 ? echo_buffer[the_other]
7716 : echo_buffer[this_one]);
7717 clear_buffer_p = 1;
7718 }
7719
7720 buffer = echo_area_buffer[this_one];
7721
7722 /* Don't get confused by reusing the buffer used for echoing
7723 for a different purpose. */
7724 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7725 cancel_echoing ();
7726
7727 record_unwind_protect (unwind_with_echo_area_buffer,
7728 with_echo_area_buffer_unwind_data (w));
7729
7730 /* Make the echo area buffer current. Note that for display
7731 purposes, it is not necessary that the displayed window's buffer
7732 == current_buffer, except for text property lookup. So, let's
7733 only set that buffer temporarily here without doing a full
7734 Fset_window_buffer. We must also change w->pointm, though,
7735 because otherwise an assertions in unshow_buffer fails, and Emacs
7736 aborts. */
7737 set_buffer_internal_1 (XBUFFER (buffer));
7738 if (w)
7739 {
7740 w->buffer = buffer;
7741 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7742 }
7743
7744 current_buffer->undo_list = Qt;
7745 current_buffer->read_only = Qnil;
7746 specbind (Qinhibit_read_only, Qt);
7747 specbind (Qinhibit_modification_hooks, Qt);
7748
7749 if (clear_buffer_p && Z > BEG)
7750 del_range (BEG, Z);
7751
7752 xassert (BEGV >= BEG);
7753 xassert (ZV <= Z && ZV >= BEGV);
7754
7755 rc = fn (a1, a2, a3, a4);
7756
7757 xassert (BEGV >= BEG);
7758 xassert (ZV <= Z && ZV >= BEGV);
7759
7760 unbind_to (count, Qnil);
7761 return rc;
7762 }
7763
7764
7765 /* Save state that should be preserved around the call to the function
7766 FN called in with_echo_area_buffer. */
7767
7768 static Lisp_Object
7769 with_echo_area_buffer_unwind_data (w)
7770 struct window *w;
7771 {
7772 int i = 0;
7773 Lisp_Object vector;
7774
7775 /* Reduce consing by keeping one vector in
7776 Vwith_echo_area_save_vector. */
7777 vector = Vwith_echo_area_save_vector;
7778 Vwith_echo_area_save_vector = Qnil;
7779
7780 if (NILP (vector))
7781 vector = Fmake_vector (make_number (7), Qnil);
7782
7783 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7784 AREF (vector, i) = Vdeactivate_mark, ++i;
7785 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7786
7787 if (w)
7788 {
7789 XSETWINDOW (AREF (vector, i), w); ++i;
7790 AREF (vector, i) = w->buffer; ++i;
7791 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7792 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7793 }
7794 else
7795 {
7796 int end = i + 4;
7797 for (; i < end; ++i)
7798 AREF (vector, i) = Qnil;
7799 }
7800
7801 xassert (i == ASIZE (vector));
7802 return vector;
7803 }
7804
7805
7806 /* Restore global state from VECTOR which was created by
7807 with_echo_area_buffer_unwind_data. */
7808
7809 static Lisp_Object
7810 unwind_with_echo_area_buffer (vector)
7811 Lisp_Object vector;
7812 {
7813 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7814 Vdeactivate_mark = AREF (vector, 1);
7815 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7816
7817 if (WINDOWP (AREF (vector, 3)))
7818 {
7819 struct window *w;
7820 Lisp_Object buffer, charpos, bytepos;
7821
7822 w = XWINDOW (AREF (vector, 3));
7823 buffer = AREF (vector, 4);
7824 charpos = AREF (vector, 5);
7825 bytepos = AREF (vector, 6);
7826
7827 w->buffer = buffer;
7828 set_marker_both (w->pointm, buffer,
7829 XFASTINT (charpos), XFASTINT (bytepos));
7830 }
7831
7832 Vwith_echo_area_save_vector = vector;
7833 return Qnil;
7834 }
7835
7836
7837 /* Set up the echo area for use by print functions. MULTIBYTE_P
7838 non-zero means we will print multibyte. */
7839
7840 void
7841 setup_echo_area_for_printing (multibyte_p)
7842 int multibyte_p;
7843 {
7844 /* If we can't find an echo area any more, exit. */
7845 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7846 Fkill_emacs (Qnil);
7847
7848 ensure_echo_area_buffers ();
7849
7850 if (!message_buf_print)
7851 {
7852 /* A message has been output since the last time we printed.
7853 Choose a fresh echo area buffer. */
7854 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7855 echo_area_buffer[0] = echo_buffer[1];
7856 else
7857 echo_area_buffer[0] = echo_buffer[0];
7858
7859 /* Switch to that buffer and clear it. */
7860 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7861 current_buffer->truncate_lines = Qnil;
7862
7863 if (Z > BEG)
7864 {
7865 int count = SPECPDL_INDEX ();
7866 specbind (Qinhibit_read_only, Qt);
7867 /* Note that undo recording is always disabled. */
7868 del_range (BEG, Z);
7869 unbind_to (count, Qnil);
7870 }
7871 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7872
7873 /* Set up the buffer for the multibyteness we need. */
7874 if (multibyte_p
7875 != !NILP (current_buffer->enable_multibyte_characters))
7876 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7877
7878 /* Raise the frame containing the echo area. */
7879 if (minibuffer_auto_raise)
7880 {
7881 struct frame *sf = SELECTED_FRAME ();
7882 Lisp_Object mini_window;
7883 mini_window = FRAME_MINIBUF_WINDOW (sf);
7884 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7885 }
7886
7887 message_log_maybe_newline ();
7888 message_buf_print = 1;
7889 }
7890 else
7891 {
7892 if (NILP (echo_area_buffer[0]))
7893 {
7894 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7895 echo_area_buffer[0] = echo_buffer[1];
7896 else
7897 echo_area_buffer[0] = echo_buffer[0];
7898 }
7899
7900 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7901 {
7902 /* Someone switched buffers between print requests. */
7903 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7904 current_buffer->truncate_lines = Qnil;
7905 }
7906 }
7907 }
7908
7909
7910 /* Display an echo area message in window W. Value is non-zero if W's
7911 height is changed. If display_last_displayed_message_p is
7912 non-zero, display the message that was last displayed, otherwise
7913 display the current message. */
7914
7915 static int
7916 display_echo_area (w)
7917 struct window *w;
7918 {
7919 int i, no_message_p, window_height_changed_p, count;
7920
7921 /* Temporarily disable garbage collections while displaying the echo
7922 area. This is done because a GC can print a message itself.
7923 That message would modify the echo area buffer's contents while a
7924 redisplay of the buffer is going on, and seriously confuse
7925 redisplay. */
7926 count = inhibit_garbage_collection ();
7927
7928 /* If there is no message, we must call display_echo_area_1
7929 nevertheless because it resizes the window. But we will have to
7930 reset the echo_area_buffer in question to nil at the end because
7931 with_echo_area_buffer will sets it to an empty buffer. */
7932 i = display_last_displayed_message_p ? 1 : 0;
7933 no_message_p = NILP (echo_area_buffer[i]);
7934
7935 window_height_changed_p
7936 = with_echo_area_buffer (w, display_last_displayed_message_p,
7937 display_echo_area_1,
7938 (EMACS_INT) w, Qnil, 0, 0);
7939
7940 if (no_message_p)
7941 echo_area_buffer[i] = Qnil;
7942
7943 unbind_to (count, Qnil);
7944 return window_height_changed_p;
7945 }
7946
7947
7948 /* Helper for display_echo_area. Display the current buffer which
7949 contains the current echo area message in window W, a mini-window,
7950 a pointer to which is passed in A1. A2..A4 are currently not used.
7951 Change the height of W so that all of the message is displayed.
7952 Value is non-zero if height of W was changed. */
7953
7954 static int
7955 display_echo_area_1 (a1, a2, a3, a4)
7956 EMACS_INT a1;
7957 Lisp_Object a2;
7958 EMACS_INT a3, a4;
7959 {
7960 struct window *w = (struct window *) a1;
7961 Lisp_Object window;
7962 struct text_pos start;
7963 int window_height_changed_p = 0;
7964
7965 /* Do this before displaying, so that we have a large enough glyph
7966 matrix for the display. If we can't get enough space for the
7967 whole text, display the last N lines. That works by setting w->start. */
7968 window_height_changed_p = resize_mini_window (w, 0);
7969
7970 /* Use the starting position chosen by resize_mini_window. */
7971 SET_TEXT_POS_FROM_MARKER (start, w->start);
7972
7973 /* Display. */
7974 clear_glyph_matrix (w->desired_matrix);
7975 XSETWINDOW (window, w);
7976 try_window (window, start, 0);
7977
7978 return window_height_changed_p;
7979 }
7980
7981
7982 /* Resize the echo area window to exactly the size needed for the
7983 currently displayed message, if there is one. If a mini-buffer
7984 is active, don't shrink it. */
7985
7986 void
7987 resize_echo_area_exactly ()
7988 {
7989 if (BUFFERP (echo_area_buffer[0])
7990 && WINDOWP (echo_area_window))
7991 {
7992 struct window *w = XWINDOW (echo_area_window);
7993 int resized_p;
7994 Lisp_Object resize_exactly;
7995
7996 if (minibuf_level == 0)
7997 resize_exactly = Qt;
7998 else
7999 resize_exactly = Qnil;
8000
8001 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8002 (EMACS_INT) w, resize_exactly, 0, 0);
8003 if (resized_p)
8004 {
8005 ++windows_or_buffers_changed;
8006 ++update_mode_lines;
8007 redisplay_internal (0);
8008 }
8009 }
8010 }
8011
8012
8013 /* Callback function for with_echo_area_buffer, when used from
8014 resize_echo_area_exactly. A1 contains a pointer to the window to
8015 resize, EXACTLY non-nil means resize the mini-window exactly to the
8016 size of the text displayed. A3 and A4 are not used. Value is what
8017 resize_mini_window returns. */
8018
8019 static int
8020 resize_mini_window_1 (a1, exactly, a3, a4)
8021 EMACS_INT a1;
8022 Lisp_Object exactly;
8023 EMACS_INT a3, a4;
8024 {
8025 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8026 }
8027
8028
8029 /* Resize mini-window W to fit the size of its contents. EXACT:P
8030 means size the window exactly to the size needed. Otherwise, it's
8031 only enlarged until W's buffer is empty.
8032
8033 Set W->start to the right place to begin display. If the whole
8034 contents fit, start at the beginning. Otherwise, start so as
8035 to make the end of the contents appear. This is particularly
8036 important for y-or-n-p, but seems desirable generally.
8037
8038 Value is non-zero if the window height has been changed. */
8039
8040 int
8041 resize_mini_window (w, exact_p)
8042 struct window *w;
8043 int exact_p;
8044 {
8045 struct frame *f = XFRAME (w->frame);
8046 int window_height_changed_p = 0;
8047
8048 xassert (MINI_WINDOW_P (w));
8049
8050 /* By default, start display at the beginning. */
8051 set_marker_both (w->start, w->buffer,
8052 BUF_BEGV (XBUFFER (w->buffer)),
8053 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8054
8055 /* Don't resize windows while redisplaying a window; it would
8056 confuse redisplay functions when the size of the window they are
8057 displaying changes from under them. Such a resizing can happen,
8058 for instance, when which-func prints a long message while
8059 we are running fontification-functions. We're running these
8060 functions with safe_call which binds inhibit-redisplay to t. */
8061 if (!NILP (Vinhibit_redisplay))
8062 return 0;
8063
8064 /* Nil means don't try to resize. */
8065 if (NILP (Vresize_mini_windows)
8066 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8067 return 0;
8068
8069 if (!FRAME_MINIBUF_ONLY_P (f))
8070 {
8071 struct it it;
8072 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8073 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8074 int height, max_height;
8075 int unit = FRAME_LINE_HEIGHT (f);
8076 struct text_pos start;
8077 struct buffer *old_current_buffer = NULL;
8078
8079 if (current_buffer != XBUFFER (w->buffer))
8080 {
8081 old_current_buffer = current_buffer;
8082 set_buffer_internal (XBUFFER (w->buffer));
8083 }
8084
8085 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8086
8087 /* Compute the max. number of lines specified by the user. */
8088 if (FLOATP (Vmax_mini_window_height))
8089 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8090 else if (INTEGERP (Vmax_mini_window_height))
8091 max_height = XINT (Vmax_mini_window_height);
8092 else
8093 max_height = total_height / 4;
8094
8095 /* Correct that max. height if it's bogus. */
8096 max_height = max (1, max_height);
8097 max_height = min (total_height, max_height);
8098
8099 /* Find out the height of the text in the window. */
8100 if (it.truncate_lines_p)
8101 height = 1;
8102 else
8103 {
8104 last_height = 0;
8105 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
8106 if (it.max_ascent == 0 && it.max_descent == 0)
8107 height = it.current_y + last_height;
8108 else
8109 height = it.current_y + it.max_ascent + it.max_descent;
8110 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
8111 height = (height + unit - 1) / unit;
8112 }
8113
8114 /* Compute a suitable window start. */
8115 if (height > max_height)
8116 {
8117 height = max_height;
8118 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
8119 move_it_vertically_backward (&it, (height - 1) * unit);
8120 start = it.current.pos;
8121 }
8122 else
8123 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
8124 SET_MARKER_FROM_TEXT_POS (w->start, start);
8125
8126 if (EQ (Vresize_mini_windows, Qgrow_only))
8127 {
8128 /* Let it grow only, until we display an empty message, in which
8129 case the window shrinks again. */
8130 if (height > WINDOW_TOTAL_LINES (w))
8131 {
8132 int old_height = WINDOW_TOTAL_LINES (w);
8133 freeze_window_starts (f, 1);
8134 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8135 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8136 }
8137 else if (height < WINDOW_TOTAL_LINES (w)
8138 && (exact_p || BEGV == ZV))
8139 {
8140 int old_height = WINDOW_TOTAL_LINES (w);
8141 freeze_window_starts (f, 0);
8142 shrink_mini_window (w);
8143 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8144 }
8145 }
8146 else
8147 {
8148 /* Always resize to exact size needed. */
8149 if (height > WINDOW_TOTAL_LINES (w))
8150 {
8151 int old_height = WINDOW_TOTAL_LINES (w);
8152 freeze_window_starts (f, 1);
8153 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8154 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8155 }
8156 else if (height < WINDOW_TOTAL_LINES (w))
8157 {
8158 int old_height = WINDOW_TOTAL_LINES (w);
8159 freeze_window_starts (f, 0);
8160 shrink_mini_window (w);
8161
8162 if (height)
8163 {
8164 freeze_window_starts (f, 1);
8165 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8166 }
8167
8168 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8169 }
8170 }
8171
8172 if (old_current_buffer)
8173 set_buffer_internal (old_current_buffer);
8174 }
8175
8176 return window_height_changed_p;
8177 }
8178
8179
8180 /* Value is the current message, a string, or nil if there is no
8181 current message. */
8182
8183 Lisp_Object
8184 current_message ()
8185 {
8186 Lisp_Object msg;
8187
8188 if (NILP (echo_area_buffer[0]))
8189 msg = Qnil;
8190 else
8191 {
8192 with_echo_area_buffer (0, 0, current_message_1,
8193 (EMACS_INT) &msg, Qnil, 0, 0);
8194 if (NILP (msg))
8195 echo_area_buffer[0] = Qnil;
8196 }
8197
8198 return msg;
8199 }
8200
8201
8202 static int
8203 current_message_1 (a1, a2, a3, a4)
8204 EMACS_INT a1;
8205 Lisp_Object a2;
8206 EMACS_INT a3, a4;
8207 {
8208 Lisp_Object *msg = (Lisp_Object *) a1;
8209
8210 if (Z > BEG)
8211 *msg = make_buffer_string (BEG, Z, 1);
8212 else
8213 *msg = Qnil;
8214 return 0;
8215 }
8216
8217
8218 /* Push the current message on Vmessage_stack for later restauration
8219 by restore_message. Value is non-zero if the current message isn't
8220 empty. This is a relatively infrequent operation, so it's not
8221 worth optimizing. */
8222
8223 int
8224 push_message ()
8225 {
8226 Lisp_Object msg;
8227 msg = current_message ();
8228 Vmessage_stack = Fcons (msg, Vmessage_stack);
8229 return STRINGP (msg);
8230 }
8231
8232
8233 /* Restore message display from the top of Vmessage_stack. */
8234
8235 void
8236 restore_message ()
8237 {
8238 Lisp_Object msg;
8239
8240 xassert (CONSP (Vmessage_stack));
8241 msg = XCAR (Vmessage_stack);
8242 if (STRINGP (msg))
8243 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8244 else
8245 message3_nolog (msg, 0, 0);
8246 }
8247
8248
8249 /* Handler for record_unwind_protect calling pop_message. */
8250
8251 Lisp_Object
8252 pop_message_unwind (dummy)
8253 Lisp_Object dummy;
8254 {
8255 pop_message ();
8256 return Qnil;
8257 }
8258
8259 /* Pop the top-most entry off Vmessage_stack. */
8260
8261 void
8262 pop_message ()
8263 {
8264 xassert (CONSP (Vmessage_stack));
8265 Vmessage_stack = XCDR (Vmessage_stack);
8266 }
8267
8268
8269 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
8270 exits. If the stack is not empty, we have a missing pop_message
8271 somewhere. */
8272
8273 void
8274 check_message_stack ()
8275 {
8276 if (!NILP (Vmessage_stack))
8277 abort ();
8278 }
8279
8280
8281 /* Truncate to NCHARS what will be displayed in the echo area the next
8282 time we display it---but don't redisplay it now. */
8283
8284 void
8285 truncate_echo_area (nchars)
8286 int nchars;
8287 {
8288 if (nchars == 0)
8289 echo_area_buffer[0] = Qnil;
8290 /* A null message buffer means that the frame hasn't really been
8291 initialized yet. Error messages get reported properly by
8292 cmd_error, so this must be just an informative message; toss it. */
8293 else if (!noninteractive
8294 && INTERACTIVE
8295 && !NILP (echo_area_buffer[0]))
8296 {
8297 struct frame *sf = SELECTED_FRAME ();
8298 if (FRAME_MESSAGE_BUF (sf))
8299 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
8300 }
8301 }
8302
8303
8304 /* Helper function for truncate_echo_area. Truncate the current
8305 message to at most NCHARS characters. */
8306
8307 static int
8308 truncate_message_1 (nchars, a2, a3, a4)
8309 EMACS_INT nchars;
8310 Lisp_Object a2;
8311 EMACS_INT a3, a4;
8312 {
8313 if (BEG + nchars < Z)
8314 del_range (BEG + nchars, Z);
8315 if (Z == BEG)
8316 echo_area_buffer[0] = Qnil;
8317 return 0;
8318 }
8319
8320
8321 /* Set the current message to a substring of S or STRING.
8322
8323 If STRING is a Lisp string, set the message to the first NBYTES
8324 bytes from STRING. NBYTES zero means use the whole string. If
8325 STRING is multibyte, the message will be displayed multibyte.
8326
8327 If S is not null, set the message to the first LEN bytes of S. LEN
8328 zero means use the whole string. MULTIBYTE_P non-zero means S is
8329 multibyte. Display the message multibyte in that case.
8330
8331 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
8332 to t before calling set_message_1 (which calls insert).
8333 */
8334
8335 void
8336 set_message (s, string, nbytes, multibyte_p)
8337 const char *s;
8338 Lisp_Object string;
8339 int nbytes, multibyte_p;
8340 {
8341 message_enable_multibyte
8342 = ((s && multibyte_p)
8343 || (STRINGP (string) && STRING_MULTIBYTE (string)));
8344
8345 with_echo_area_buffer (0, 0, set_message_1,
8346 (EMACS_INT) s, string, nbytes, multibyte_p);
8347 message_buf_print = 0;
8348 help_echo_showing_p = 0;
8349 }
8350
8351
8352 /* Helper function for set_message. Arguments have the same meaning
8353 as there, with A1 corresponding to S and A2 corresponding to STRING
8354 This function is called with the echo area buffer being
8355 current. */
8356
8357 static int
8358 set_message_1 (a1, a2, nbytes, multibyte_p)
8359 EMACS_INT a1;
8360 Lisp_Object a2;
8361 EMACS_INT nbytes, multibyte_p;
8362 {
8363 const char *s = (const char *) a1;
8364 Lisp_Object string = a2;
8365
8366 /* Change multibyteness of the echo buffer appropriately. */
8367 if (message_enable_multibyte
8368 != !NILP (current_buffer->enable_multibyte_characters))
8369 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
8370
8371 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
8372
8373 /* Insert new message at BEG. */
8374 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8375 Ferase_buffer ();
8376
8377 if (STRINGP (string))
8378 {
8379 int nchars;
8380
8381 if (nbytes == 0)
8382 nbytes = SBYTES (string);
8383 nchars = string_byte_to_char (string, nbytes);
8384
8385 /* This function takes care of single/multibyte conversion. We
8386 just have to ensure that the echo area buffer has the right
8387 setting of enable_multibyte_characters. */
8388 insert_from_string (string, 0, 0, nchars, nbytes, 1);
8389 }
8390 else if (s)
8391 {
8392 if (nbytes == 0)
8393 nbytes = strlen (s);
8394
8395 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
8396 {
8397 /* Convert from multi-byte to single-byte. */
8398 int i, c, n;
8399 unsigned char work[1];
8400
8401 /* Convert a multibyte string to single-byte. */
8402 for (i = 0; i < nbytes; i += n)
8403 {
8404 c = string_char_and_length (s + i, nbytes - i, &n);
8405 work[0] = (SINGLE_BYTE_CHAR_P (c)
8406 ? c
8407 : multibyte_char_to_unibyte (c, Qnil));
8408 insert_1_both (work, 1, 1, 1, 0, 0);
8409 }
8410 }
8411 else if (!multibyte_p
8412 && !NILP (current_buffer->enable_multibyte_characters))
8413 {
8414 /* Convert from single-byte to multi-byte. */
8415 int i, c, n;
8416 const unsigned char *msg = (const unsigned char *) s;
8417 unsigned char str[MAX_MULTIBYTE_LENGTH];
8418
8419 /* Convert a single-byte string to multibyte. */
8420 for (i = 0; i < nbytes; i++)
8421 {
8422 c = unibyte_char_to_multibyte (msg[i]);
8423 n = CHAR_STRING (c, str);
8424 insert_1_both (str, 1, n, 1, 0, 0);
8425 }
8426 }
8427 else
8428 insert_1 (s, nbytes, 1, 0, 0);
8429 }
8430
8431 return 0;
8432 }
8433
8434
8435 /* Clear messages. CURRENT_P non-zero means clear the current
8436 message. LAST_DISPLAYED_P non-zero means clear the message
8437 last displayed. */
8438
8439 void
8440 clear_message (current_p, last_displayed_p)
8441 int current_p, last_displayed_p;
8442 {
8443 if (current_p)
8444 {
8445 echo_area_buffer[0] = Qnil;
8446 message_cleared_p = 1;
8447 }
8448
8449 if (last_displayed_p)
8450 echo_area_buffer[1] = Qnil;
8451
8452 message_buf_print = 0;
8453 }
8454
8455 /* Clear garbaged frames.
8456
8457 This function is used where the old redisplay called
8458 redraw_garbaged_frames which in turn called redraw_frame which in
8459 turn called clear_frame. The call to clear_frame was a source of
8460 flickering. I believe a clear_frame is not necessary. It should
8461 suffice in the new redisplay to invalidate all current matrices,
8462 and ensure a complete redisplay of all windows. */
8463
8464 static void
8465 clear_garbaged_frames ()
8466 {
8467 if (frame_garbaged)
8468 {
8469 Lisp_Object tail, frame;
8470 int changed_count = 0;
8471
8472 FOR_EACH_FRAME (tail, frame)
8473 {
8474 struct frame *f = XFRAME (frame);
8475
8476 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8477 {
8478 if (f->resized_p)
8479 {
8480 Fredraw_frame (frame);
8481 f->force_flush_display_p = 1;
8482 }
8483 clear_current_matrices (f);
8484 changed_count++;
8485 f->garbaged = 0;
8486 f->resized_p = 0;
8487 }
8488 }
8489
8490 frame_garbaged = 0;
8491 if (changed_count)
8492 ++windows_or_buffers_changed;
8493 }
8494 }
8495
8496
8497 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8498 is non-zero update selected_frame. Value is non-zero if the
8499 mini-windows height has been changed. */
8500
8501 static int
8502 echo_area_display (update_frame_p)
8503 int update_frame_p;
8504 {
8505 Lisp_Object mini_window;
8506 struct window *w;
8507 struct frame *f;
8508 int window_height_changed_p = 0;
8509 struct frame *sf = SELECTED_FRAME ();
8510
8511 mini_window = FRAME_MINIBUF_WINDOW (sf);
8512 w = XWINDOW (mini_window);
8513 f = XFRAME (WINDOW_FRAME (w));
8514
8515 /* Don't display if frame is invisible or not yet initialized. */
8516 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8517 return 0;
8518
8519 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8520 #ifndef MAC_OS8
8521 #ifdef HAVE_WINDOW_SYSTEM
8522 /* When Emacs starts, selected_frame may be a visible terminal
8523 frame, even if we run under a window system. If we let this
8524 through, a message would be displayed on the terminal. */
8525 if (EQ (selected_frame, Vterminal_frame)
8526 && !NILP (Vwindow_system))
8527 return 0;
8528 #endif /* HAVE_WINDOW_SYSTEM */
8529 #endif
8530
8531 /* Redraw garbaged frames. */
8532 if (frame_garbaged)
8533 clear_garbaged_frames ();
8534
8535 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8536 {
8537 echo_area_window = mini_window;
8538 window_height_changed_p = display_echo_area (w);
8539 w->must_be_updated_p = 1;
8540
8541 /* Update the display, unless called from redisplay_internal.
8542 Also don't update the screen during redisplay itself. The
8543 update will happen at the end of redisplay, and an update
8544 here could cause confusion. */
8545 if (update_frame_p && !redisplaying_p)
8546 {
8547 int n = 0;
8548
8549 /* If the display update has been interrupted by pending
8550 input, update mode lines in the frame. Due to the
8551 pending input, it might have been that redisplay hasn't
8552 been called, so that mode lines above the echo area are
8553 garbaged. This looks odd, so we prevent it here. */
8554 if (!display_completed)
8555 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8556
8557 if (window_height_changed_p
8558 /* Don't do this if Emacs is shutting down. Redisplay
8559 needs to run hooks. */
8560 && !NILP (Vrun_hooks))
8561 {
8562 /* Must update other windows. Likewise as in other
8563 cases, don't let this update be interrupted by
8564 pending input. */
8565 int count = SPECPDL_INDEX ();
8566 specbind (Qredisplay_dont_pause, Qt);
8567 windows_or_buffers_changed = 1;
8568 redisplay_internal (0);
8569 unbind_to (count, Qnil);
8570 }
8571 else if (FRAME_WINDOW_P (f) && n == 0)
8572 {
8573 /* Window configuration is the same as before.
8574 Can do with a display update of the echo area,
8575 unless we displayed some mode lines. */
8576 update_single_window (w, 1);
8577 rif->flush_display (f);
8578 }
8579 else
8580 update_frame (f, 1, 1);
8581
8582 /* If cursor is in the echo area, make sure that the next
8583 redisplay displays the minibuffer, so that the cursor will
8584 be replaced with what the minibuffer wants. */
8585 if (cursor_in_echo_area)
8586 ++windows_or_buffers_changed;
8587 }
8588 }
8589 else if (!EQ (mini_window, selected_window))
8590 windows_or_buffers_changed++;
8591
8592 /* The current message is now also the last one displayed. */
8593 echo_area_buffer[1] = echo_area_buffer[0];
8594
8595 /* Prevent redisplay optimization in redisplay_internal by resetting
8596 this_line_start_pos. This is done because the mini-buffer now
8597 displays the message instead of its buffer text. */
8598 if (EQ (mini_window, selected_window))
8599 CHARPOS (this_line_start_pos) = 0;
8600
8601 return window_height_changed_p;
8602 }
8603
8604
8605 \f
8606 /***********************************************************************
8607 Mode Lines and Frame Titles
8608 ***********************************************************************/
8609
8610 /* A buffer for constructing non-propertized mode-line strings and
8611 frame titles in it; allocated from the heap in init_xdisp and
8612 resized as needed in store_mode_line_noprop_char. */
8613
8614 static char *mode_line_noprop_buf;
8615
8616 /* The buffer's end, and a current output position in it. */
8617
8618 static char *mode_line_noprop_buf_end;
8619 static char *mode_line_noprop_ptr;
8620
8621 #define MODE_LINE_NOPROP_LEN(start) \
8622 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
8623
8624 static enum {
8625 MODE_LINE_DISPLAY = 0,
8626 MODE_LINE_TITLE,
8627 MODE_LINE_NOPROP,
8628 MODE_LINE_STRING
8629 } mode_line_target;
8630
8631 /* Alist that caches the results of :propertize.
8632 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
8633 static Lisp_Object mode_line_proptrans_alist;
8634
8635 /* List of strings making up the mode-line. */
8636 static Lisp_Object mode_line_string_list;
8637
8638 /* Base face property when building propertized mode line string. */
8639 static Lisp_Object mode_line_string_face;
8640 static Lisp_Object mode_line_string_face_prop;
8641
8642
8643 /* Unwind data for mode line strings */
8644
8645 static Lisp_Object Vmode_line_unwind_vector;
8646
8647 static Lisp_Object
8648 format_mode_line_unwind_data (obuf, save_proptrans)
8649 struct buffer *obuf;
8650 {
8651 Lisp_Object vector;
8652
8653 /* Reduce consing by keeping one vector in
8654 Vwith_echo_area_save_vector. */
8655 vector = Vmode_line_unwind_vector;
8656 Vmode_line_unwind_vector = Qnil;
8657
8658 if (NILP (vector))
8659 vector = Fmake_vector (make_number (7), Qnil);
8660
8661 AREF (vector, 0) = make_number (mode_line_target);
8662 AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
8663 AREF (vector, 2) = mode_line_string_list;
8664 AREF (vector, 3) = (save_proptrans ? mode_line_proptrans_alist : Qt);
8665 AREF (vector, 4) = mode_line_string_face;
8666 AREF (vector, 5) = mode_line_string_face_prop;
8667
8668 if (obuf)
8669 XSETBUFFER (AREF (vector, 6), obuf);
8670 else
8671 AREF (vector, 6) = Qnil;
8672
8673 return vector;
8674 }
8675
8676 static Lisp_Object
8677 unwind_format_mode_line (vector)
8678 Lisp_Object vector;
8679 {
8680 mode_line_target = XINT (AREF (vector, 0));
8681 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
8682 mode_line_string_list = AREF (vector, 2);
8683 if (! EQ (AREF (vector, 3), Qt))
8684 mode_line_proptrans_alist = AREF (vector, 3);
8685 mode_line_string_face = AREF (vector, 4);
8686 mode_line_string_face_prop = AREF (vector, 5);
8687
8688 if (!NILP (AREF (vector, 6)))
8689 {
8690 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
8691 AREF (vector, 6) = Qnil;
8692 }
8693
8694 Vmode_line_unwind_vector = vector;
8695 return Qnil;
8696 }
8697
8698
8699 /* Store a single character C for the frame title in mode_line_noprop_buf.
8700 Re-allocate mode_line_noprop_buf if necessary. */
8701
8702 static void
8703 #ifdef PROTOTYPES
8704 store_mode_line_noprop_char (char c)
8705 #else
8706 store_mode_line_noprop_char (c)
8707 char c;
8708 #endif
8709 {
8710 /* If output position has reached the end of the allocated buffer,
8711 double the buffer's size. */
8712 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
8713 {
8714 int len = MODE_LINE_NOPROP_LEN (0);
8715 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
8716 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
8717 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
8718 mode_line_noprop_ptr = mode_line_noprop_buf + len;
8719 }
8720
8721 *mode_line_noprop_ptr++ = c;
8722 }
8723
8724
8725 /* Store part of a frame title in mode_line_noprop_buf, beginning at
8726 mode_line_noprop_ptr. STR is the string to store. Do not copy
8727 characters that yield more columns than PRECISION; PRECISION <= 0
8728 means copy the whole string. Pad with spaces until FIELD_WIDTH
8729 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8730 pad. Called from display_mode_element when it is used to build a
8731 frame title. */
8732
8733 static int
8734 store_mode_line_noprop (str, field_width, precision)
8735 const unsigned char *str;
8736 int field_width, precision;
8737 {
8738 int n = 0;
8739 int dummy, nbytes;
8740
8741 /* Copy at most PRECISION chars from STR. */
8742 nbytes = strlen (str);
8743 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8744 while (nbytes--)
8745 store_mode_line_noprop_char (*str++);
8746
8747 /* Fill up with spaces until FIELD_WIDTH reached. */
8748 while (field_width > 0
8749 && n < field_width)
8750 {
8751 store_mode_line_noprop_char (' ');
8752 ++n;
8753 }
8754
8755 return n;
8756 }
8757
8758 /***********************************************************************
8759 Frame Titles
8760 ***********************************************************************/
8761
8762 #ifdef HAVE_WINDOW_SYSTEM
8763
8764 /* Set the title of FRAME, if it has changed. The title format is
8765 Vicon_title_format if FRAME is iconified, otherwise it is
8766 frame_title_format. */
8767
8768 static void
8769 x_consider_frame_title (frame)
8770 Lisp_Object frame;
8771 {
8772 struct frame *f = XFRAME (frame);
8773
8774 if (FRAME_WINDOW_P (f)
8775 || FRAME_MINIBUF_ONLY_P (f)
8776 || f->explicit_name)
8777 {
8778 /* Do we have more than one visible frame on this X display? */
8779 Lisp_Object tail;
8780 Lisp_Object fmt;
8781 int title_start;
8782 char *title;
8783 int len;
8784 struct it it;
8785 int count = SPECPDL_INDEX ();
8786
8787 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8788 {
8789 Lisp_Object other_frame = XCAR (tail);
8790 struct frame *tf = XFRAME (other_frame);
8791
8792 if (tf != f
8793 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8794 && !FRAME_MINIBUF_ONLY_P (tf)
8795 && !EQ (other_frame, tip_frame)
8796 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8797 break;
8798 }
8799
8800 /* Set global variable indicating that multiple frames exist. */
8801 multiple_frames = CONSP (tail);
8802
8803 /* Switch to the buffer of selected window of the frame. Set up
8804 mode_line_target so that display_mode_element will output into
8805 mode_line_noprop_buf; then display the title. */
8806 record_unwind_protect (unwind_format_mode_line,
8807 format_mode_line_unwind_data (current_buffer, 0));
8808
8809 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8810 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8811
8812 mode_line_target = MODE_LINE_TITLE;
8813 title_start = MODE_LINE_NOPROP_LEN (0);
8814 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8815 NULL, DEFAULT_FACE_ID);
8816 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8817 len = MODE_LINE_NOPROP_LEN (title_start);
8818 title = mode_line_noprop_buf + title_start;
8819 unbind_to (count, Qnil);
8820
8821 /* Set the title only if it's changed. This avoids consing in
8822 the common case where it hasn't. (If it turns out that we've
8823 already wasted too much time by walking through the list with
8824 display_mode_element, then we might need to optimize at a
8825 higher level than this.) */
8826 if (! STRINGP (f->name)
8827 || SBYTES (f->name) != len
8828 || bcmp (title, SDATA (f->name), len) != 0)
8829 x_implicitly_set_name (f, make_string (title, len), Qnil);
8830 }
8831 }
8832
8833 #endif /* not HAVE_WINDOW_SYSTEM */
8834
8835
8836
8837 \f
8838 /***********************************************************************
8839 Menu Bars
8840 ***********************************************************************/
8841
8842
8843 /* Prepare for redisplay by updating menu-bar item lists when
8844 appropriate. This can call eval. */
8845
8846 void
8847 prepare_menu_bars ()
8848 {
8849 int all_windows;
8850 struct gcpro gcpro1, gcpro2;
8851 struct frame *f;
8852 Lisp_Object tooltip_frame;
8853
8854 #ifdef HAVE_WINDOW_SYSTEM
8855 tooltip_frame = tip_frame;
8856 #else
8857 tooltip_frame = Qnil;
8858 #endif
8859
8860 /* Update all frame titles based on their buffer names, etc. We do
8861 this before the menu bars so that the buffer-menu will show the
8862 up-to-date frame titles. */
8863 #ifdef HAVE_WINDOW_SYSTEM
8864 if (windows_or_buffers_changed || update_mode_lines)
8865 {
8866 Lisp_Object tail, frame;
8867
8868 FOR_EACH_FRAME (tail, frame)
8869 {
8870 f = XFRAME (frame);
8871 if (!EQ (frame, tooltip_frame)
8872 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8873 x_consider_frame_title (frame);
8874 }
8875 }
8876 #endif /* HAVE_WINDOW_SYSTEM */
8877
8878 /* Update the menu bar item lists, if appropriate. This has to be
8879 done before any actual redisplay or generation of display lines. */
8880 all_windows = (update_mode_lines
8881 || buffer_shared > 1
8882 || windows_or_buffers_changed);
8883 if (all_windows)
8884 {
8885 Lisp_Object tail, frame;
8886 int count = SPECPDL_INDEX ();
8887
8888 record_unwind_save_match_data ();
8889
8890 FOR_EACH_FRAME (tail, frame)
8891 {
8892 f = XFRAME (frame);
8893
8894 /* Ignore tooltip frame. */
8895 if (EQ (frame, tooltip_frame))
8896 continue;
8897
8898 /* If a window on this frame changed size, report that to
8899 the user and clear the size-change flag. */
8900 if (FRAME_WINDOW_SIZES_CHANGED (f))
8901 {
8902 Lisp_Object functions;
8903
8904 /* Clear flag first in case we get an error below. */
8905 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8906 functions = Vwindow_size_change_functions;
8907 GCPRO2 (tail, functions);
8908
8909 while (CONSP (functions))
8910 {
8911 call1 (XCAR (functions), frame);
8912 functions = XCDR (functions);
8913 }
8914 UNGCPRO;
8915 }
8916
8917 GCPRO1 (tail);
8918 update_menu_bar (f, 0);
8919 #ifdef HAVE_WINDOW_SYSTEM
8920 update_tool_bar (f, 0);
8921 #endif
8922 UNGCPRO;
8923 }
8924
8925 unbind_to (count, Qnil);
8926 }
8927 else
8928 {
8929 struct frame *sf = SELECTED_FRAME ();
8930 update_menu_bar (sf, 1);
8931 #ifdef HAVE_WINDOW_SYSTEM
8932 update_tool_bar (sf, 1);
8933 #endif
8934 }
8935
8936 /* Motif needs this. See comment in xmenu.c. Turn it off when
8937 pending_menu_activation is not defined. */
8938 #ifdef USE_X_TOOLKIT
8939 pending_menu_activation = 0;
8940 #endif
8941 }
8942
8943
8944 /* Update the menu bar item list for frame F. This has to be done
8945 before we start to fill in any display lines, because it can call
8946 eval.
8947
8948 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8949
8950 static void
8951 update_menu_bar (f, save_match_data)
8952 struct frame *f;
8953 int save_match_data;
8954 {
8955 Lisp_Object window;
8956 register struct window *w;
8957
8958 /* If called recursively during a menu update, do nothing. This can
8959 happen when, for instance, an activate-menubar-hook causes a
8960 redisplay. */
8961 if (inhibit_menubar_update)
8962 return;
8963
8964 window = FRAME_SELECTED_WINDOW (f);
8965 w = XWINDOW (window);
8966
8967 #if 0 /* The if statement below this if statement used to include the
8968 condition !NILP (w->update_mode_line), rather than using
8969 update_mode_lines directly, and this if statement may have
8970 been added to make that condition work. Now the if
8971 statement below matches its comment, this isn't needed. */
8972 if (update_mode_lines)
8973 w->update_mode_line = Qt;
8974 #endif
8975
8976 if (FRAME_WINDOW_P (f)
8977 ?
8978 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8979 || defined (USE_GTK)
8980 FRAME_EXTERNAL_MENU_BAR (f)
8981 #else
8982 FRAME_MENU_BAR_LINES (f) > 0
8983 #endif
8984 : FRAME_MENU_BAR_LINES (f) > 0)
8985 {
8986 /* If the user has switched buffers or windows, we need to
8987 recompute to reflect the new bindings. But we'll
8988 recompute when update_mode_lines is set too; that means
8989 that people can use force-mode-line-update to request
8990 that the menu bar be recomputed. The adverse effect on
8991 the rest of the redisplay algorithm is about the same as
8992 windows_or_buffers_changed anyway. */
8993 if (windows_or_buffers_changed
8994 /* This used to test w->update_mode_line, but we believe
8995 there is no need to recompute the menu in that case. */
8996 || update_mode_lines
8997 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8998 < BUF_MODIFF (XBUFFER (w->buffer)))
8999 != !NILP (w->last_had_star))
9000 || ((!NILP (Vtransient_mark_mode)
9001 && !NILP (XBUFFER (w->buffer)->mark_active))
9002 != !NILP (w->region_showing)))
9003 {
9004 struct buffer *prev = current_buffer;
9005 int count = SPECPDL_INDEX ();
9006
9007 specbind (Qinhibit_menubar_update, Qt);
9008
9009 set_buffer_internal_1 (XBUFFER (w->buffer));
9010 if (save_match_data)
9011 record_unwind_save_match_data ();
9012 if (NILP (Voverriding_local_map_menu_flag))
9013 {
9014 specbind (Qoverriding_terminal_local_map, Qnil);
9015 specbind (Qoverriding_local_map, Qnil);
9016 }
9017
9018 /* Run the Lucid hook. */
9019 safe_run_hooks (Qactivate_menubar_hook);
9020
9021 /* If it has changed current-menubar from previous value,
9022 really recompute the menu-bar from the value. */
9023 if (! NILP (Vlucid_menu_bar_dirty_flag))
9024 call0 (Qrecompute_lucid_menubar);
9025
9026 safe_run_hooks (Qmenu_bar_update_hook);
9027 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9028
9029 /* Redisplay the menu bar in case we changed it. */
9030 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9031 || defined (USE_GTK)
9032 if (FRAME_WINDOW_P (f)
9033 #if defined (MAC_OS)
9034 /* All frames on Mac OS share the same menubar. So only the
9035 selected frame should be allowed to set it. */
9036 && f == SELECTED_FRAME ()
9037 #endif
9038 )
9039 set_frame_menubar (f, 0, 0);
9040 else
9041 /* On a terminal screen, the menu bar is an ordinary screen
9042 line, and this makes it get updated. */
9043 w->update_mode_line = Qt;
9044 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9045 /* In the non-toolkit version, the menu bar is an ordinary screen
9046 line, and this makes it get updated. */
9047 w->update_mode_line = Qt;
9048 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9049
9050 unbind_to (count, Qnil);
9051 set_buffer_internal_1 (prev);
9052 }
9053 }
9054 }
9055
9056
9057 \f
9058 /***********************************************************************
9059 Output Cursor
9060 ***********************************************************************/
9061
9062 #ifdef HAVE_WINDOW_SYSTEM
9063
9064 /* EXPORT:
9065 Nominal cursor position -- where to draw output.
9066 HPOS and VPOS are window relative glyph matrix coordinates.
9067 X and Y are window relative pixel coordinates. */
9068
9069 struct cursor_pos output_cursor;
9070
9071
9072 /* EXPORT:
9073 Set the global variable output_cursor to CURSOR. All cursor
9074 positions are relative to updated_window. */
9075
9076 void
9077 set_output_cursor (cursor)
9078 struct cursor_pos *cursor;
9079 {
9080 output_cursor.hpos = cursor->hpos;
9081 output_cursor.vpos = cursor->vpos;
9082 output_cursor.x = cursor->x;
9083 output_cursor.y = cursor->y;
9084 }
9085
9086
9087 /* EXPORT for RIF:
9088 Set a nominal cursor position.
9089
9090 HPOS and VPOS are column/row positions in a window glyph matrix. X
9091 and Y are window text area relative pixel positions.
9092
9093 If this is done during an update, updated_window will contain the
9094 window that is being updated and the position is the future output
9095 cursor position for that window. If updated_window is null, use
9096 selected_window and display the cursor at the given position. */
9097
9098 void
9099 x_cursor_to (vpos, hpos, y, x)
9100 int vpos, hpos, y, x;
9101 {
9102 struct window *w;
9103
9104 /* If updated_window is not set, work on selected_window. */
9105 if (updated_window)
9106 w = updated_window;
9107 else
9108 w = XWINDOW (selected_window);
9109
9110 /* Set the output cursor. */
9111 output_cursor.hpos = hpos;
9112 output_cursor.vpos = vpos;
9113 output_cursor.x = x;
9114 output_cursor.y = y;
9115
9116 /* If not called as part of an update, really display the cursor.
9117 This will also set the cursor position of W. */
9118 if (updated_window == NULL)
9119 {
9120 BLOCK_INPUT;
9121 display_and_set_cursor (w, 1, hpos, vpos, x, y);
9122 if (rif->flush_display_optional)
9123 rif->flush_display_optional (SELECTED_FRAME ());
9124 UNBLOCK_INPUT;
9125 }
9126 }
9127
9128 #endif /* HAVE_WINDOW_SYSTEM */
9129
9130 \f
9131 /***********************************************************************
9132 Tool-bars
9133 ***********************************************************************/
9134
9135 #ifdef HAVE_WINDOW_SYSTEM
9136
9137 /* Where the mouse was last time we reported a mouse event. */
9138
9139 FRAME_PTR last_mouse_frame;
9140
9141 /* Tool-bar item index of the item on which a mouse button was pressed
9142 or -1. */
9143
9144 int last_tool_bar_item;
9145
9146
9147 /* Update the tool-bar item list for frame F. This has to be done
9148 before we start to fill in any display lines. Called from
9149 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9150 and restore it here. */
9151
9152 static void
9153 update_tool_bar (f, save_match_data)
9154 struct frame *f;
9155 int save_match_data;
9156 {
9157 #ifdef USE_GTK
9158 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
9159 #else
9160 int do_update = WINDOWP (f->tool_bar_window)
9161 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
9162 #endif
9163
9164 if (do_update)
9165 {
9166 Lisp_Object window;
9167 struct window *w;
9168
9169 window = FRAME_SELECTED_WINDOW (f);
9170 w = XWINDOW (window);
9171
9172 /* If the user has switched buffers or windows, we need to
9173 recompute to reflect the new bindings. But we'll
9174 recompute when update_mode_lines is set too; that means
9175 that people can use force-mode-line-update to request
9176 that the menu bar be recomputed. The adverse effect on
9177 the rest of the redisplay algorithm is about the same as
9178 windows_or_buffers_changed anyway. */
9179 if (windows_or_buffers_changed
9180 || !NILP (w->update_mode_line)
9181 || update_mode_lines
9182 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9183 < BUF_MODIFF (XBUFFER (w->buffer)))
9184 != !NILP (w->last_had_star))
9185 || ((!NILP (Vtransient_mark_mode)
9186 && !NILP (XBUFFER (w->buffer)->mark_active))
9187 != !NILP (w->region_showing)))
9188 {
9189 struct buffer *prev = current_buffer;
9190 int count = SPECPDL_INDEX ();
9191 Lisp_Object new_tool_bar;
9192 int new_n_tool_bar;
9193 struct gcpro gcpro1;
9194
9195 /* Set current_buffer to the buffer of the selected
9196 window of the frame, so that we get the right local
9197 keymaps. */
9198 set_buffer_internal_1 (XBUFFER (w->buffer));
9199
9200 /* Save match data, if we must. */
9201 if (save_match_data)
9202 record_unwind_save_match_data ();
9203
9204 /* Make sure that we don't accidentally use bogus keymaps. */
9205 if (NILP (Voverriding_local_map_menu_flag))
9206 {
9207 specbind (Qoverriding_terminal_local_map, Qnil);
9208 specbind (Qoverriding_local_map, Qnil);
9209 }
9210
9211 GCPRO1 (new_tool_bar);
9212
9213 /* Build desired tool-bar items from keymaps. */
9214 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
9215 &new_n_tool_bar);
9216
9217 /* Redisplay the tool-bar if we changed it. */
9218 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
9219 {
9220 /* Redisplay that happens asynchronously due to an expose event
9221 may access f->tool_bar_items. Make sure we update both
9222 variables within BLOCK_INPUT so no such event interrupts. */
9223 BLOCK_INPUT;
9224 f->tool_bar_items = new_tool_bar;
9225 f->n_tool_bar_items = new_n_tool_bar;
9226 w->update_mode_line = Qt;
9227 UNBLOCK_INPUT;
9228 }
9229
9230 UNGCPRO;
9231
9232 unbind_to (count, Qnil);
9233 set_buffer_internal_1 (prev);
9234 }
9235 }
9236 }
9237
9238
9239 /* Set F->desired_tool_bar_string to a Lisp string representing frame
9240 F's desired tool-bar contents. F->tool_bar_items must have
9241 been set up previously by calling prepare_menu_bars. */
9242
9243 static void
9244 build_desired_tool_bar_string (f)
9245 struct frame *f;
9246 {
9247 int i, size, size_needed;
9248 struct gcpro gcpro1, gcpro2, gcpro3;
9249 Lisp_Object image, plist, props;
9250
9251 image = plist = props = Qnil;
9252 GCPRO3 (image, plist, props);
9253
9254 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
9255 Otherwise, make a new string. */
9256
9257 /* The size of the string we might be able to reuse. */
9258 size = (STRINGP (f->desired_tool_bar_string)
9259 ? SCHARS (f->desired_tool_bar_string)
9260 : 0);
9261
9262 /* We need one space in the string for each image. */
9263 size_needed = f->n_tool_bar_items;
9264
9265 /* Reuse f->desired_tool_bar_string, if possible. */
9266 if (size < size_needed || NILP (f->desired_tool_bar_string))
9267 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
9268 make_number (' '));
9269 else
9270 {
9271 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
9272 Fremove_text_properties (make_number (0), make_number (size),
9273 props, f->desired_tool_bar_string);
9274 }
9275
9276 /* Put a `display' property on the string for the images to display,
9277 put a `menu_item' property on tool-bar items with a value that
9278 is the index of the item in F's tool-bar item vector. */
9279 for (i = 0; i < f->n_tool_bar_items; ++i)
9280 {
9281 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
9282
9283 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
9284 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
9285 int hmargin, vmargin, relief, idx, end;
9286 extern Lisp_Object QCrelief, QCmargin, QCconversion;
9287
9288 /* If image is a vector, choose the image according to the
9289 button state. */
9290 image = PROP (TOOL_BAR_ITEM_IMAGES);
9291 if (VECTORP (image))
9292 {
9293 if (enabled_p)
9294 idx = (selected_p
9295 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
9296 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
9297 else
9298 idx = (selected_p
9299 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
9300 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
9301
9302 xassert (ASIZE (image) >= idx);
9303 image = AREF (image, idx);
9304 }
9305 else
9306 idx = -1;
9307
9308 /* Ignore invalid image specifications. */
9309 if (!valid_image_p (image))
9310 continue;
9311
9312 /* Display the tool-bar button pressed, or depressed. */
9313 plist = Fcopy_sequence (XCDR (image));
9314
9315 /* Compute margin and relief to draw. */
9316 relief = (tool_bar_button_relief >= 0
9317 ? tool_bar_button_relief
9318 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
9319 hmargin = vmargin = relief;
9320
9321 if (INTEGERP (Vtool_bar_button_margin)
9322 && XINT (Vtool_bar_button_margin) > 0)
9323 {
9324 hmargin += XFASTINT (Vtool_bar_button_margin);
9325 vmargin += XFASTINT (Vtool_bar_button_margin);
9326 }
9327 else if (CONSP (Vtool_bar_button_margin))
9328 {
9329 if (INTEGERP (XCAR (Vtool_bar_button_margin))
9330 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
9331 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
9332
9333 if (INTEGERP (XCDR (Vtool_bar_button_margin))
9334 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
9335 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
9336 }
9337
9338 if (auto_raise_tool_bar_buttons_p)
9339 {
9340 /* Add a `:relief' property to the image spec if the item is
9341 selected. */
9342 if (selected_p)
9343 {
9344 plist = Fplist_put (plist, QCrelief, make_number (-relief));
9345 hmargin -= relief;
9346 vmargin -= relief;
9347 }
9348 }
9349 else
9350 {
9351 /* If image is selected, display it pressed, i.e. with a
9352 negative relief. If it's not selected, display it with a
9353 raised relief. */
9354 plist = Fplist_put (plist, QCrelief,
9355 (selected_p
9356 ? make_number (-relief)
9357 : make_number (relief)));
9358 hmargin -= relief;
9359 vmargin -= relief;
9360 }
9361
9362 /* Put a margin around the image. */
9363 if (hmargin || vmargin)
9364 {
9365 if (hmargin == vmargin)
9366 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
9367 else
9368 plist = Fplist_put (plist, QCmargin,
9369 Fcons (make_number (hmargin),
9370 make_number (vmargin)));
9371 }
9372
9373 /* If button is not enabled, and we don't have special images
9374 for the disabled state, make the image appear disabled by
9375 applying an appropriate algorithm to it. */
9376 if (!enabled_p && idx < 0)
9377 plist = Fplist_put (plist, QCconversion, Qdisabled);
9378
9379 /* Put a `display' text property on the string for the image to
9380 display. Put a `menu-item' property on the string that gives
9381 the start of this item's properties in the tool-bar items
9382 vector. */
9383 image = Fcons (Qimage, plist);
9384 props = list4 (Qdisplay, image,
9385 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
9386
9387 /* Let the last image hide all remaining spaces in the tool bar
9388 string. The string can be longer than needed when we reuse a
9389 previous string. */
9390 if (i + 1 == f->n_tool_bar_items)
9391 end = SCHARS (f->desired_tool_bar_string);
9392 else
9393 end = i + 1;
9394 Fadd_text_properties (make_number (i), make_number (end),
9395 props, f->desired_tool_bar_string);
9396 #undef PROP
9397 }
9398
9399 UNGCPRO;
9400 }
9401
9402
9403 /* Display one line of the tool-bar of frame IT->f. */
9404
9405 static void
9406 display_tool_bar_line (it)
9407 struct it *it;
9408 {
9409 struct glyph_row *row = it->glyph_row;
9410 int max_x = it->last_visible_x;
9411 struct glyph *last;
9412
9413 prepare_desired_row (row);
9414 row->y = it->current_y;
9415
9416 /* Note that this isn't made use of if the face hasn't a box,
9417 so there's no need to check the face here. */
9418 it->start_of_box_run_p = 1;
9419
9420 while (it->current_x < max_x)
9421 {
9422 int x_before, x, n_glyphs_before, i, nglyphs;
9423
9424 /* Get the next display element. */
9425 if (!get_next_display_element (it))
9426 break;
9427
9428 /* Produce glyphs. */
9429 x_before = it->current_x;
9430 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
9431 PRODUCE_GLYPHS (it);
9432
9433 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
9434 i = 0;
9435 x = x_before;
9436 while (i < nglyphs)
9437 {
9438 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
9439
9440 if (x + glyph->pixel_width > max_x)
9441 {
9442 /* Glyph doesn't fit on line. */
9443 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
9444 it->current_x = x;
9445 goto out;
9446 }
9447
9448 ++it->hpos;
9449 x += glyph->pixel_width;
9450 ++i;
9451 }
9452
9453 /* Stop at line ends. */
9454 if (ITERATOR_AT_END_OF_LINE_P (it))
9455 break;
9456
9457 set_iterator_to_next (it, 1);
9458 }
9459
9460 out:;
9461
9462 row->displays_text_p = row->used[TEXT_AREA] != 0;
9463 extend_face_to_end_of_line (it);
9464 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
9465 last->right_box_line_p = 1;
9466 if (last == row->glyphs[TEXT_AREA])
9467 last->left_box_line_p = 1;
9468 compute_line_metrics (it);
9469
9470 /* If line is empty, make it occupy the rest of the tool-bar. */
9471 if (!row->displays_text_p)
9472 {
9473 row->height = row->phys_height = it->last_visible_y - row->y;
9474 row->ascent = row->phys_ascent = 0;
9475 row->extra_line_spacing = 0;
9476 }
9477
9478 row->full_width_p = 1;
9479 row->continued_p = 0;
9480 row->truncated_on_left_p = 0;
9481 row->truncated_on_right_p = 0;
9482
9483 it->current_x = it->hpos = 0;
9484 it->current_y += row->height;
9485 ++it->vpos;
9486 ++it->glyph_row;
9487 }
9488
9489
9490 /* Value is the number of screen lines needed to make all tool-bar
9491 items of frame F visible. */
9492
9493 static int
9494 tool_bar_lines_needed (f)
9495 struct frame *f;
9496 {
9497 struct window *w = XWINDOW (f->tool_bar_window);
9498 struct it it;
9499
9500 /* Initialize an iterator for iteration over
9501 F->desired_tool_bar_string in the tool-bar window of frame F. */
9502 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9503 it.first_visible_x = 0;
9504 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9505 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9506
9507 while (!ITERATOR_AT_END_P (&it))
9508 {
9509 it.glyph_row = w->desired_matrix->rows;
9510 clear_glyph_row (it.glyph_row);
9511 display_tool_bar_line (&it);
9512 }
9513
9514 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
9515 }
9516
9517
9518 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
9519 0, 1, 0,
9520 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
9521 (frame)
9522 Lisp_Object frame;
9523 {
9524 struct frame *f;
9525 struct window *w;
9526 int nlines = 0;
9527
9528 if (NILP (frame))
9529 frame = selected_frame;
9530 else
9531 CHECK_FRAME (frame);
9532 f = XFRAME (frame);
9533
9534 if (WINDOWP (f->tool_bar_window)
9535 || (w = XWINDOW (f->tool_bar_window),
9536 WINDOW_TOTAL_LINES (w) > 0))
9537 {
9538 update_tool_bar (f, 1);
9539 if (f->n_tool_bar_items)
9540 {
9541 build_desired_tool_bar_string (f);
9542 nlines = tool_bar_lines_needed (f);
9543 }
9544 }
9545
9546 return make_number (nlines);
9547 }
9548
9549
9550 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9551 height should be changed. */
9552
9553 static int
9554 redisplay_tool_bar (f)
9555 struct frame *f;
9556 {
9557 struct window *w;
9558 struct it it;
9559 struct glyph_row *row;
9560 int change_height_p = 0;
9561
9562 #ifdef USE_GTK
9563 if (FRAME_EXTERNAL_TOOL_BAR (f))
9564 update_frame_tool_bar (f);
9565 return 0;
9566 #endif
9567
9568 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9569 do anything. This means you must start with tool-bar-lines
9570 non-zero to get the auto-sizing effect. Or in other words, you
9571 can turn off tool-bars by specifying tool-bar-lines zero. */
9572 if (!WINDOWP (f->tool_bar_window)
9573 || (w = XWINDOW (f->tool_bar_window),
9574 WINDOW_TOTAL_LINES (w) == 0))
9575 return 0;
9576
9577 /* Set up an iterator for the tool-bar window. */
9578 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9579 it.first_visible_x = 0;
9580 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9581 row = it.glyph_row;
9582
9583 /* Build a string that represents the contents of the tool-bar. */
9584 build_desired_tool_bar_string (f);
9585 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9586
9587 /* Display as many lines as needed to display all tool-bar items. */
9588 while (it.current_y < it.last_visible_y)
9589 display_tool_bar_line (&it);
9590
9591 /* It doesn't make much sense to try scrolling in the tool-bar
9592 window, so don't do it. */
9593 w->desired_matrix->no_scrolling_p = 1;
9594 w->must_be_updated_p = 1;
9595
9596 if (auto_resize_tool_bars_p)
9597 {
9598 int nlines;
9599
9600 /* If we couldn't display everything, change the tool-bar's
9601 height. */
9602 if (IT_STRING_CHARPOS (it) < it.end_charpos)
9603 change_height_p = 1;
9604
9605 /* If there are blank lines at the end, except for a partially
9606 visible blank line at the end that is smaller than
9607 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9608 row = it.glyph_row - 1;
9609 if (!row->displays_text_p
9610 && row->height >= FRAME_LINE_HEIGHT (f))
9611 change_height_p = 1;
9612
9613 /* If row displays tool-bar items, but is partially visible,
9614 change the tool-bar's height. */
9615 if (row->displays_text_p
9616 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
9617 change_height_p = 1;
9618
9619 /* Resize windows as needed by changing the `tool-bar-lines'
9620 frame parameter. */
9621 if (change_height_p
9622 && (nlines = tool_bar_lines_needed (f),
9623 nlines != WINDOW_TOTAL_LINES (w)))
9624 {
9625 extern Lisp_Object Qtool_bar_lines;
9626 Lisp_Object frame;
9627 int old_height = WINDOW_TOTAL_LINES (w);
9628
9629 XSETFRAME (frame, f);
9630 clear_glyph_matrix (w->desired_matrix);
9631 Fmodify_frame_parameters (frame,
9632 Fcons (Fcons (Qtool_bar_lines,
9633 make_number (nlines)),
9634 Qnil));
9635 if (WINDOW_TOTAL_LINES (w) != old_height)
9636 fonts_changed_p = 1;
9637 }
9638 }
9639
9640 return change_height_p;
9641 }
9642
9643
9644 /* Get information about the tool-bar item which is displayed in GLYPH
9645 on frame F. Return in *PROP_IDX the index where tool-bar item
9646 properties start in F->tool_bar_items. Value is zero if
9647 GLYPH doesn't display a tool-bar item. */
9648
9649 static int
9650 tool_bar_item_info (f, glyph, prop_idx)
9651 struct frame *f;
9652 struct glyph *glyph;
9653 int *prop_idx;
9654 {
9655 Lisp_Object prop;
9656 int success_p;
9657 int charpos;
9658
9659 /* This function can be called asynchronously, which means we must
9660 exclude any possibility that Fget_text_property signals an
9661 error. */
9662 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
9663 charpos = max (0, charpos);
9664
9665 /* Get the text property `menu-item' at pos. The value of that
9666 property is the start index of this item's properties in
9667 F->tool_bar_items. */
9668 prop = Fget_text_property (make_number (charpos),
9669 Qmenu_item, f->current_tool_bar_string);
9670 if (INTEGERP (prop))
9671 {
9672 *prop_idx = XINT (prop);
9673 success_p = 1;
9674 }
9675 else
9676 success_p = 0;
9677
9678 return success_p;
9679 }
9680
9681 \f
9682 /* Get information about the tool-bar item at position X/Y on frame F.
9683 Return in *GLYPH a pointer to the glyph of the tool-bar item in
9684 the current matrix of the tool-bar window of F, or NULL if not
9685 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
9686 item in F->tool_bar_items. Value is
9687
9688 -1 if X/Y is not on a tool-bar item
9689 0 if X/Y is on the same item that was highlighted before.
9690 1 otherwise. */
9691
9692 static int
9693 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
9694 struct frame *f;
9695 int x, y;
9696 struct glyph **glyph;
9697 int *hpos, *vpos, *prop_idx;
9698 {
9699 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9700 struct window *w = XWINDOW (f->tool_bar_window);
9701 int area;
9702
9703 /* Find the glyph under X/Y. */
9704 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
9705 if (*glyph == NULL)
9706 return -1;
9707
9708 /* Get the start of this tool-bar item's properties in
9709 f->tool_bar_items. */
9710 if (!tool_bar_item_info (f, *glyph, prop_idx))
9711 return -1;
9712
9713 /* Is mouse on the highlighted item? */
9714 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
9715 && *vpos >= dpyinfo->mouse_face_beg_row
9716 && *vpos <= dpyinfo->mouse_face_end_row
9717 && (*vpos > dpyinfo->mouse_face_beg_row
9718 || *hpos >= dpyinfo->mouse_face_beg_col)
9719 && (*vpos < dpyinfo->mouse_face_end_row
9720 || *hpos < dpyinfo->mouse_face_end_col
9721 || dpyinfo->mouse_face_past_end))
9722 return 0;
9723
9724 return 1;
9725 }
9726
9727
9728 /* EXPORT:
9729 Handle mouse button event on the tool-bar of frame F, at
9730 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
9731 0 for button release. MODIFIERS is event modifiers for button
9732 release. */
9733
9734 void
9735 handle_tool_bar_click (f, x, y, down_p, modifiers)
9736 struct frame *f;
9737 int x, y, down_p;
9738 unsigned int modifiers;
9739 {
9740 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9741 struct window *w = XWINDOW (f->tool_bar_window);
9742 int hpos, vpos, prop_idx;
9743 struct glyph *glyph;
9744 Lisp_Object enabled_p;
9745
9746 /* If not on the highlighted tool-bar item, return. */
9747 frame_to_window_pixel_xy (w, &x, &y);
9748 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
9749 return;
9750
9751 /* If item is disabled, do nothing. */
9752 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9753 if (NILP (enabled_p))
9754 return;
9755
9756 if (down_p)
9757 {
9758 /* Show item in pressed state. */
9759 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
9760 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
9761 last_tool_bar_item = prop_idx;
9762 }
9763 else
9764 {
9765 Lisp_Object key, frame;
9766 struct input_event event;
9767 EVENT_INIT (event);
9768
9769 /* Show item in released state. */
9770 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
9771 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9772
9773 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9774
9775 XSETFRAME (frame, f);
9776 event.kind = TOOL_BAR_EVENT;
9777 event.frame_or_window = frame;
9778 event.arg = frame;
9779 kbd_buffer_store_event (&event);
9780
9781 event.kind = TOOL_BAR_EVENT;
9782 event.frame_or_window = frame;
9783 event.arg = key;
9784 event.modifiers = modifiers;
9785 kbd_buffer_store_event (&event);
9786 last_tool_bar_item = -1;
9787 }
9788 }
9789
9790
9791 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9792 tool-bar window-relative coordinates X/Y. Called from
9793 note_mouse_highlight. */
9794
9795 static void
9796 note_tool_bar_highlight (f, x, y)
9797 struct frame *f;
9798 int x, y;
9799 {
9800 Lisp_Object window = f->tool_bar_window;
9801 struct window *w = XWINDOW (window);
9802 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9803 int hpos, vpos;
9804 struct glyph *glyph;
9805 struct glyph_row *row;
9806 int i;
9807 Lisp_Object enabled_p;
9808 int prop_idx;
9809 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9810 int mouse_down_p, rc;
9811
9812 /* Function note_mouse_highlight is called with negative x(y
9813 values when mouse moves outside of the frame. */
9814 if (x <= 0 || y <= 0)
9815 {
9816 clear_mouse_face (dpyinfo);
9817 return;
9818 }
9819
9820 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9821 if (rc < 0)
9822 {
9823 /* Not on tool-bar item. */
9824 clear_mouse_face (dpyinfo);
9825 return;
9826 }
9827 else if (rc == 0)
9828 /* On same tool-bar item as before. */
9829 goto set_help_echo;
9830
9831 clear_mouse_face (dpyinfo);
9832
9833 /* Mouse is down, but on different tool-bar item? */
9834 mouse_down_p = (dpyinfo->grabbed
9835 && f == last_mouse_frame
9836 && FRAME_LIVE_P (f));
9837 if (mouse_down_p
9838 && last_tool_bar_item != prop_idx)
9839 return;
9840
9841 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9842 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9843
9844 /* If tool-bar item is not enabled, don't highlight it. */
9845 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9846 if (!NILP (enabled_p))
9847 {
9848 /* Compute the x-position of the glyph. In front and past the
9849 image is a space. We include this in the highlighted area. */
9850 row = MATRIX_ROW (w->current_matrix, vpos);
9851 for (i = x = 0; i < hpos; ++i)
9852 x += row->glyphs[TEXT_AREA][i].pixel_width;
9853
9854 /* Record this as the current active region. */
9855 dpyinfo->mouse_face_beg_col = hpos;
9856 dpyinfo->mouse_face_beg_row = vpos;
9857 dpyinfo->mouse_face_beg_x = x;
9858 dpyinfo->mouse_face_beg_y = row->y;
9859 dpyinfo->mouse_face_past_end = 0;
9860
9861 dpyinfo->mouse_face_end_col = hpos + 1;
9862 dpyinfo->mouse_face_end_row = vpos;
9863 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9864 dpyinfo->mouse_face_end_y = row->y;
9865 dpyinfo->mouse_face_window = window;
9866 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9867
9868 /* Display it as active. */
9869 show_mouse_face (dpyinfo, draw);
9870 dpyinfo->mouse_face_image_state = draw;
9871 }
9872
9873 set_help_echo:
9874
9875 /* Set help_echo_string to a help string to display for this tool-bar item.
9876 XTread_socket does the rest. */
9877 help_echo_object = help_echo_window = Qnil;
9878 help_echo_pos = -1;
9879 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9880 if (NILP (help_echo_string))
9881 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9882 }
9883
9884 #endif /* HAVE_WINDOW_SYSTEM */
9885
9886
9887 \f
9888 /************************************************************************
9889 Horizontal scrolling
9890 ************************************************************************/
9891
9892 static int hscroll_window_tree P_ ((Lisp_Object));
9893 static int hscroll_windows P_ ((Lisp_Object));
9894
9895 /* For all leaf windows in the window tree rooted at WINDOW, set their
9896 hscroll value so that PT is (i) visible in the window, and (ii) so
9897 that it is not within a certain margin at the window's left and
9898 right border. Value is non-zero if any window's hscroll has been
9899 changed. */
9900
9901 static int
9902 hscroll_window_tree (window)
9903 Lisp_Object window;
9904 {
9905 int hscrolled_p = 0;
9906 int hscroll_relative_p = FLOATP (Vhscroll_step);
9907 int hscroll_step_abs = 0;
9908 double hscroll_step_rel = 0;
9909
9910 if (hscroll_relative_p)
9911 {
9912 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9913 if (hscroll_step_rel < 0)
9914 {
9915 hscroll_relative_p = 0;
9916 hscroll_step_abs = 0;
9917 }
9918 }
9919 else if (INTEGERP (Vhscroll_step))
9920 {
9921 hscroll_step_abs = XINT (Vhscroll_step);
9922 if (hscroll_step_abs < 0)
9923 hscroll_step_abs = 0;
9924 }
9925 else
9926 hscroll_step_abs = 0;
9927
9928 while (WINDOWP (window))
9929 {
9930 struct window *w = XWINDOW (window);
9931
9932 if (WINDOWP (w->hchild))
9933 hscrolled_p |= hscroll_window_tree (w->hchild);
9934 else if (WINDOWP (w->vchild))
9935 hscrolled_p |= hscroll_window_tree (w->vchild);
9936 else if (w->cursor.vpos >= 0)
9937 {
9938 int h_margin;
9939 int text_area_width;
9940 struct glyph_row *current_cursor_row
9941 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9942 struct glyph_row *desired_cursor_row
9943 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9944 struct glyph_row *cursor_row
9945 = (desired_cursor_row->enabled_p
9946 ? desired_cursor_row
9947 : current_cursor_row);
9948
9949 text_area_width = window_box_width (w, TEXT_AREA);
9950
9951 /* Scroll when cursor is inside this scroll margin. */
9952 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9953
9954 if ((XFASTINT (w->hscroll)
9955 && w->cursor.x <= h_margin)
9956 || (cursor_row->enabled_p
9957 && cursor_row->truncated_on_right_p
9958 && (w->cursor.x >= text_area_width - h_margin)))
9959 {
9960 struct it it;
9961 int hscroll;
9962 struct buffer *saved_current_buffer;
9963 int pt;
9964 int wanted_x;
9965
9966 /* Find point in a display of infinite width. */
9967 saved_current_buffer = current_buffer;
9968 current_buffer = XBUFFER (w->buffer);
9969
9970 if (w == XWINDOW (selected_window))
9971 pt = BUF_PT (current_buffer);
9972 else
9973 {
9974 pt = marker_position (w->pointm);
9975 pt = max (BEGV, pt);
9976 pt = min (ZV, pt);
9977 }
9978
9979 /* Move iterator to pt starting at cursor_row->start in
9980 a line with infinite width. */
9981 init_to_row_start (&it, w, cursor_row);
9982 it.last_visible_x = INFINITY;
9983 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9984 current_buffer = saved_current_buffer;
9985
9986 /* Position cursor in window. */
9987 if (!hscroll_relative_p && hscroll_step_abs == 0)
9988 hscroll = max (0, (it.current_x
9989 - (ITERATOR_AT_END_OF_LINE_P (&it)
9990 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9991 : (text_area_width / 2))))
9992 / FRAME_COLUMN_WIDTH (it.f);
9993 else if (w->cursor.x >= text_area_width - h_margin)
9994 {
9995 if (hscroll_relative_p)
9996 wanted_x = text_area_width * (1 - hscroll_step_rel)
9997 - h_margin;
9998 else
9999 wanted_x = text_area_width
10000 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10001 - h_margin;
10002 hscroll
10003 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10004 }
10005 else
10006 {
10007 if (hscroll_relative_p)
10008 wanted_x = text_area_width * hscroll_step_rel
10009 + h_margin;
10010 else
10011 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10012 + h_margin;
10013 hscroll
10014 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10015 }
10016 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
10017
10018 /* Don't call Fset_window_hscroll if value hasn't
10019 changed because it will prevent redisplay
10020 optimizations. */
10021 if (XFASTINT (w->hscroll) != hscroll)
10022 {
10023 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
10024 w->hscroll = make_number (hscroll);
10025 hscrolled_p = 1;
10026 }
10027 }
10028 }
10029
10030 window = w->next;
10031 }
10032
10033 /* Value is non-zero if hscroll of any leaf window has been changed. */
10034 return hscrolled_p;
10035 }
10036
10037
10038 /* Set hscroll so that cursor is visible and not inside horizontal
10039 scroll margins for all windows in the tree rooted at WINDOW. See
10040 also hscroll_window_tree above. Value is non-zero if any window's
10041 hscroll has been changed. If it has, desired matrices on the frame
10042 of WINDOW are cleared. */
10043
10044 static int
10045 hscroll_windows (window)
10046 Lisp_Object window;
10047 {
10048 int hscrolled_p;
10049
10050 if (automatic_hscrolling_p)
10051 {
10052 hscrolled_p = hscroll_window_tree (window);
10053 if (hscrolled_p)
10054 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
10055 }
10056 else
10057 hscrolled_p = 0;
10058 return hscrolled_p;
10059 }
10060
10061
10062 \f
10063 /************************************************************************
10064 Redisplay
10065 ************************************************************************/
10066
10067 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
10068 to a non-zero value. This is sometimes handy to have in a debugger
10069 session. */
10070
10071 #if GLYPH_DEBUG
10072
10073 /* First and last unchanged row for try_window_id. */
10074
10075 int debug_first_unchanged_at_end_vpos;
10076 int debug_last_unchanged_at_beg_vpos;
10077
10078 /* Delta vpos and y. */
10079
10080 int debug_dvpos, debug_dy;
10081
10082 /* Delta in characters and bytes for try_window_id. */
10083
10084 int debug_delta, debug_delta_bytes;
10085
10086 /* Values of window_end_pos and window_end_vpos at the end of
10087 try_window_id. */
10088
10089 EMACS_INT debug_end_pos, debug_end_vpos;
10090
10091 /* Append a string to W->desired_matrix->method. FMT is a printf
10092 format string. A1...A9 are a supplement for a variable-length
10093 argument list. If trace_redisplay_p is non-zero also printf the
10094 resulting string to stderr. */
10095
10096 static void
10097 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
10098 struct window *w;
10099 char *fmt;
10100 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
10101 {
10102 char buffer[512];
10103 char *method = w->desired_matrix->method;
10104 int len = strlen (method);
10105 int size = sizeof w->desired_matrix->method;
10106 int remaining = size - len - 1;
10107
10108 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
10109 if (len && remaining)
10110 {
10111 method[len] = '|';
10112 --remaining, ++len;
10113 }
10114
10115 strncpy (method + len, buffer, remaining);
10116
10117 if (trace_redisplay_p)
10118 fprintf (stderr, "%p (%s): %s\n",
10119 w,
10120 ((BUFFERP (w->buffer)
10121 && STRINGP (XBUFFER (w->buffer)->name))
10122 ? (char *) SDATA (XBUFFER (w->buffer)->name)
10123 : "no buffer"),
10124 buffer);
10125 }
10126
10127 #endif /* GLYPH_DEBUG */
10128
10129
10130 /* Value is non-zero if all changes in window W, which displays
10131 current_buffer, are in the text between START and END. START is a
10132 buffer position, END is given as a distance from Z. Used in
10133 redisplay_internal for display optimization. */
10134
10135 static INLINE int
10136 text_outside_line_unchanged_p (w, start, end)
10137 struct window *w;
10138 int start, end;
10139 {
10140 int unchanged_p = 1;
10141
10142 /* If text or overlays have changed, see where. */
10143 if (XFASTINT (w->last_modified) < MODIFF
10144 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10145 {
10146 /* Gap in the line? */
10147 if (GPT < start || Z - GPT < end)
10148 unchanged_p = 0;
10149
10150 /* Changes start in front of the line, or end after it? */
10151 if (unchanged_p
10152 && (BEG_UNCHANGED < start - 1
10153 || END_UNCHANGED < end))
10154 unchanged_p = 0;
10155
10156 /* If selective display, can't optimize if changes start at the
10157 beginning of the line. */
10158 if (unchanged_p
10159 && INTEGERP (current_buffer->selective_display)
10160 && XINT (current_buffer->selective_display) > 0
10161 && (BEG_UNCHANGED < start || GPT <= start))
10162 unchanged_p = 0;
10163
10164 /* If there are overlays at the start or end of the line, these
10165 may have overlay strings with newlines in them. A change at
10166 START, for instance, may actually concern the display of such
10167 overlay strings as well, and they are displayed on different
10168 lines. So, quickly rule out this case. (For the future, it
10169 might be desirable to implement something more telling than
10170 just BEG/END_UNCHANGED.) */
10171 if (unchanged_p)
10172 {
10173 if (BEG + BEG_UNCHANGED == start
10174 && overlay_touches_p (start))
10175 unchanged_p = 0;
10176 if (END_UNCHANGED == end
10177 && overlay_touches_p (Z - end))
10178 unchanged_p = 0;
10179 }
10180 }
10181
10182 return unchanged_p;
10183 }
10184
10185
10186 /* Do a frame update, taking possible shortcuts into account. This is
10187 the main external entry point for redisplay.
10188
10189 If the last redisplay displayed an echo area message and that message
10190 is no longer requested, we clear the echo area or bring back the
10191 mini-buffer if that is in use. */
10192
10193 void
10194 redisplay ()
10195 {
10196 redisplay_internal (0);
10197 }
10198
10199
10200 static Lisp_Object
10201 overlay_arrow_string_or_property (var)
10202 Lisp_Object var;
10203 {
10204 Lisp_Object val;
10205
10206 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
10207 return val;
10208
10209 return Voverlay_arrow_string;
10210 }
10211
10212 /* Return 1 if there are any overlay-arrows in current_buffer. */
10213 static int
10214 overlay_arrow_in_current_buffer_p ()
10215 {
10216 Lisp_Object vlist;
10217
10218 for (vlist = Voverlay_arrow_variable_list;
10219 CONSP (vlist);
10220 vlist = XCDR (vlist))
10221 {
10222 Lisp_Object var = XCAR (vlist);
10223 Lisp_Object val;
10224
10225 if (!SYMBOLP (var))
10226 continue;
10227 val = find_symbol_value (var);
10228 if (MARKERP (val)
10229 && current_buffer == XMARKER (val)->buffer)
10230 return 1;
10231 }
10232 return 0;
10233 }
10234
10235
10236 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
10237 has changed. */
10238
10239 static int
10240 overlay_arrows_changed_p ()
10241 {
10242 Lisp_Object vlist;
10243
10244 for (vlist = Voverlay_arrow_variable_list;
10245 CONSP (vlist);
10246 vlist = XCDR (vlist))
10247 {
10248 Lisp_Object var = XCAR (vlist);
10249 Lisp_Object val, pstr;
10250
10251 if (!SYMBOLP (var))
10252 continue;
10253 val = find_symbol_value (var);
10254 if (!MARKERP (val))
10255 continue;
10256 if (! EQ (COERCE_MARKER (val),
10257 Fget (var, Qlast_arrow_position))
10258 || ! (pstr = overlay_arrow_string_or_property (var),
10259 EQ (pstr, Fget (var, Qlast_arrow_string))))
10260 return 1;
10261 }
10262 return 0;
10263 }
10264
10265 /* Mark overlay arrows to be updated on next redisplay. */
10266
10267 static void
10268 update_overlay_arrows (up_to_date)
10269 int up_to_date;
10270 {
10271 Lisp_Object vlist;
10272
10273 for (vlist = Voverlay_arrow_variable_list;
10274 CONSP (vlist);
10275 vlist = XCDR (vlist))
10276 {
10277 Lisp_Object var = XCAR (vlist);
10278
10279 if (!SYMBOLP (var))
10280 continue;
10281
10282 if (up_to_date > 0)
10283 {
10284 Lisp_Object val = find_symbol_value (var);
10285 Fput (var, Qlast_arrow_position,
10286 COERCE_MARKER (val));
10287 Fput (var, Qlast_arrow_string,
10288 overlay_arrow_string_or_property (var));
10289 }
10290 else if (up_to_date < 0
10291 || !NILP (Fget (var, Qlast_arrow_position)))
10292 {
10293 Fput (var, Qlast_arrow_position, Qt);
10294 Fput (var, Qlast_arrow_string, Qt);
10295 }
10296 }
10297 }
10298
10299
10300 /* Return overlay arrow string to display at row.
10301 Return integer (bitmap number) for arrow bitmap in left fringe.
10302 Return nil if no overlay arrow. */
10303
10304 static Lisp_Object
10305 overlay_arrow_at_row (it, row)
10306 struct it *it;
10307 struct glyph_row *row;
10308 {
10309 Lisp_Object vlist;
10310
10311 for (vlist = Voverlay_arrow_variable_list;
10312 CONSP (vlist);
10313 vlist = XCDR (vlist))
10314 {
10315 Lisp_Object var = XCAR (vlist);
10316 Lisp_Object val;
10317
10318 if (!SYMBOLP (var))
10319 continue;
10320
10321 val = find_symbol_value (var);
10322
10323 if (MARKERP (val)
10324 && current_buffer == XMARKER (val)->buffer
10325 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
10326 {
10327 if (FRAME_WINDOW_P (it->f)
10328 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
10329 {
10330 #ifdef HAVE_WINDOW_SYSTEM
10331 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
10332 {
10333 int fringe_bitmap;
10334 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
10335 return make_number (fringe_bitmap);
10336 }
10337 #endif
10338 return make_number (-1); /* Use default arrow bitmap */
10339 }
10340 return overlay_arrow_string_or_property (var);
10341 }
10342 }
10343
10344 return Qnil;
10345 }
10346
10347 /* Return 1 if point moved out of or into a composition. Otherwise
10348 return 0. PREV_BUF and PREV_PT are the last point buffer and
10349 position. BUF and PT are the current point buffer and position. */
10350
10351 int
10352 check_point_in_composition (prev_buf, prev_pt, buf, pt)
10353 struct buffer *prev_buf, *buf;
10354 int prev_pt, pt;
10355 {
10356 int start, end;
10357 Lisp_Object prop;
10358 Lisp_Object buffer;
10359
10360 XSETBUFFER (buffer, buf);
10361 /* Check a composition at the last point if point moved within the
10362 same buffer. */
10363 if (prev_buf == buf)
10364 {
10365 if (prev_pt == pt)
10366 /* Point didn't move. */
10367 return 0;
10368
10369 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
10370 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
10371 && COMPOSITION_VALID_P (start, end, prop)
10372 && start < prev_pt && end > prev_pt)
10373 /* The last point was within the composition. Return 1 iff
10374 point moved out of the composition. */
10375 return (pt <= start || pt >= end);
10376 }
10377
10378 /* Check a composition at the current point. */
10379 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
10380 && find_composition (pt, -1, &start, &end, &prop, buffer)
10381 && COMPOSITION_VALID_P (start, end, prop)
10382 && start < pt && end > pt);
10383 }
10384
10385
10386 /* Reconsider the setting of B->clip_changed which is displayed
10387 in window W. */
10388
10389 static INLINE void
10390 reconsider_clip_changes (w, b)
10391 struct window *w;
10392 struct buffer *b;
10393 {
10394 if (b->clip_changed
10395 && !NILP (w->window_end_valid)
10396 && w->current_matrix->buffer == b
10397 && w->current_matrix->zv == BUF_ZV (b)
10398 && w->current_matrix->begv == BUF_BEGV (b))
10399 b->clip_changed = 0;
10400
10401 /* If display wasn't paused, and W is not a tool bar window, see if
10402 point has been moved into or out of a composition. In that case,
10403 we set b->clip_changed to 1 to force updating the screen. If
10404 b->clip_changed has already been set to 1, we can skip this
10405 check. */
10406 if (!b->clip_changed
10407 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
10408 {
10409 int pt;
10410
10411 if (w == XWINDOW (selected_window))
10412 pt = BUF_PT (current_buffer);
10413 else
10414 pt = marker_position (w->pointm);
10415
10416 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
10417 || pt != XINT (w->last_point))
10418 && check_point_in_composition (w->current_matrix->buffer,
10419 XINT (w->last_point),
10420 XBUFFER (w->buffer), pt))
10421 b->clip_changed = 1;
10422 }
10423 }
10424 \f
10425
10426 /* Select FRAME to forward the values of frame-local variables into C
10427 variables so that the redisplay routines can access those values
10428 directly. */
10429
10430 static void
10431 select_frame_for_redisplay (frame)
10432 Lisp_Object frame;
10433 {
10434 Lisp_Object tail, sym, val;
10435 Lisp_Object old = selected_frame;
10436
10437 selected_frame = frame;
10438
10439 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
10440 if (CONSP (XCAR (tail))
10441 && (sym = XCAR (XCAR (tail)),
10442 SYMBOLP (sym))
10443 && (sym = indirect_variable (sym),
10444 val = SYMBOL_VALUE (sym),
10445 (BUFFER_LOCAL_VALUEP (val)
10446 || SOME_BUFFER_LOCAL_VALUEP (val)))
10447 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10448 /* Use find_symbol_value rather than Fsymbol_value
10449 to avoid an error if it is void. */
10450 find_symbol_value (sym);
10451
10452 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
10453 if (CONSP (XCAR (tail))
10454 && (sym = XCAR (XCAR (tail)),
10455 SYMBOLP (sym))
10456 && (sym = indirect_variable (sym),
10457 val = SYMBOL_VALUE (sym),
10458 (BUFFER_LOCAL_VALUEP (val)
10459 || SOME_BUFFER_LOCAL_VALUEP (val)))
10460 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10461 find_symbol_value (sym);
10462 }
10463
10464
10465 #define STOP_POLLING \
10466 do { if (! polling_stopped_here) stop_polling (); \
10467 polling_stopped_here = 1; } while (0)
10468
10469 #define RESUME_POLLING \
10470 do { if (polling_stopped_here) start_polling (); \
10471 polling_stopped_here = 0; } while (0)
10472
10473
10474 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
10475 response to any user action; therefore, we should preserve the echo
10476 area. (Actually, our caller does that job.) Perhaps in the future
10477 avoid recentering windows if it is not necessary; currently that
10478 causes some problems. */
10479
10480 static void
10481 redisplay_internal (preserve_echo_area)
10482 int preserve_echo_area;
10483 {
10484 struct window *w = XWINDOW (selected_window);
10485 struct frame *f = XFRAME (w->frame);
10486 int pause;
10487 int must_finish = 0;
10488 struct text_pos tlbufpos, tlendpos;
10489 int number_of_visible_frames;
10490 int count;
10491 struct frame *sf = SELECTED_FRAME ();
10492 int polling_stopped_here = 0;
10493
10494 /* Non-zero means redisplay has to consider all windows on all
10495 frames. Zero means, only selected_window is considered. */
10496 int consider_all_windows_p;
10497
10498 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
10499
10500 /* No redisplay if running in batch mode or frame is not yet fully
10501 initialized, or redisplay is explicitly turned off by setting
10502 Vinhibit_redisplay. */
10503 if (noninteractive
10504 || !NILP (Vinhibit_redisplay)
10505 || !f->glyphs_initialized_p)
10506 return;
10507
10508 /* The flag redisplay_performed_directly_p is set by
10509 direct_output_for_insert when it already did the whole screen
10510 update necessary. */
10511 if (redisplay_performed_directly_p)
10512 {
10513 redisplay_performed_directly_p = 0;
10514 if (!hscroll_windows (selected_window))
10515 return;
10516 }
10517
10518 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
10519 if (popup_activated ())
10520 return;
10521 #endif
10522
10523 /* I don't think this happens but let's be paranoid. */
10524 if (redisplaying_p)
10525 return;
10526
10527 /* Record a function that resets redisplaying_p to its old value
10528 when we leave this function. */
10529 count = SPECPDL_INDEX ();
10530 record_unwind_protect (unwind_redisplay,
10531 Fcons (make_number (redisplaying_p), selected_frame));
10532 ++redisplaying_p;
10533 specbind (Qinhibit_free_realized_faces, Qnil);
10534
10535 {
10536 Lisp_Object tail, frame;
10537
10538 FOR_EACH_FRAME (tail, frame)
10539 {
10540 struct frame *f = XFRAME (frame);
10541 f->already_hscrolled_p = 0;
10542 }
10543 }
10544
10545 retry:
10546 pause = 0;
10547 reconsider_clip_changes (w, current_buffer);
10548
10549 /* If new fonts have been loaded that make a glyph matrix adjustment
10550 necessary, do it. */
10551 if (fonts_changed_p)
10552 {
10553 adjust_glyphs (NULL);
10554 ++windows_or_buffers_changed;
10555 fonts_changed_p = 0;
10556 }
10557
10558 /* If face_change_count is non-zero, init_iterator will free all
10559 realized faces, which includes the faces referenced from current
10560 matrices. So, we can't reuse current matrices in this case. */
10561 if (face_change_count)
10562 ++windows_or_buffers_changed;
10563
10564 if (! FRAME_WINDOW_P (sf)
10565 && previous_terminal_frame != sf)
10566 {
10567 /* Since frames on an ASCII terminal share the same display
10568 area, displaying a different frame means redisplay the whole
10569 thing. */
10570 windows_or_buffers_changed++;
10571 SET_FRAME_GARBAGED (sf);
10572 XSETFRAME (Vterminal_frame, sf);
10573 }
10574 previous_terminal_frame = sf;
10575
10576 /* Set the visible flags for all frames. Do this before checking
10577 for resized or garbaged frames; they want to know if their frames
10578 are visible. See the comment in frame.h for
10579 FRAME_SAMPLE_VISIBILITY. */
10580 {
10581 Lisp_Object tail, frame;
10582
10583 number_of_visible_frames = 0;
10584
10585 FOR_EACH_FRAME (tail, frame)
10586 {
10587 struct frame *f = XFRAME (frame);
10588
10589 FRAME_SAMPLE_VISIBILITY (f);
10590 if (FRAME_VISIBLE_P (f))
10591 ++number_of_visible_frames;
10592 clear_desired_matrices (f);
10593 }
10594 }
10595
10596 /* Notice any pending interrupt request to change frame size. */
10597 do_pending_window_change (1);
10598
10599 /* Clear frames marked as garbaged. */
10600 if (frame_garbaged)
10601 clear_garbaged_frames ();
10602
10603 /* Build menubar and tool-bar items. */
10604 if (NILP (Vmemory_full))
10605 prepare_menu_bars ();
10606
10607 if (windows_or_buffers_changed)
10608 update_mode_lines++;
10609
10610 /* Detect case that we need to write or remove a star in the mode line. */
10611 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
10612 {
10613 w->update_mode_line = Qt;
10614 if (buffer_shared > 1)
10615 update_mode_lines++;
10616 }
10617
10618 /* If %c is in the mode line, update it if needed. */
10619 if (!NILP (w->column_number_displayed)
10620 /* This alternative quickly identifies a common case
10621 where no change is needed. */
10622 && !(PT == XFASTINT (w->last_point)
10623 && XFASTINT (w->last_modified) >= MODIFF
10624 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
10625 && (XFASTINT (w->column_number_displayed)
10626 != (int) current_column ())) /* iftc */
10627 w->update_mode_line = Qt;
10628
10629 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
10630
10631 /* The variable buffer_shared is set in redisplay_window and
10632 indicates that we redisplay a buffer in different windows. See
10633 there. */
10634 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
10635 || cursor_type_changed);
10636
10637 /* If specs for an arrow have changed, do thorough redisplay
10638 to ensure we remove any arrow that should no longer exist. */
10639 if (overlay_arrows_changed_p ())
10640 consider_all_windows_p = windows_or_buffers_changed = 1;
10641
10642 /* Normally the message* functions will have already displayed and
10643 updated the echo area, but the frame may have been trashed, or
10644 the update may have been preempted, so display the echo area
10645 again here. Checking message_cleared_p captures the case that
10646 the echo area should be cleared. */
10647 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
10648 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
10649 || (message_cleared_p
10650 && minibuf_level == 0
10651 /* If the mini-window is currently selected, this means the
10652 echo-area doesn't show through. */
10653 && !MINI_WINDOW_P (XWINDOW (selected_window))))
10654 {
10655 int window_height_changed_p = echo_area_display (0);
10656 must_finish = 1;
10657
10658 /* If we don't display the current message, don't clear the
10659 message_cleared_p flag, because, if we did, we wouldn't clear
10660 the echo area in the next redisplay which doesn't preserve
10661 the echo area. */
10662 if (!display_last_displayed_message_p)
10663 message_cleared_p = 0;
10664
10665 if (fonts_changed_p)
10666 goto retry;
10667 else if (window_height_changed_p)
10668 {
10669 consider_all_windows_p = 1;
10670 ++update_mode_lines;
10671 ++windows_or_buffers_changed;
10672
10673 /* If window configuration was changed, frames may have been
10674 marked garbaged. Clear them or we will experience
10675 surprises wrt scrolling. */
10676 if (frame_garbaged)
10677 clear_garbaged_frames ();
10678 }
10679 }
10680 else if (EQ (selected_window, minibuf_window)
10681 && (current_buffer->clip_changed
10682 || XFASTINT (w->last_modified) < MODIFF
10683 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10684 && resize_mini_window (w, 0))
10685 {
10686 /* Resized active mini-window to fit the size of what it is
10687 showing if its contents might have changed. */
10688 must_finish = 1;
10689 consider_all_windows_p = 1;
10690 ++windows_or_buffers_changed;
10691 ++update_mode_lines;
10692
10693 /* If window configuration was changed, frames may have been
10694 marked garbaged. Clear them or we will experience
10695 surprises wrt scrolling. */
10696 if (frame_garbaged)
10697 clear_garbaged_frames ();
10698 }
10699
10700
10701 /* If showing the region, and mark has changed, we must redisplay
10702 the whole window. The assignment to this_line_start_pos prevents
10703 the optimization directly below this if-statement. */
10704 if (((!NILP (Vtransient_mark_mode)
10705 && !NILP (XBUFFER (w->buffer)->mark_active))
10706 != !NILP (w->region_showing))
10707 || (!NILP (w->region_showing)
10708 && !EQ (w->region_showing,
10709 Fmarker_position (XBUFFER (w->buffer)->mark))))
10710 CHARPOS (this_line_start_pos) = 0;
10711
10712 /* Optimize the case that only the line containing the cursor in the
10713 selected window has changed. Variables starting with this_ are
10714 set in display_line and record information about the line
10715 containing the cursor. */
10716 tlbufpos = this_line_start_pos;
10717 tlendpos = this_line_end_pos;
10718 if (!consider_all_windows_p
10719 && CHARPOS (tlbufpos) > 0
10720 && NILP (w->update_mode_line)
10721 && !current_buffer->clip_changed
10722 && !current_buffer->prevent_redisplay_optimizations_p
10723 && FRAME_VISIBLE_P (XFRAME (w->frame))
10724 && !FRAME_OBSCURED_P (XFRAME (w->frame))
10725 /* Make sure recorded data applies to current buffer, etc. */
10726 && this_line_buffer == current_buffer
10727 && current_buffer == XBUFFER (w->buffer)
10728 && NILP (w->force_start)
10729 && NILP (w->optional_new_start)
10730 /* Point must be on the line that we have info recorded about. */
10731 && PT >= CHARPOS (tlbufpos)
10732 && PT <= Z - CHARPOS (tlendpos)
10733 /* All text outside that line, including its final newline,
10734 must be unchanged */
10735 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
10736 CHARPOS (tlendpos)))
10737 {
10738 if (CHARPOS (tlbufpos) > BEGV
10739 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
10740 && (CHARPOS (tlbufpos) == ZV
10741 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
10742 /* Former continuation line has disappeared by becoming empty */
10743 goto cancel;
10744 else if (XFASTINT (w->last_modified) < MODIFF
10745 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
10746 || MINI_WINDOW_P (w))
10747 {
10748 /* We have to handle the case of continuation around a
10749 wide-column character (See the comment in indent.c around
10750 line 885).
10751
10752 For instance, in the following case:
10753
10754 -------- Insert --------
10755 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10756 J_I_ ==> J_I_ `^^' are cursors.
10757 ^^ ^^
10758 -------- --------
10759
10760 As we have to redraw the line above, we should goto cancel. */
10761
10762 struct it it;
10763 int line_height_before = this_line_pixel_height;
10764
10765 /* Note that start_display will handle the case that the
10766 line starting at tlbufpos is a continuation lines. */
10767 start_display (&it, w, tlbufpos);
10768
10769 /* Implementation note: It this still necessary? */
10770 if (it.current_x != this_line_start_x)
10771 goto cancel;
10772
10773 TRACE ((stderr, "trying display optimization 1\n"));
10774 w->cursor.vpos = -1;
10775 overlay_arrow_seen = 0;
10776 it.vpos = this_line_vpos;
10777 it.current_y = this_line_y;
10778 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10779 display_line (&it);
10780
10781 /* If line contains point, is not continued,
10782 and ends at same distance from eob as before, we win */
10783 if (w->cursor.vpos >= 0
10784 /* Line is not continued, otherwise this_line_start_pos
10785 would have been set to 0 in display_line. */
10786 && CHARPOS (this_line_start_pos)
10787 /* Line ends as before. */
10788 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10789 /* Line has same height as before. Otherwise other lines
10790 would have to be shifted up or down. */
10791 && this_line_pixel_height == line_height_before)
10792 {
10793 /* If this is not the window's last line, we must adjust
10794 the charstarts of the lines below. */
10795 if (it.current_y < it.last_visible_y)
10796 {
10797 struct glyph_row *row
10798 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10799 int delta, delta_bytes;
10800
10801 if (Z - CHARPOS (tlendpos) == ZV)
10802 {
10803 /* This line ends at end of (accessible part of)
10804 buffer. There is no newline to count. */
10805 delta = (Z
10806 - CHARPOS (tlendpos)
10807 - MATRIX_ROW_START_CHARPOS (row));
10808 delta_bytes = (Z_BYTE
10809 - BYTEPOS (tlendpos)
10810 - MATRIX_ROW_START_BYTEPOS (row));
10811 }
10812 else
10813 {
10814 /* This line ends in a newline. Must take
10815 account of the newline and the rest of the
10816 text that follows. */
10817 delta = (Z
10818 - CHARPOS (tlendpos)
10819 - MATRIX_ROW_START_CHARPOS (row));
10820 delta_bytes = (Z_BYTE
10821 - BYTEPOS (tlendpos)
10822 - MATRIX_ROW_START_BYTEPOS (row));
10823 }
10824
10825 increment_matrix_positions (w->current_matrix,
10826 this_line_vpos + 1,
10827 w->current_matrix->nrows,
10828 delta, delta_bytes);
10829 }
10830
10831 /* If this row displays text now but previously didn't,
10832 or vice versa, w->window_end_vpos may have to be
10833 adjusted. */
10834 if ((it.glyph_row - 1)->displays_text_p)
10835 {
10836 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10837 XSETINT (w->window_end_vpos, this_line_vpos);
10838 }
10839 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10840 && this_line_vpos > 0)
10841 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10842 w->window_end_valid = Qnil;
10843
10844 /* Update hint: No need to try to scroll in update_window. */
10845 w->desired_matrix->no_scrolling_p = 1;
10846
10847 #if GLYPH_DEBUG
10848 *w->desired_matrix->method = 0;
10849 debug_method_add (w, "optimization 1");
10850 #endif
10851 #ifdef HAVE_WINDOW_SYSTEM
10852 update_window_fringes (w, 0);
10853 #endif
10854 goto update;
10855 }
10856 else
10857 goto cancel;
10858 }
10859 else if (/* Cursor position hasn't changed. */
10860 PT == XFASTINT (w->last_point)
10861 /* Make sure the cursor was last displayed
10862 in this window. Otherwise we have to reposition it. */
10863 && 0 <= w->cursor.vpos
10864 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10865 {
10866 if (!must_finish)
10867 {
10868 do_pending_window_change (1);
10869
10870 /* We used to always goto end_of_redisplay here, but this
10871 isn't enough if we have a blinking cursor. */
10872 if (w->cursor_off_p == w->last_cursor_off_p)
10873 goto end_of_redisplay;
10874 }
10875 goto update;
10876 }
10877 /* If highlighting the region, or if the cursor is in the echo area,
10878 then we can't just move the cursor. */
10879 else if (! (!NILP (Vtransient_mark_mode)
10880 && !NILP (current_buffer->mark_active))
10881 && (EQ (selected_window, current_buffer->last_selected_window)
10882 || highlight_nonselected_windows)
10883 && NILP (w->region_showing)
10884 && NILP (Vshow_trailing_whitespace)
10885 && !cursor_in_echo_area)
10886 {
10887 struct it it;
10888 struct glyph_row *row;
10889
10890 /* Skip from tlbufpos to PT and see where it is. Note that
10891 PT may be in invisible text. If so, we will end at the
10892 next visible position. */
10893 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10894 NULL, DEFAULT_FACE_ID);
10895 it.current_x = this_line_start_x;
10896 it.current_y = this_line_y;
10897 it.vpos = this_line_vpos;
10898
10899 /* The call to move_it_to stops in front of PT, but
10900 moves over before-strings. */
10901 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10902
10903 if (it.vpos == this_line_vpos
10904 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10905 row->enabled_p))
10906 {
10907 xassert (this_line_vpos == it.vpos);
10908 xassert (this_line_y == it.current_y);
10909 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10910 #if GLYPH_DEBUG
10911 *w->desired_matrix->method = 0;
10912 debug_method_add (w, "optimization 3");
10913 #endif
10914 goto update;
10915 }
10916 else
10917 goto cancel;
10918 }
10919
10920 cancel:
10921 /* Text changed drastically or point moved off of line. */
10922 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10923 }
10924
10925 CHARPOS (this_line_start_pos) = 0;
10926 consider_all_windows_p |= buffer_shared > 1;
10927 ++clear_face_cache_count;
10928 #ifdef HAVE_WINDOW_SYSTEM
10929 ++clear_image_cache_count;
10930 #endif
10931
10932 /* Build desired matrices, and update the display. If
10933 consider_all_windows_p is non-zero, do it for all windows on all
10934 frames. Otherwise do it for selected_window, only. */
10935
10936 if (consider_all_windows_p)
10937 {
10938 Lisp_Object tail, frame;
10939
10940 FOR_EACH_FRAME (tail, frame)
10941 XFRAME (frame)->updated_p = 0;
10942
10943 /* Recompute # windows showing selected buffer. This will be
10944 incremented each time such a window is displayed. */
10945 buffer_shared = 0;
10946
10947 FOR_EACH_FRAME (tail, frame)
10948 {
10949 struct frame *f = XFRAME (frame);
10950
10951 if (FRAME_WINDOW_P (f) || f == sf)
10952 {
10953 if (! EQ (frame, selected_frame))
10954 /* Select the frame, for the sake of frame-local
10955 variables. */
10956 select_frame_for_redisplay (frame);
10957
10958 /* Mark all the scroll bars to be removed; we'll redeem
10959 the ones we want when we redisplay their windows. */
10960 if (condemn_scroll_bars_hook)
10961 condemn_scroll_bars_hook (f);
10962
10963 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10964 redisplay_windows (FRAME_ROOT_WINDOW (f));
10965
10966 /* Any scroll bars which redisplay_windows should have
10967 nuked should now go away. */
10968 if (judge_scroll_bars_hook)
10969 judge_scroll_bars_hook (f);
10970
10971 /* If fonts changed, display again. */
10972 /* ??? rms: I suspect it is a mistake to jump all the way
10973 back to retry here. It should just retry this frame. */
10974 if (fonts_changed_p)
10975 goto retry;
10976
10977 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10978 {
10979 /* See if we have to hscroll. */
10980 if (!f->already_hscrolled_p)
10981 {
10982 f->already_hscrolled_p = 1;
10983 if (hscroll_windows (f->root_window))
10984 goto retry;
10985 }
10986
10987 /* Prevent various kinds of signals during display
10988 update. stdio is not robust about handling
10989 signals, which can cause an apparent I/O
10990 error. */
10991 if (interrupt_input)
10992 unrequest_sigio ();
10993 STOP_POLLING;
10994
10995 /* Update the display. */
10996 set_window_update_flags (XWINDOW (f->root_window), 1);
10997 pause |= update_frame (f, 0, 0);
10998 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10999 if (pause)
11000 break;
11001 #endif
11002
11003 f->updated_p = 1;
11004 }
11005 }
11006 }
11007
11008 if (!pause)
11009 {
11010 /* Do the mark_window_display_accurate after all windows have
11011 been redisplayed because this call resets flags in buffers
11012 which are needed for proper redisplay. */
11013 FOR_EACH_FRAME (tail, frame)
11014 {
11015 struct frame *f = XFRAME (frame);
11016 if (f->updated_p)
11017 {
11018 mark_window_display_accurate (f->root_window, 1);
11019 if (frame_up_to_date_hook)
11020 frame_up_to_date_hook (f);
11021 }
11022 }
11023 }
11024 }
11025 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11026 {
11027 Lisp_Object mini_window;
11028 struct frame *mini_frame;
11029
11030 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
11031 /* Use list_of_error, not Qerror, so that
11032 we catch only errors and don't run the debugger. */
11033 internal_condition_case_1 (redisplay_window_1, selected_window,
11034 list_of_error,
11035 redisplay_window_error);
11036
11037 /* Compare desired and current matrices, perform output. */
11038
11039 update:
11040 /* If fonts changed, display again. */
11041 if (fonts_changed_p)
11042 goto retry;
11043
11044 /* Prevent various kinds of signals during display update.
11045 stdio is not robust about handling signals,
11046 which can cause an apparent I/O error. */
11047 if (interrupt_input)
11048 unrequest_sigio ();
11049 STOP_POLLING;
11050
11051 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11052 {
11053 if (hscroll_windows (selected_window))
11054 goto retry;
11055
11056 XWINDOW (selected_window)->must_be_updated_p = 1;
11057 pause = update_frame (sf, 0, 0);
11058 }
11059
11060 /* We may have called echo_area_display at the top of this
11061 function. If the echo area is on another frame, that may
11062 have put text on a frame other than the selected one, so the
11063 above call to update_frame would not have caught it. Catch
11064 it here. */
11065 mini_window = FRAME_MINIBUF_WINDOW (sf);
11066 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
11067
11068 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
11069 {
11070 XWINDOW (mini_window)->must_be_updated_p = 1;
11071 pause |= update_frame (mini_frame, 0, 0);
11072 if (!pause && hscroll_windows (mini_window))
11073 goto retry;
11074 }
11075 }
11076
11077 /* If display was paused because of pending input, make sure we do a
11078 thorough update the next time. */
11079 if (pause)
11080 {
11081 /* Prevent the optimization at the beginning of
11082 redisplay_internal that tries a single-line update of the
11083 line containing the cursor in the selected window. */
11084 CHARPOS (this_line_start_pos) = 0;
11085
11086 /* Let the overlay arrow be updated the next time. */
11087 update_overlay_arrows (0);
11088
11089 /* If we pause after scrolling, some rows in the current
11090 matrices of some windows are not valid. */
11091 if (!WINDOW_FULL_WIDTH_P (w)
11092 && !FRAME_WINDOW_P (XFRAME (w->frame)))
11093 update_mode_lines = 1;
11094 }
11095 else
11096 {
11097 if (!consider_all_windows_p)
11098 {
11099 /* This has already been done above if
11100 consider_all_windows_p is set. */
11101 mark_window_display_accurate_1 (w, 1);
11102
11103 /* Say overlay arrows are up to date. */
11104 update_overlay_arrows (1);
11105
11106 if (frame_up_to_date_hook != 0)
11107 frame_up_to_date_hook (sf);
11108 }
11109
11110 update_mode_lines = 0;
11111 windows_or_buffers_changed = 0;
11112 cursor_type_changed = 0;
11113 }
11114
11115 /* Start SIGIO interrupts coming again. Having them off during the
11116 code above makes it less likely one will discard output, but not
11117 impossible, since there might be stuff in the system buffer here.
11118 But it is much hairier to try to do anything about that. */
11119 if (interrupt_input)
11120 request_sigio ();
11121 RESUME_POLLING;
11122
11123 /* If a frame has become visible which was not before, redisplay
11124 again, so that we display it. Expose events for such a frame
11125 (which it gets when becoming visible) don't call the parts of
11126 redisplay constructing glyphs, so simply exposing a frame won't
11127 display anything in this case. So, we have to display these
11128 frames here explicitly. */
11129 if (!pause)
11130 {
11131 Lisp_Object tail, frame;
11132 int new_count = 0;
11133
11134 FOR_EACH_FRAME (tail, frame)
11135 {
11136 int this_is_visible = 0;
11137
11138 if (XFRAME (frame)->visible)
11139 this_is_visible = 1;
11140 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
11141 if (XFRAME (frame)->visible)
11142 this_is_visible = 1;
11143
11144 if (this_is_visible)
11145 new_count++;
11146 }
11147
11148 if (new_count != number_of_visible_frames)
11149 windows_or_buffers_changed++;
11150 }
11151
11152 /* Change frame size now if a change is pending. */
11153 do_pending_window_change (1);
11154
11155 /* If we just did a pending size change, or have additional
11156 visible frames, redisplay again. */
11157 if (windows_or_buffers_changed && !pause)
11158 goto retry;
11159
11160 /* Clear the face cache eventually. */
11161 if (consider_all_windows_p)
11162 {
11163 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
11164 {
11165 clear_face_cache (0);
11166 clear_face_cache_count = 0;
11167 }
11168 #ifdef HAVE_WINDOW_SYSTEM
11169 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
11170 {
11171 Lisp_Object tail, frame;
11172 FOR_EACH_FRAME (tail, frame)
11173 {
11174 struct frame *f = XFRAME (frame);
11175 if (FRAME_WINDOW_P (f))
11176 clear_image_cache (f, 0);
11177 }
11178 clear_image_cache_count = 0;
11179 }
11180 #endif /* HAVE_WINDOW_SYSTEM */
11181 }
11182
11183 end_of_redisplay:
11184 unbind_to (count, Qnil);
11185 RESUME_POLLING;
11186 }
11187
11188
11189 /* Redisplay, but leave alone any recent echo area message unless
11190 another message has been requested in its place.
11191
11192 This is useful in situations where you need to redisplay but no
11193 user action has occurred, making it inappropriate for the message
11194 area to be cleared. See tracking_off and
11195 wait_reading_process_output for examples of these situations.
11196
11197 FROM_WHERE is an integer saying from where this function was
11198 called. This is useful for debugging. */
11199
11200 void
11201 redisplay_preserve_echo_area (from_where)
11202 int from_where;
11203 {
11204 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
11205
11206 if (!NILP (echo_area_buffer[1]))
11207 {
11208 /* We have a previously displayed message, but no current
11209 message. Redisplay the previous message. */
11210 display_last_displayed_message_p = 1;
11211 redisplay_internal (1);
11212 display_last_displayed_message_p = 0;
11213 }
11214 else
11215 redisplay_internal (1);
11216
11217 if (rif != NULL && rif->flush_display_optional)
11218 rif->flush_display_optional (NULL);
11219 }
11220
11221
11222 /* Function registered with record_unwind_protect in
11223 redisplay_internal. Reset redisplaying_p to the value it had
11224 before redisplay_internal was called, and clear
11225 prevent_freeing_realized_faces_p. It also selects the previously
11226 selected frame. */
11227
11228 static Lisp_Object
11229 unwind_redisplay (val)
11230 Lisp_Object val;
11231 {
11232 Lisp_Object old_redisplaying_p, old_frame;
11233
11234 old_redisplaying_p = XCAR (val);
11235 redisplaying_p = XFASTINT (old_redisplaying_p);
11236 old_frame = XCDR (val);
11237 if (! EQ (old_frame, selected_frame))
11238 select_frame_for_redisplay (old_frame);
11239 return Qnil;
11240 }
11241
11242
11243 /* Mark the display of window W as accurate or inaccurate. If
11244 ACCURATE_P is non-zero mark display of W as accurate. If
11245 ACCURATE_P is zero, arrange for W to be redisplayed the next time
11246 redisplay_internal is called. */
11247
11248 static void
11249 mark_window_display_accurate_1 (w, accurate_p)
11250 struct window *w;
11251 int accurate_p;
11252 {
11253 if (BUFFERP (w->buffer))
11254 {
11255 struct buffer *b = XBUFFER (w->buffer);
11256
11257 w->last_modified
11258 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
11259 w->last_overlay_modified
11260 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
11261 w->last_had_star
11262 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
11263
11264 if (accurate_p)
11265 {
11266 b->clip_changed = 0;
11267 b->prevent_redisplay_optimizations_p = 0;
11268
11269 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
11270 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
11271 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
11272 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
11273
11274 w->current_matrix->buffer = b;
11275 w->current_matrix->begv = BUF_BEGV (b);
11276 w->current_matrix->zv = BUF_ZV (b);
11277
11278 w->last_cursor = w->cursor;
11279 w->last_cursor_off_p = w->cursor_off_p;
11280
11281 if (w == XWINDOW (selected_window))
11282 w->last_point = make_number (BUF_PT (b));
11283 else
11284 w->last_point = make_number (XMARKER (w->pointm)->charpos);
11285 }
11286 }
11287
11288 if (accurate_p)
11289 {
11290 w->window_end_valid = w->buffer;
11291 #if 0 /* This is incorrect with variable-height lines. */
11292 xassert (XINT (w->window_end_vpos)
11293 < (WINDOW_TOTAL_LINES (w)
11294 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
11295 #endif
11296 w->update_mode_line = Qnil;
11297 }
11298 }
11299
11300
11301 /* Mark the display of windows in the window tree rooted at WINDOW as
11302 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
11303 windows as accurate. If ACCURATE_P is zero, arrange for windows to
11304 be redisplayed the next time redisplay_internal is called. */
11305
11306 void
11307 mark_window_display_accurate (window, accurate_p)
11308 Lisp_Object window;
11309 int accurate_p;
11310 {
11311 struct window *w;
11312
11313 for (; !NILP (window); window = w->next)
11314 {
11315 w = XWINDOW (window);
11316 mark_window_display_accurate_1 (w, accurate_p);
11317
11318 if (!NILP (w->vchild))
11319 mark_window_display_accurate (w->vchild, accurate_p);
11320 if (!NILP (w->hchild))
11321 mark_window_display_accurate (w->hchild, accurate_p);
11322 }
11323
11324 if (accurate_p)
11325 {
11326 update_overlay_arrows (1);
11327 }
11328 else
11329 {
11330 /* Force a thorough redisplay the next time by setting
11331 last_arrow_position and last_arrow_string to t, which is
11332 unequal to any useful value of Voverlay_arrow_... */
11333 update_overlay_arrows (-1);
11334 }
11335 }
11336
11337
11338 /* Return value in display table DP (Lisp_Char_Table *) for character
11339 C. Since a display table doesn't have any parent, we don't have to
11340 follow parent. Do not call this function directly but use the
11341 macro DISP_CHAR_VECTOR. */
11342
11343 Lisp_Object
11344 disp_char_vector (dp, c)
11345 struct Lisp_Char_Table *dp;
11346 int c;
11347 {
11348 int code[4], i;
11349 Lisp_Object val;
11350
11351 if (SINGLE_BYTE_CHAR_P (c))
11352 return (dp->contents[c]);
11353
11354 SPLIT_CHAR (c, code[0], code[1], code[2]);
11355 if (code[1] < 32)
11356 code[1] = -1;
11357 else if (code[2] < 32)
11358 code[2] = -1;
11359
11360 /* Here, the possible range of code[0] (== charset ID) is
11361 128..max_charset. Since the top level char table contains data
11362 for multibyte characters after 256th element, we must increment
11363 code[0] by 128 to get a correct index. */
11364 code[0] += 128;
11365 code[3] = -1; /* anchor */
11366
11367 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
11368 {
11369 val = dp->contents[code[i]];
11370 if (!SUB_CHAR_TABLE_P (val))
11371 return (NILP (val) ? dp->defalt : val);
11372 }
11373
11374 /* Here, val is a sub char table. We return the default value of
11375 it. */
11376 return (dp->defalt);
11377 }
11378
11379
11380 \f
11381 /***********************************************************************
11382 Window Redisplay
11383 ***********************************************************************/
11384
11385 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
11386
11387 static void
11388 redisplay_windows (window)
11389 Lisp_Object window;
11390 {
11391 while (!NILP (window))
11392 {
11393 struct window *w = XWINDOW (window);
11394
11395 if (!NILP (w->hchild))
11396 redisplay_windows (w->hchild);
11397 else if (!NILP (w->vchild))
11398 redisplay_windows (w->vchild);
11399 else
11400 {
11401 displayed_buffer = XBUFFER (w->buffer);
11402 /* Use list_of_error, not Qerror, so that
11403 we catch only errors and don't run the debugger. */
11404 internal_condition_case_1 (redisplay_window_0, window,
11405 list_of_error,
11406 redisplay_window_error);
11407 }
11408
11409 window = w->next;
11410 }
11411 }
11412
11413 static Lisp_Object
11414 redisplay_window_error ()
11415 {
11416 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
11417 return Qnil;
11418 }
11419
11420 static Lisp_Object
11421 redisplay_window_0 (window)
11422 Lisp_Object window;
11423 {
11424 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11425 redisplay_window (window, 0);
11426 return Qnil;
11427 }
11428
11429 static Lisp_Object
11430 redisplay_window_1 (window)
11431 Lisp_Object window;
11432 {
11433 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11434 redisplay_window (window, 1);
11435 return Qnil;
11436 }
11437 \f
11438
11439 /* Increment GLYPH until it reaches END or CONDITION fails while
11440 adding (GLYPH)->pixel_width to X. */
11441
11442 #define SKIP_GLYPHS(glyph, end, x, condition) \
11443 do \
11444 { \
11445 (x) += (glyph)->pixel_width; \
11446 ++(glyph); \
11447 } \
11448 while ((glyph) < (end) && (condition))
11449
11450
11451 /* Set cursor position of W. PT is assumed to be displayed in ROW.
11452 DELTA is the number of bytes by which positions recorded in ROW
11453 differ from current buffer positions. */
11454
11455 void
11456 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
11457 struct window *w;
11458 struct glyph_row *row;
11459 struct glyph_matrix *matrix;
11460 int delta, delta_bytes, dy, dvpos;
11461 {
11462 struct glyph *glyph = row->glyphs[TEXT_AREA];
11463 struct glyph *end = glyph + row->used[TEXT_AREA];
11464 struct glyph *cursor = NULL;
11465 /* The first glyph that starts a sequence of glyphs from string. */
11466 struct glyph *string_start;
11467 /* The X coordinate of string_start. */
11468 int string_start_x;
11469 /* The last known character position. */
11470 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
11471 /* The last known character position before string_start. */
11472 int string_before_pos;
11473 int x = row->x;
11474 int cursor_x = x;
11475 int cursor_from_overlay_pos = 0;
11476 int pt_old = PT - delta;
11477
11478 /* Skip over glyphs not having an object at the start of the row.
11479 These are special glyphs like truncation marks on terminal
11480 frames. */
11481 if (row->displays_text_p)
11482 while (glyph < end
11483 && INTEGERP (glyph->object)
11484 && glyph->charpos < 0)
11485 {
11486 x += glyph->pixel_width;
11487 ++glyph;
11488 }
11489
11490 string_start = NULL;
11491 while (glyph < end
11492 && !INTEGERP (glyph->object)
11493 && (!BUFFERP (glyph->object)
11494 || (last_pos = glyph->charpos) < pt_old))
11495 {
11496 if (! STRINGP (glyph->object))
11497 {
11498 string_start = NULL;
11499 x += glyph->pixel_width;
11500 ++glyph;
11501 if (cursor_from_overlay_pos
11502 && last_pos > cursor_from_overlay_pos)
11503 {
11504 cursor_from_overlay_pos = 0;
11505 cursor = 0;
11506 }
11507 }
11508 else
11509 {
11510 string_before_pos = last_pos;
11511 string_start = glyph;
11512 string_start_x = x;
11513 /* Skip all glyphs from string. */
11514 do
11515 {
11516 int pos;
11517 if ((cursor == NULL || glyph > cursor)
11518 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
11519 Qcursor, (glyph)->object))
11520 && (pos = string_buffer_position (w, glyph->object,
11521 string_before_pos),
11522 (pos == 0 /* From overlay */
11523 || pos == pt_old)))
11524 {
11525 /* Estimate overlay buffer position from the buffer
11526 positions of the glyphs before and after the overlay.
11527 Add 1 to last_pos so that if point corresponds to the
11528 glyph right after the overlay, we still use a 'cursor'
11529 property found in that overlay. */
11530 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
11531 cursor = glyph;
11532 cursor_x = x;
11533 }
11534 x += glyph->pixel_width;
11535 ++glyph;
11536 }
11537 while (glyph < end && STRINGP (glyph->object));
11538 }
11539 }
11540
11541 if (cursor != NULL)
11542 {
11543 glyph = cursor;
11544 x = cursor_x;
11545 }
11546 else if (row->ends_in_ellipsis_p && glyph == end)
11547 {
11548 /* Scan back over the ellipsis glyphs, decrementing positions. */
11549 while (glyph > row->glyphs[TEXT_AREA]
11550 && (glyph - 1)->charpos == last_pos)
11551 glyph--, x -= glyph->pixel_width;
11552 /* That loop always goes one position too far,
11553 including the glyph before the ellipsis.
11554 So scan forward over that one. */
11555 x += glyph->pixel_width;
11556 glyph++;
11557 }
11558 else if (string_start
11559 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
11560 {
11561 /* We may have skipped over point because the previous glyphs
11562 are from string. As there's no easy way to know the
11563 character position of the current glyph, find the correct
11564 glyph on point by scanning from string_start again. */
11565 Lisp_Object limit;
11566 Lisp_Object string;
11567 int pos;
11568
11569 limit = make_number (pt_old + 1);
11570 end = glyph;
11571 glyph = string_start;
11572 x = string_start_x;
11573 string = glyph->object;
11574 pos = string_buffer_position (w, string, string_before_pos);
11575 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11576 because we always put cursor after overlay strings. */
11577 while (pos == 0 && glyph < end)
11578 {
11579 string = glyph->object;
11580 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11581 if (glyph < end)
11582 pos = string_buffer_position (w, glyph->object, string_before_pos);
11583 }
11584
11585 while (glyph < end)
11586 {
11587 pos = XINT (Fnext_single_char_property_change
11588 (make_number (pos), Qdisplay, Qnil, limit));
11589 if (pos > pt_old)
11590 break;
11591 /* Skip glyphs from the same string. */
11592 string = glyph->object;
11593 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11594 /* Skip glyphs from an overlay. */
11595 while (glyph < end
11596 && ! string_buffer_position (w, glyph->object, pos))
11597 {
11598 string = glyph->object;
11599 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11600 }
11601 }
11602 }
11603
11604 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
11605 w->cursor.x = x;
11606 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
11607 w->cursor.y = row->y + dy;
11608
11609 if (w == XWINDOW (selected_window))
11610 {
11611 if (!row->continued_p
11612 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
11613 && row->x == 0)
11614 {
11615 this_line_buffer = XBUFFER (w->buffer);
11616
11617 CHARPOS (this_line_start_pos)
11618 = MATRIX_ROW_START_CHARPOS (row) + delta;
11619 BYTEPOS (this_line_start_pos)
11620 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
11621
11622 CHARPOS (this_line_end_pos)
11623 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
11624 BYTEPOS (this_line_end_pos)
11625 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
11626
11627 this_line_y = w->cursor.y;
11628 this_line_pixel_height = row->height;
11629 this_line_vpos = w->cursor.vpos;
11630 this_line_start_x = row->x;
11631 }
11632 else
11633 CHARPOS (this_line_start_pos) = 0;
11634 }
11635 }
11636
11637
11638 /* Run window scroll functions, if any, for WINDOW with new window
11639 start STARTP. Sets the window start of WINDOW to that position.
11640
11641 We assume that the window's buffer is really current. */
11642
11643 static INLINE struct text_pos
11644 run_window_scroll_functions (window, startp)
11645 Lisp_Object window;
11646 struct text_pos startp;
11647 {
11648 struct window *w = XWINDOW (window);
11649 SET_MARKER_FROM_TEXT_POS (w->start, startp);
11650
11651 if (current_buffer != XBUFFER (w->buffer))
11652 abort ();
11653
11654 if (!NILP (Vwindow_scroll_functions))
11655 {
11656 run_hook_with_args_2 (Qwindow_scroll_functions, window,
11657 make_number (CHARPOS (startp)));
11658 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11659 /* In case the hook functions switch buffers. */
11660 if (current_buffer != XBUFFER (w->buffer))
11661 set_buffer_internal_1 (XBUFFER (w->buffer));
11662 }
11663
11664 return startp;
11665 }
11666
11667
11668 /* Make sure the line containing the cursor is fully visible.
11669 A value of 1 means there is nothing to be done.
11670 (Either the line is fully visible, or it cannot be made so,
11671 or we cannot tell.)
11672
11673 If FORCE_P is non-zero, return 0 even if partial visible cursor row
11674 is higher than window.
11675
11676 A value of 0 means the caller should do scrolling
11677 as if point had gone off the screen. */
11678
11679 static int
11680 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
11681 struct window *w;
11682 int force_p;
11683 int current_matrix_p;
11684 {
11685 struct glyph_matrix *matrix;
11686 struct glyph_row *row;
11687 int window_height;
11688
11689 if (!make_cursor_line_fully_visible_p)
11690 return 1;
11691
11692 /* It's not always possible to find the cursor, e.g, when a window
11693 is full of overlay strings. Don't do anything in that case. */
11694 if (w->cursor.vpos < 0)
11695 return 1;
11696
11697 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
11698 row = MATRIX_ROW (matrix, w->cursor.vpos);
11699
11700 /* If the cursor row is not partially visible, there's nothing to do. */
11701 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
11702 return 1;
11703
11704 /* If the row the cursor is in is taller than the window's height,
11705 it's not clear what to do, so do nothing. */
11706 window_height = window_box_height (w);
11707 if (row->height >= window_height)
11708 {
11709 if (!force_p || MINI_WINDOW_P (w) || w->vscroll)
11710 return 1;
11711 }
11712 return 0;
11713
11714 #if 0
11715 /* This code used to try to scroll the window just enough to make
11716 the line visible. It returned 0 to say that the caller should
11717 allocate larger glyph matrices. */
11718
11719 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
11720 {
11721 int dy = row->height - row->visible_height;
11722 w->vscroll = 0;
11723 w->cursor.y += dy;
11724 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11725 }
11726 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11727 {
11728 int dy = - (row->height - row->visible_height);
11729 w->vscroll = dy;
11730 w->cursor.y += dy;
11731 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11732 }
11733
11734 /* When we change the cursor y-position of the selected window,
11735 change this_line_y as well so that the display optimization for
11736 the cursor line of the selected window in redisplay_internal uses
11737 the correct y-position. */
11738 if (w == XWINDOW (selected_window))
11739 this_line_y = w->cursor.y;
11740
11741 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11742 redisplay with larger matrices. */
11743 if (matrix->nrows < required_matrix_height (w))
11744 {
11745 fonts_changed_p = 1;
11746 return 0;
11747 }
11748
11749 return 1;
11750 #endif /* 0 */
11751 }
11752
11753
11754 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11755 non-zero means only WINDOW is redisplayed in redisplay_internal.
11756 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11757 in redisplay_window to bring a partially visible line into view in
11758 the case that only the cursor has moved.
11759
11760 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11761 last screen line's vertical height extends past the end of the screen.
11762
11763 Value is
11764
11765 1 if scrolling succeeded
11766
11767 0 if scrolling didn't find point.
11768
11769 -1 if new fonts have been loaded so that we must interrupt
11770 redisplay, adjust glyph matrices, and try again. */
11771
11772 enum
11773 {
11774 SCROLLING_SUCCESS,
11775 SCROLLING_FAILED,
11776 SCROLLING_NEED_LARGER_MATRICES
11777 };
11778
11779 static int
11780 try_scrolling (window, just_this_one_p, scroll_conservatively,
11781 scroll_step, temp_scroll_step, last_line_misfit)
11782 Lisp_Object window;
11783 int just_this_one_p;
11784 EMACS_INT scroll_conservatively, scroll_step;
11785 int temp_scroll_step;
11786 int last_line_misfit;
11787 {
11788 struct window *w = XWINDOW (window);
11789 struct frame *f = XFRAME (w->frame);
11790 struct text_pos scroll_margin_pos;
11791 struct text_pos pos;
11792 struct text_pos startp;
11793 struct it it;
11794 Lisp_Object window_end;
11795 int this_scroll_margin;
11796 int dy = 0;
11797 int scroll_max;
11798 int rc;
11799 int amount_to_scroll = 0;
11800 Lisp_Object aggressive;
11801 int height;
11802 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
11803
11804 #if GLYPH_DEBUG
11805 debug_method_add (w, "try_scrolling");
11806 #endif
11807
11808 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11809
11810 /* Compute scroll margin height in pixels. We scroll when point is
11811 within this distance from the top or bottom of the window. */
11812 if (scroll_margin > 0)
11813 {
11814 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11815 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11816 }
11817 else
11818 this_scroll_margin = 0;
11819
11820 /* Force scroll_conservatively to have a reasonable value so it doesn't
11821 cause an overflow while computing how much to scroll. */
11822 if (scroll_conservatively)
11823 scroll_conservatively = min (scroll_conservatively,
11824 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11825
11826 /* Compute how much we should try to scroll maximally to bring point
11827 into view. */
11828 if (scroll_step || scroll_conservatively || temp_scroll_step)
11829 scroll_max = max (scroll_step,
11830 max (scroll_conservatively, temp_scroll_step));
11831 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11832 || NUMBERP (current_buffer->scroll_up_aggressively))
11833 /* We're trying to scroll because of aggressive scrolling
11834 but no scroll_step is set. Choose an arbitrary one. Maybe
11835 there should be a variable for this. */
11836 scroll_max = 10;
11837 else
11838 scroll_max = 0;
11839 scroll_max *= FRAME_LINE_HEIGHT (f);
11840
11841 /* Decide whether we have to scroll down. Start at the window end
11842 and move this_scroll_margin up to find the position of the scroll
11843 margin. */
11844 window_end = Fwindow_end (window, Qt);
11845
11846 too_near_end:
11847
11848 CHARPOS (scroll_margin_pos) = XINT (window_end);
11849 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11850
11851 if (this_scroll_margin || extra_scroll_margin_lines)
11852 {
11853 start_display (&it, w, scroll_margin_pos);
11854 if (this_scroll_margin)
11855 move_it_vertically_backward (&it, this_scroll_margin);
11856 if (extra_scroll_margin_lines)
11857 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11858 scroll_margin_pos = it.current.pos;
11859 }
11860
11861 if (PT >= CHARPOS (scroll_margin_pos))
11862 {
11863 int y0;
11864
11865 /* Point is in the scroll margin at the bottom of the window, or
11866 below. Compute a new window start that makes point visible. */
11867
11868 /* Compute the distance from the scroll margin to PT.
11869 Give up if the distance is greater than scroll_max. */
11870 start_display (&it, w, scroll_margin_pos);
11871 y0 = it.current_y;
11872 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11873 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11874
11875 /* To make point visible, we have to move the window start
11876 down so that the line the cursor is in is visible, which
11877 means we have to add in the height of the cursor line. */
11878 dy = line_bottom_y (&it) - y0;
11879
11880 if (dy > scroll_max)
11881 return SCROLLING_FAILED;
11882
11883 /* Move the window start down. If scrolling conservatively,
11884 move it just enough down to make point visible. If
11885 scroll_step is set, move it down by scroll_step. */
11886 start_display (&it, w, startp);
11887
11888 if (scroll_conservatively)
11889 /* Set AMOUNT_TO_SCROLL to at least one line,
11890 and at most scroll_conservatively lines. */
11891 amount_to_scroll
11892 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11893 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11894 else if (scroll_step || temp_scroll_step)
11895 amount_to_scroll = scroll_max;
11896 else
11897 {
11898 aggressive = current_buffer->scroll_up_aggressively;
11899 height = WINDOW_BOX_TEXT_HEIGHT (w);
11900 if (NUMBERP (aggressive))
11901 {
11902 double float_amount = XFLOATINT (aggressive) * height;
11903 amount_to_scroll = float_amount;
11904 if (amount_to_scroll == 0 && float_amount > 0)
11905 amount_to_scroll = 1;
11906 }
11907 }
11908
11909 if (amount_to_scroll <= 0)
11910 return SCROLLING_FAILED;
11911
11912 /* If moving by amount_to_scroll leaves STARTP unchanged,
11913 move it down one screen line. */
11914
11915 move_it_vertically (&it, amount_to_scroll);
11916 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11917 move_it_by_lines (&it, 1, 1);
11918 startp = it.current.pos;
11919 }
11920 else
11921 {
11922 /* See if point is inside the scroll margin at the top of the
11923 window. */
11924 scroll_margin_pos = startp;
11925 if (this_scroll_margin)
11926 {
11927 start_display (&it, w, startp);
11928 move_it_vertically (&it, this_scroll_margin);
11929 scroll_margin_pos = it.current.pos;
11930 }
11931
11932 if (PT < CHARPOS (scroll_margin_pos))
11933 {
11934 /* Point is in the scroll margin at the top of the window or
11935 above what is displayed in the window. */
11936 int y0;
11937
11938 /* Compute the vertical distance from PT to the scroll
11939 margin position. Give up if distance is greater than
11940 scroll_max. */
11941 SET_TEXT_POS (pos, PT, PT_BYTE);
11942 start_display (&it, w, pos);
11943 y0 = it.current_y;
11944 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11945 it.last_visible_y, -1,
11946 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11947 dy = it.current_y - y0;
11948 if (dy > scroll_max)
11949 return SCROLLING_FAILED;
11950
11951 /* Compute new window start. */
11952 start_display (&it, w, startp);
11953
11954 if (scroll_conservatively)
11955 amount_to_scroll
11956 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11957 else if (scroll_step || temp_scroll_step)
11958 amount_to_scroll = scroll_max;
11959 else
11960 {
11961 aggressive = current_buffer->scroll_down_aggressively;
11962 height = WINDOW_BOX_TEXT_HEIGHT (w);
11963 if (NUMBERP (aggressive))
11964 {
11965 double float_amount = XFLOATINT (aggressive) * height;
11966 amount_to_scroll = float_amount;
11967 if (amount_to_scroll == 0 && float_amount > 0)
11968 amount_to_scroll = 1;
11969 }
11970 }
11971
11972 if (amount_to_scroll <= 0)
11973 return SCROLLING_FAILED;
11974
11975 move_it_vertically_backward (&it, amount_to_scroll);
11976 startp = it.current.pos;
11977 }
11978 }
11979
11980 /* Run window scroll functions. */
11981 startp = run_window_scroll_functions (window, startp);
11982
11983 /* Display the window. Give up if new fonts are loaded, or if point
11984 doesn't appear. */
11985 if (!try_window (window, startp, 0))
11986 rc = SCROLLING_NEED_LARGER_MATRICES;
11987 else if (w->cursor.vpos < 0)
11988 {
11989 clear_glyph_matrix (w->desired_matrix);
11990 rc = SCROLLING_FAILED;
11991 }
11992 else
11993 {
11994 /* Maybe forget recorded base line for line number display. */
11995 if (!just_this_one_p
11996 || current_buffer->clip_changed
11997 || BEG_UNCHANGED < CHARPOS (startp))
11998 w->base_line_number = Qnil;
11999
12000 /* If cursor ends up on a partially visible line,
12001 treat that as being off the bottom of the screen. */
12002 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
12003 {
12004 clear_glyph_matrix (w->desired_matrix);
12005 ++extra_scroll_margin_lines;
12006 goto too_near_end;
12007 }
12008 rc = SCROLLING_SUCCESS;
12009 }
12010
12011 return rc;
12012 }
12013
12014
12015 /* Compute a suitable window start for window W if display of W starts
12016 on a continuation line. Value is non-zero if a new window start
12017 was computed.
12018
12019 The new window start will be computed, based on W's width, starting
12020 from the start of the continued line. It is the start of the
12021 screen line with the minimum distance from the old start W->start. */
12022
12023 static int
12024 compute_window_start_on_continuation_line (w)
12025 struct window *w;
12026 {
12027 struct text_pos pos, start_pos;
12028 int window_start_changed_p = 0;
12029
12030 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
12031
12032 /* If window start is on a continuation line... Window start may be
12033 < BEGV in case there's invisible text at the start of the
12034 buffer (M-x rmail, for example). */
12035 if (CHARPOS (start_pos) > BEGV
12036 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
12037 {
12038 struct it it;
12039 struct glyph_row *row;
12040
12041 /* Handle the case that the window start is out of range. */
12042 if (CHARPOS (start_pos) < BEGV)
12043 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
12044 else if (CHARPOS (start_pos) > ZV)
12045 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
12046
12047 /* Find the start of the continued line. This should be fast
12048 because scan_buffer is fast (newline cache). */
12049 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
12050 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
12051 row, DEFAULT_FACE_ID);
12052 reseat_at_previous_visible_line_start (&it);
12053
12054 /* If the line start is "too far" away from the window start,
12055 say it takes too much time to compute a new window start. */
12056 if (CHARPOS (start_pos) - IT_CHARPOS (it)
12057 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
12058 {
12059 int min_distance, distance;
12060
12061 /* Move forward by display lines to find the new window
12062 start. If window width was enlarged, the new start can
12063 be expected to be > the old start. If window width was
12064 decreased, the new window start will be < the old start.
12065 So, we're looking for the display line start with the
12066 minimum distance from the old window start. */
12067 pos = it.current.pos;
12068 min_distance = INFINITY;
12069 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
12070 distance < min_distance)
12071 {
12072 min_distance = distance;
12073 pos = it.current.pos;
12074 move_it_by_lines (&it, 1, 0);
12075 }
12076
12077 /* Set the window start there. */
12078 SET_MARKER_FROM_TEXT_POS (w->start, pos);
12079 window_start_changed_p = 1;
12080 }
12081 }
12082
12083 return window_start_changed_p;
12084 }
12085
12086
12087 /* Try cursor movement in case text has not changed in window WINDOW,
12088 with window start STARTP. Value is
12089
12090 CURSOR_MOVEMENT_SUCCESS if successful
12091
12092 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
12093
12094 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
12095 display. *SCROLL_STEP is set to 1, under certain circumstances, if
12096 we want to scroll as if scroll-step were set to 1. See the code.
12097
12098 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
12099 which case we have to abort this redisplay, and adjust matrices
12100 first. */
12101
12102 enum
12103 {
12104 CURSOR_MOVEMENT_SUCCESS,
12105 CURSOR_MOVEMENT_CANNOT_BE_USED,
12106 CURSOR_MOVEMENT_MUST_SCROLL,
12107 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
12108 };
12109
12110 static int
12111 try_cursor_movement (window, startp, scroll_step)
12112 Lisp_Object window;
12113 struct text_pos startp;
12114 int *scroll_step;
12115 {
12116 struct window *w = XWINDOW (window);
12117 struct frame *f = XFRAME (w->frame);
12118 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
12119
12120 #if GLYPH_DEBUG
12121 if (inhibit_try_cursor_movement)
12122 return rc;
12123 #endif
12124
12125 /* Handle case where text has not changed, only point, and it has
12126 not moved off the frame. */
12127 if (/* Point may be in this window. */
12128 PT >= CHARPOS (startp)
12129 /* Selective display hasn't changed. */
12130 && !current_buffer->clip_changed
12131 /* Function force-mode-line-update is used to force a thorough
12132 redisplay. It sets either windows_or_buffers_changed or
12133 update_mode_lines. So don't take a shortcut here for these
12134 cases. */
12135 && !update_mode_lines
12136 && !windows_or_buffers_changed
12137 && !cursor_type_changed
12138 /* Can't use this case if highlighting a region. When a
12139 region exists, cursor movement has to do more than just
12140 set the cursor. */
12141 && !(!NILP (Vtransient_mark_mode)
12142 && !NILP (current_buffer->mark_active))
12143 && NILP (w->region_showing)
12144 && NILP (Vshow_trailing_whitespace)
12145 /* Right after splitting windows, last_point may be nil. */
12146 && INTEGERP (w->last_point)
12147 /* This code is not used for mini-buffer for the sake of the case
12148 of redisplaying to replace an echo area message; since in
12149 that case the mini-buffer contents per se are usually
12150 unchanged. This code is of no real use in the mini-buffer
12151 since the handling of this_line_start_pos, etc., in redisplay
12152 handles the same cases. */
12153 && !EQ (window, minibuf_window)
12154 /* When splitting windows or for new windows, it happens that
12155 redisplay is called with a nil window_end_vpos or one being
12156 larger than the window. This should really be fixed in
12157 window.c. I don't have this on my list, now, so we do
12158 approximately the same as the old redisplay code. --gerd. */
12159 && INTEGERP (w->window_end_vpos)
12160 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
12161 && (FRAME_WINDOW_P (f)
12162 || !overlay_arrow_in_current_buffer_p ()))
12163 {
12164 int this_scroll_margin, top_scroll_margin;
12165 struct glyph_row *row = NULL;
12166
12167 #if GLYPH_DEBUG
12168 debug_method_add (w, "cursor movement");
12169 #endif
12170
12171 /* Scroll if point within this distance from the top or bottom
12172 of the window. This is a pixel value. */
12173 this_scroll_margin = max (0, scroll_margin);
12174 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12175 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12176
12177 top_scroll_margin = this_scroll_margin;
12178 if (WINDOW_WANTS_HEADER_LINE_P (w))
12179 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
12180
12181 /* Start with the row the cursor was displayed during the last
12182 not paused redisplay. Give up if that row is not valid. */
12183 if (w->last_cursor.vpos < 0
12184 || w->last_cursor.vpos >= w->current_matrix->nrows)
12185 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12186 else
12187 {
12188 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
12189 if (row->mode_line_p)
12190 ++row;
12191 if (!row->enabled_p)
12192 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12193 }
12194
12195 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
12196 {
12197 int scroll_p = 0;
12198 int last_y = window_text_bottom_y (w) - this_scroll_margin;
12199
12200 if (PT > XFASTINT (w->last_point))
12201 {
12202 /* Point has moved forward. */
12203 while (MATRIX_ROW_END_CHARPOS (row) < PT
12204 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
12205 {
12206 xassert (row->enabled_p);
12207 ++row;
12208 }
12209
12210 /* The end position of a row equals the start position
12211 of the next row. If PT is there, we would rather
12212 display it in the next line. */
12213 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12214 && MATRIX_ROW_END_CHARPOS (row) == PT
12215 && !cursor_row_p (w, row))
12216 ++row;
12217
12218 /* If within the scroll margin, scroll. Note that
12219 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
12220 the next line would be drawn, and that
12221 this_scroll_margin can be zero. */
12222 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
12223 || PT > MATRIX_ROW_END_CHARPOS (row)
12224 /* Line is completely visible last line in window
12225 and PT is to be set in the next line. */
12226 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
12227 && PT == MATRIX_ROW_END_CHARPOS (row)
12228 && !row->ends_at_zv_p
12229 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12230 scroll_p = 1;
12231 }
12232 else if (PT < XFASTINT (w->last_point))
12233 {
12234 /* Cursor has to be moved backward. Note that PT >=
12235 CHARPOS (startp) because of the outer if-statement. */
12236 while (!row->mode_line_p
12237 && (MATRIX_ROW_START_CHARPOS (row) > PT
12238 || (MATRIX_ROW_START_CHARPOS (row) == PT
12239 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
12240 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
12241 row > w->current_matrix->rows
12242 && (row-1)->ends_in_newline_from_string_p))))
12243 && (row->y > top_scroll_margin
12244 || CHARPOS (startp) == BEGV))
12245 {
12246 xassert (row->enabled_p);
12247 --row;
12248 }
12249
12250 /* Consider the following case: Window starts at BEGV,
12251 there is invisible, intangible text at BEGV, so that
12252 display starts at some point START > BEGV. It can
12253 happen that we are called with PT somewhere between
12254 BEGV and START. Try to handle that case. */
12255 if (row < w->current_matrix->rows
12256 || row->mode_line_p)
12257 {
12258 row = w->current_matrix->rows;
12259 if (row->mode_line_p)
12260 ++row;
12261 }
12262
12263 /* Due to newlines in overlay strings, we may have to
12264 skip forward over overlay strings. */
12265 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12266 && MATRIX_ROW_END_CHARPOS (row) == PT
12267 && !cursor_row_p (w, row))
12268 ++row;
12269
12270 /* If within the scroll margin, scroll. */
12271 if (row->y < top_scroll_margin
12272 && CHARPOS (startp) != BEGV)
12273 scroll_p = 1;
12274 }
12275 else
12276 {
12277 /* Cursor did not move. So don't scroll even if cursor line
12278 is partially visible, as it was so before. */
12279 rc = CURSOR_MOVEMENT_SUCCESS;
12280 }
12281
12282 if (PT < MATRIX_ROW_START_CHARPOS (row)
12283 || PT > MATRIX_ROW_END_CHARPOS (row))
12284 {
12285 /* if PT is not in the glyph row, give up. */
12286 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12287 }
12288 else if (rc != CURSOR_MOVEMENT_SUCCESS
12289 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
12290 && make_cursor_line_fully_visible_p)
12291 {
12292 if (PT == MATRIX_ROW_END_CHARPOS (row)
12293 && !row->ends_at_zv_p
12294 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
12295 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12296 else if (row->height > window_box_height (w))
12297 {
12298 /* If we end up in a partially visible line, let's
12299 make it fully visible, except when it's taller
12300 than the window, in which case we can't do much
12301 about it. */
12302 *scroll_step = 1;
12303 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12304 }
12305 else
12306 {
12307 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12308 if (!cursor_row_fully_visible_p (w, 0, 1))
12309 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12310 else
12311 rc = CURSOR_MOVEMENT_SUCCESS;
12312 }
12313 }
12314 else if (scroll_p)
12315 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12316 else
12317 {
12318 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12319 rc = CURSOR_MOVEMENT_SUCCESS;
12320 }
12321 }
12322 }
12323
12324 return rc;
12325 }
12326
12327 void
12328 set_vertical_scroll_bar (w)
12329 struct window *w;
12330 {
12331 int start, end, whole;
12332
12333 /* Calculate the start and end positions for the current window.
12334 At some point, it would be nice to choose between scrollbars
12335 which reflect the whole buffer size, with special markers
12336 indicating narrowing, and scrollbars which reflect only the
12337 visible region.
12338
12339 Note that mini-buffers sometimes aren't displaying any text. */
12340 if (!MINI_WINDOW_P (w)
12341 || (w == XWINDOW (minibuf_window)
12342 && NILP (echo_area_buffer[0])))
12343 {
12344 struct buffer *buf = XBUFFER (w->buffer);
12345 whole = BUF_ZV (buf) - BUF_BEGV (buf);
12346 start = marker_position (w->start) - BUF_BEGV (buf);
12347 /* I don't think this is guaranteed to be right. For the
12348 moment, we'll pretend it is. */
12349 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
12350
12351 if (end < start)
12352 end = start;
12353 if (whole < (end - start))
12354 whole = end - start;
12355 }
12356 else
12357 start = end = whole = 0;
12358
12359 /* Indicate what this scroll bar ought to be displaying now. */
12360 set_vertical_scroll_bar_hook (w, end - start, whole, start);
12361 }
12362
12363
12364 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
12365 selected_window is redisplayed.
12366
12367 We can return without actually redisplaying the window if
12368 fonts_changed_p is nonzero. In that case, redisplay_internal will
12369 retry. */
12370
12371 static void
12372 redisplay_window (window, just_this_one_p)
12373 Lisp_Object window;
12374 int just_this_one_p;
12375 {
12376 struct window *w = XWINDOW (window);
12377 struct frame *f = XFRAME (w->frame);
12378 struct buffer *buffer = XBUFFER (w->buffer);
12379 struct buffer *old = current_buffer;
12380 struct text_pos lpoint, opoint, startp;
12381 int update_mode_line;
12382 int tem;
12383 struct it it;
12384 /* Record it now because it's overwritten. */
12385 int current_matrix_up_to_date_p = 0;
12386 int used_current_matrix_p = 0;
12387 /* This is less strict than current_matrix_up_to_date_p.
12388 It indictes that the buffer contents and narrowing are unchanged. */
12389 int buffer_unchanged_p = 0;
12390 int temp_scroll_step = 0;
12391 int count = SPECPDL_INDEX ();
12392 int rc;
12393 int centering_position = -1;
12394 int last_line_misfit = 0;
12395
12396 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12397 opoint = lpoint;
12398
12399 /* W must be a leaf window here. */
12400 xassert (!NILP (w->buffer));
12401 #if GLYPH_DEBUG
12402 *w->desired_matrix->method = 0;
12403 #endif
12404
12405 specbind (Qinhibit_point_motion_hooks, Qt);
12406
12407 reconsider_clip_changes (w, buffer);
12408
12409 /* Has the mode line to be updated? */
12410 update_mode_line = (!NILP (w->update_mode_line)
12411 || update_mode_lines
12412 || buffer->clip_changed
12413 || buffer->prevent_redisplay_optimizations_p);
12414
12415 if (MINI_WINDOW_P (w))
12416 {
12417 if (w == XWINDOW (echo_area_window)
12418 && !NILP (echo_area_buffer[0]))
12419 {
12420 if (update_mode_line)
12421 /* We may have to update a tty frame's menu bar or a
12422 tool-bar. Example `M-x C-h C-h C-g'. */
12423 goto finish_menu_bars;
12424 else
12425 /* We've already displayed the echo area glyphs in this window. */
12426 goto finish_scroll_bars;
12427 }
12428 else if ((w != XWINDOW (minibuf_window)
12429 || minibuf_level == 0)
12430 /* When buffer is nonempty, redisplay window normally. */
12431 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
12432 /* Quail displays non-mini buffers in minibuffer window.
12433 In that case, redisplay the window normally. */
12434 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
12435 {
12436 /* W is a mini-buffer window, but it's not active, so clear
12437 it. */
12438 int yb = window_text_bottom_y (w);
12439 struct glyph_row *row;
12440 int y;
12441
12442 for (y = 0, row = w->desired_matrix->rows;
12443 y < yb;
12444 y += row->height, ++row)
12445 blank_row (w, row, y);
12446 goto finish_scroll_bars;
12447 }
12448
12449 clear_glyph_matrix (w->desired_matrix);
12450 }
12451
12452 /* Otherwise set up data on this window; select its buffer and point
12453 value. */
12454 /* Really select the buffer, for the sake of buffer-local
12455 variables. */
12456 set_buffer_internal_1 (XBUFFER (w->buffer));
12457 SET_TEXT_POS (opoint, PT, PT_BYTE);
12458
12459 current_matrix_up_to_date_p
12460 = (!NILP (w->window_end_valid)
12461 && !current_buffer->clip_changed
12462 && !current_buffer->prevent_redisplay_optimizations_p
12463 && XFASTINT (w->last_modified) >= MODIFF
12464 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12465
12466 buffer_unchanged_p
12467 = (!NILP (w->window_end_valid)
12468 && !current_buffer->clip_changed
12469 && XFASTINT (w->last_modified) >= MODIFF
12470 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12471
12472 /* When windows_or_buffers_changed is non-zero, we can't rely on
12473 the window end being valid, so set it to nil there. */
12474 if (windows_or_buffers_changed)
12475 {
12476 /* If window starts on a continuation line, maybe adjust the
12477 window start in case the window's width changed. */
12478 if (XMARKER (w->start)->buffer == current_buffer)
12479 compute_window_start_on_continuation_line (w);
12480
12481 w->window_end_valid = Qnil;
12482 }
12483
12484 /* Some sanity checks. */
12485 CHECK_WINDOW_END (w);
12486 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
12487 abort ();
12488 if (BYTEPOS (opoint) < CHARPOS (opoint))
12489 abort ();
12490
12491 /* If %c is in mode line, update it if needed. */
12492 if (!NILP (w->column_number_displayed)
12493 /* This alternative quickly identifies a common case
12494 where no change is needed. */
12495 && !(PT == XFASTINT (w->last_point)
12496 && XFASTINT (w->last_modified) >= MODIFF
12497 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
12498 && (XFASTINT (w->column_number_displayed)
12499 != (int) current_column ())) /* iftc */
12500 update_mode_line = 1;
12501
12502 /* Count number of windows showing the selected buffer. An indirect
12503 buffer counts as its base buffer. */
12504 if (!just_this_one_p)
12505 {
12506 struct buffer *current_base, *window_base;
12507 current_base = current_buffer;
12508 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
12509 if (current_base->base_buffer)
12510 current_base = current_base->base_buffer;
12511 if (window_base->base_buffer)
12512 window_base = window_base->base_buffer;
12513 if (current_base == window_base)
12514 buffer_shared++;
12515 }
12516
12517 /* Point refers normally to the selected window. For any other
12518 window, set up appropriate value. */
12519 if (!EQ (window, selected_window))
12520 {
12521 int new_pt = XMARKER (w->pointm)->charpos;
12522 int new_pt_byte = marker_byte_position (w->pointm);
12523 if (new_pt < BEGV)
12524 {
12525 new_pt = BEGV;
12526 new_pt_byte = BEGV_BYTE;
12527 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
12528 }
12529 else if (new_pt > (ZV - 1))
12530 {
12531 new_pt = ZV;
12532 new_pt_byte = ZV_BYTE;
12533 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
12534 }
12535
12536 /* We don't use SET_PT so that the point-motion hooks don't run. */
12537 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
12538 }
12539
12540 /* If any of the character widths specified in the display table
12541 have changed, invalidate the width run cache. It's true that
12542 this may be a bit late to catch such changes, but the rest of
12543 redisplay goes (non-fatally) haywire when the display table is
12544 changed, so why should we worry about doing any better? */
12545 if (current_buffer->width_run_cache)
12546 {
12547 struct Lisp_Char_Table *disptab = buffer_display_table ();
12548
12549 if (! disptab_matches_widthtab (disptab,
12550 XVECTOR (current_buffer->width_table)))
12551 {
12552 invalidate_region_cache (current_buffer,
12553 current_buffer->width_run_cache,
12554 BEG, Z);
12555 recompute_width_table (current_buffer, disptab);
12556 }
12557 }
12558
12559 /* If window-start is screwed up, choose a new one. */
12560 if (XMARKER (w->start)->buffer != current_buffer)
12561 goto recenter;
12562
12563 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12564
12565 /* If someone specified a new starting point but did not insist,
12566 check whether it can be used. */
12567 if (!NILP (w->optional_new_start)
12568 && CHARPOS (startp) >= BEGV
12569 && CHARPOS (startp) <= ZV)
12570 {
12571 w->optional_new_start = Qnil;
12572 start_display (&it, w, startp);
12573 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12574 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12575 if (IT_CHARPOS (it) == PT)
12576 w->force_start = Qt;
12577 /* IT may overshoot PT if text at PT is invisible. */
12578 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
12579 w->force_start = Qt;
12580
12581
12582 }
12583
12584 /* Handle case where place to start displaying has been specified,
12585 unless the specified location is outside the accessible range. */
12586 if (!NILP (w->force_start)
12587 || w->frozen_window_start_p)
12588 {
12589 /* We set this later on if we have to adjust point. */
12590 int new_vpos = -1;
12591 int val;
12592
12593 w->force_start = Qnil;
12594 w->vscroll = 0;
12595 w->window_end_valid = Qnil;
12596
12597 /* Forget any recorded base line for line number display. */
12598 if (!buffer_unchanged_p)
12599 w->base_line_number = Qnil;
12600
12601 /* Redisplay the mode line. Select the buffer properly for that.
12602 Also, run the hook window-scroll-functions
12603 because we have scrolled. */
12604 /* Note, we do this after clearing force_start because
12605 if there's an error, it is better to forget about force_start
12606 than to get into an infinite loop calling the hook functions
12607 and having them get more errors. */
12608 if (!update_mode_line
12609 || ! NILP (Vwindow_scroll_functions))
12610 {
12611 update_mode_line = 1;
12612 w->update_mode_line = Qt;
12613 startp = run_window_scroll_functions (window, startp);
12614 }
12615
12616 w->last_modified = make_number (0);
12617 w->last_overlay_modified = make_number (0);
12618 if (CHARPOS (startp) < BEGV)
12619 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
12620 else if (CHARPOS (startp) > ZV)
12621 SET_TEXT_POS (startp, ZV, ZV_BYTE);
12622
12623 /* Redisplay, then check if cursor has been set during the
12624 redisplay. Give up if new fonts were loaded. */
12625 val = try_window (window, startp, 1);
12626 if (!val)
12627 {
12628 w->force_start = Qt;
12629 clear_glyph_matrix (w->desired_matrix);
12630 goto need_larger_matrices;
12631 }
12632 /* Point was outside the scroll margins. */
12633 if (val < 0)
12634 new_vpos = window_box_height (w) / 2;
12635
12636 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
12637 {
12638 /* If point does not appear, try to move point so it does
12639 appear. The desired matrix has been built above, so we
12640 can use it here. */
12641 new_vpos = window_box_height (w) / 2;
12642 }
12643
12644 if (!cursor_row_fully_visible_p (w, 0, 0))
12645 {
12646 /* Point does appear, but on a line partly visible at end of window.
12647 Move it back to a fully-visible line. */
12648 new_vpos = window_box_height (w);
12649 }
12650
12651 /* If we need to move point for either of the above reasons,
12652 now actually do it. */
12653 if (new_vpos >= 0)
12654 {
12655 struct glyph_row *row;
12656
12657 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
12658 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
12659 ++row;
12660
12661 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
12662 MATRIX_ROW_START_BYTEPOS (row));
12663
12664 if (w != XWINDOW (selected_window))
12665 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
12666 else if (current_buffer == old)
12667 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12668
12669 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
12670
12671 /* If we are highlighting the region, then we just changed
12672 the region, so redisplay to show it. */
12673 if (!NILP (Vtransient_mark_mode)
12674 && !NILP (current_buffer->mark_active))
12675 {
12676 clear_glyph_matrix (w->desired_matrix);
12677 if (!try_window (window, startp, 0))
12678 goto need_larger_matrices;
12679 }
12680 }
12681
12682 #if GLYPH_DEBUG
12683 debug_method_add (w, "forced window start");
12684 #endif
12685 goto done;
12686 }
12687
12688 /* Handle case where text has not changed, only point, and it has
12689 not moved off the frame, and we are not retrying after hscroll.
12690 (current_matrix_up_to_date_p is nonzero when retrying.) */
12691 if (current_matrix_up_to_date_p
12692 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
12693 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
12694 {
12695 switch (rc)
12696 {
12697 case CURSOR_MOVEMENT_SUCCESS:
12698 used_current_matrix_p = 1;
12699 goto done;
12700
12701 #if 0 /* try_cursor_movement never returns this value. */
12702 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
12703 goto need_larger_matrices;
12704 #endif
12705
12706 case CURSOR_MOVEMENT_MUST_SCROLL:
12707 goto try_to_scroll;
12708
12709 default:
12710 abort ();
12711 }
12712 }
12713 /* If current starting point was originally the beginning of a line
12714 but no longer is, find a new starting point. */
12715 else if (!NILP (w->start_at_line_beg)
12716 && !(CHARPOS (startp) <= BEGV
12717 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
12718 {
12719 #if GLYPH_DEBUG
12720 debug_method_add (w, "recenter 1");
12721 #endif
12722 goto recenter;
12723 }
12724
12725 /* Try scrolling with try_window_id. Value is > 0 if update has
12726 been done, it is -1 if we know that the same window start will
12727 not work. It is 0 if unsuccessful for some other reason. */
12728 else if ((tem = try_window_id (w)) != 0)
12729 {
12730 #if GLYPH_DEBUG
12731 debug_method_add (w, "try_window_id %d", tem);
12732 #endif
12733
12734 if (fonts_changed_p)
12735 goto need_larger_matrices;
12736 if (tem > 0)
12737 goto done;
12738
12739 /* Otherwise try_window_id has returned -1 which means that we
12740 don't want the alternative below this comment to execute. */
12741 }
12742 else if (CHARPOS (startp) >= BEGV
12743 && CHARPOS (startp) <= ZV
12744 && PT >= CHARPOS (startp)
12745 && (CHARPOS (startp) < ZV
12746 /* Avoid starting at end of buffer. */
12747 || CHARPOS (startp) == BEGV
12748 || (XFASTINT (w->last_modified) >= MODIFF
12749 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
12750 {
12751 #if GLYPH_DEBUG
12752 debug_method_add (w, "same window start");
12753 #endif
12754
12755 /* Try to redisplay starting at same place as before.
12756 If point has not moved off frame, accept the results. */
12757 if (!current_matrix_up_to_date_p
12758 /* Don't use try_window_reusing_current_matrix in this case
12759 because a window scroll function can have changed the
12760 buffer. */
12761 || !NILP (Vwindow_scroll_functions)
12762 || MINI_WINDOW_P (w)
12763 || !(used_current_matrix_p
12764 = try_window_reusing_current_matrix (w)))
12765 {
12766 IF_DEBUG (debug_method_add (w, "1"));
12767 if (try_window (window, startp, 1) < 0)
12768 /* -1 means we need to scroll.
12769 0 means we need new matrices, but fonts_changed_p
12770 is set in that case, so we will detect it below. */
12771 goto try_to_scroll;
12772 }
12773
12774 if (fonts_changed_p)
12775 goto need_larger_matrices;
12776
12777 if (w->cursor.vpos >= 0)
12778 {
12779 if (!just_this_one_p
12780 || current_buffer->clip_changed
12781 || BEG_UNCHANGED < CHARPOS (startp))
12782 /* Forget any recorded base line for line number display. */
12783 w->base_line_number = Qnil;
12784
12785 if (!cursor_row_fully_visible_p (w, 1, 0))
12786 {
12787 clear_glyph_matrix (w->desired_matrix);
12788 last_line_misfit = 1;
12789 }
12790 /* Drop through and scroll. */
12791 else
12792 goto done;
12793 }
12794 else
12795 clear_glyph_matrix (w->desired_matrix);
12796 }
12797
12798 try_to_scroll:
12799
12800 w->last_modified = make_number (0);
12801 w->last_overlay_modified = make_number (0);
12802
12803 /* Redisplay the mode line. Select the buffer properly for that. */
12804 if (!update_mode_line)
12805 {
12806 update_mode_line = 1;
12807 w->update_mode_line = Qt;
12808 }
12809
12810 /* Try to scroll by specified few lines. */
12811 if ((scroll_conservatively
12812 || scroll_step
12813 || temp_scroll_step
12814 || NUMBERP (current_buffer->scroll_up_aggressively)
12815 || NUMBERP (current_buffer->scroll_down_aggressively))
12816 && !current_buffer->clip_changed
12817 && CHARPOS (startp) >= BEGV
12818 && CHARPOS (startp) <= ZV)
12819 {
12820 /* The function returns -1 if new fonts were loaded, 1 if
12821 successful, 0 if not successful. */
12822 int rc = try_scrolling (window, just_this_one_p,
12823 scroll_conservatively,
12824 scroll_step,
12825 temp_scroll_step, last_line_misfit);
12826 switch (rc)
12827 {
12828 case SCROLLING_SUCCESS:
12829 goto done;
12830
12831 case SCROLLING_NEED_LARGER_MATRICES:
12832 goto need_larger_matrices;
12833
12834 case SCROLLING_FAILED:
12835 break;
12836
12837 default:
12838 abort ();
12839 }
12840 }
12841
12842 /* Finally, just choose place to start which centers point */
12843
12844 recenter:
12845 if (centering_position < 0)
12846 centering_position = window_box_height (w) / 2;
12847
12848 #if GLYPH_DEBUG
12849 debug_method_add (w, "recenter");
12850 #endif
12851
12852 /* w->vscroll = 0; */
12853
12854 /* Forget any previously recorded base line for line number display. */
12855 if (!buffer_unchanged_p)
12856 w->base_line_number = Qnil;
12857
12858 /* Move backward half the height of the window. */
12859 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12860 it.current_y = it.last_visible_y;
12861 move_it_vertically_backward (&it, centering_position);
12862 xassert (IT_CHARPOS (it) >= BEGV);
12863
12864 /* The function move_it_vertically_backward may move over more
12865 than the specified y-distance. If it->w is small, e.g. a
12866 mini-buffer window, we may end up in front of the window's
12867 display area. Start displaying at the start of the line
12868 containing PT in this case. */
12869 if (it.current_y <= 0)
12870 {
12871 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12872 move_it_vertically_backward (&it, 0);
12873 #if 0
12874 /* I think this assert is bogus if buffer contains
12875 invisible text or images. KFS. */
12876 xassert (IT_CHARPOS (it) <= PT);
12877 #endif
12878 it.current_y = 0;
12879 }
12880
12881 it.current_x = it.hpos = 0;
12882
12883 /* Set startp here explicitly in case that helps avoid an infinite loop
12884 in case the window-scroll-functions functions get errors. */
12885 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12886
12887 /* Run scroll hooks. */
12888 startp = run_window_scroll_functions (window, it.current.pos);
12889
12890 /* Redisplay the window. */
12891 if (!current_matrix_up_to_date_p
12892 || windows_or_buffers_changed
12893 || cursor_type_changed
12894 /* Don't use try_window_reusing_current_matrix in this case
12895 because it can have changed the buffer. */
12896 || !NILP (Vwindow_scroll_functions)
12897 || !just_this_one_p
12898 || MINI_WINDOW_P (w)
12899 || !(used_current_matrix_p
12900 = try_window_reusing_current_matrix (w)))
12901 try_window (window, startp, 0);
12902
12903 /* If new fonts have been loaded (due to fontsets), give up. We
12904 have to start a new redisplay since we need to re-adjust glyph
12905 matrices. */
12906 if (fonts_changed_p)
12907 goto need_larger_matrices;
12908
12909 /* If cursor did not appear assume that the middle of the window is
12910 in the first line of the window. Do it again with the next line.
12911 (Imagine a window of height 100, displaying two lines of height
12912 60. Moving back 50 from it->last_visible_y will end in the first
12913 line.) */
12914 if (w->cursor.vpos < 0)
12915 {
12916 if (!NILP (w->window_end_valid)
12917 && PT >= Z - XFASTINT (w->window_end_pos))
12918 {
12919 clear_glyph_matrix (w->desired_matrix);
12920 move_it_by_lines (&it, 1, 0);
12921 try_window (window, it.current.pos, 0);
12922 }
12923 else if (PT < IT_CHARPOS (it))
12924 {
12925 clear_glyph_matrix (w->desired_matrix);
12926 move_it_by_lines (&it, -1, 0);
12927 try_window (window, it.current.pos, 0);
12928 }
12929 else
12930 {
12931 /* Not much we can do about it. */
12932 }
12933 }
12934
12935 /* Consider the following case: Window starts at BEGV, there is
12936 invisible, intangible text at BEGV, so that display starts at
12937 some point START > BEGV. It can happen that we are called with
12938 PT somewhere between BEGV and START. Try to handle that case. */
12939 if (w->cursor.vpos < 0)
12940 {
12941 struct glyph_row *row = w->current_matrix->rows;
12942 if (row->mode_line_p)
12943 ++row;
12944 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12945 }
12946
12947 if (!cursor_row_fully_visible_p (w, 0, 0))
12948 {
12949 /* If vscroll is enabled, disable it and try again. */
12950 if (w->vscroll)
12951 {
12952 w->vscroll = 0;
12953 clear_glyph_matrix (w->desired_matrix);
12954 goto recenter;
12955 }
12956
12957 /* If centering point failed to make the whole line visible,
12958 put point at the top instead. That has to make the whole line
12959 visible, if it can be done. */
12960 if (centering_position == 0)
12961 goto done;
12962
12963 clear_glyph_matrix (w->desired_matrix);
12964 centering_position = 0;
12965 goto recenter;
12966 }
12967
12968 done:
12969
12970 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12971 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12972 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12973 ? Qt : Qnil);
12974
12975 /* Display the mode line, if we must. */
12976 if ((update_mode_line
12977 /* If window not full width, must redo its mode line
12978 if (a) the window to its side is being redone and
12979 (b) we do a frame-based redisplay. This is a consequence
12980 of how inverted lines are drawn in frame-based redisplay. */
12981 || (!just_this_one_p
12982 && !FRAME_WINDOW_P (f)
12983 && !WINDOW_FULL_WIDTH_P (w))
12984 /* Line number to display. */
12985 || INTEGERP (w->base_line_pos)
12986 /* Column number is displayed and different from the one displayed. */
12987 || (!NILP (w->column_number_displayed)
12988 && (XFASTINT (w->column_number_displayed)
12989 != (int) current_column ()))) /* iftc */
12990 /* This means that the window has a mode line. */
12991 && (WINDOW_WANTS_MODELINE_P (w)
12992 || WINDOW_WANTS_HEADER_LINE_P (w)))
12993 {
12994 display_mode_lines (w);
12995
12996 /* If mode line height has changed, arrange for a thorough
12997 immediate redisplay using the correct mode line height. */
12998 if (WINDOW_WANTS_MODELINE_P (w)
12999 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
13000 {
13001 fonts_changed_p = 1;
13002 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
13003 = DESIRED_MODE_LINE_HEIGHT (w);
13004 }
13005
13006 /* If top line height has changed, arrange for a thorough
13007 immediate redisplay using the correct mode line height. */
13008 if (WINDOW_WANTS_HEADER_LINE_P (w)
13009 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
13010 {
13011 fonts_changed_p = 1;
13012 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
13013 = DESIRED_HEADER_LINE_HEIGHT (w);
13014 }
13015
13016 if (fonts_changed_p)
13017 goto need_larger_matrices;
13018 }
13019
13020 if (!line_number_displayed
13021 && !BUFFERP (w->base_line_pos))
13022 {
13023 w->base_line_pos = Qnil;
13024 w->base_line_number = Qnil;
13025 }
13026
13027 finish_menu_bars:
13028
13029 /* When we reach a frame's selected window, redo the frame's menu bar. */
13030 if (update_mode_line
13031 && EQ (FRAME_SELECTED_WINDOW (f), window))
13032 {
13033 int redisplay_menu_p = 0;
13034 int redisplay_tool_bar_p = 0;
13035
13036 if (FRAME_WINDOW_P (f))
13037 {
13038 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
13039 || defined (USE_GTK)
13040 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
13041 #else
13042 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13043 #endif
13044 }
13045 else
13046 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13047
13048 if (redisplay_menu_p)
13049 display_menu_bar (w);
13050
13051 #ifdef HAVE_WINDOW_SYSTEM
13052 #ifdef USE_GTK
13053 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
13054 #else
13055 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
13056 && (FRAME_TOOL_BAR_LINES (f) > 0
13057 || auto_resize_tool_bars_p);
13058
13059 #endif
13060
13061 if (redisplay_tool_bar_p)
13062 redisplay_tool_bar (f);
13063 #endif
13064 }
13065
13066 #ifdef HAVE_WINDOW_SYSTEM
13067 if (FRAME_WINDOW_P (f)
13068 && update_window_fringes (w, (just_this_one_p
13069 || (!used_current_matrix_p && !overlay_arrow_seen)
13070 || w->pseudo_window_p)))
13071 {
13072 update_begin (f);
13073 BLOCK_INPUT;
13074 if (draw_window_fringes (w, 1))
13075 x_draw_vertical_border (w);
13076 UNBLOCK_INPUT;
13077 update_end (f);
13078 }
13079 #endif /* HAVE_WINDOW_SYSTEM */
13080
13081 /* We go to this label, with fonts_changed_p nonzero,
13082 if it is necessary to try again using larger glyph matrices.
13083 We have to redeem the scroll bar even in this case,
13084 because the loop in redisplay_internal expects that. */
13085 need_larger_matrices:
13086 ;
13087 finish_scroll_bars:
13088
13089 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
13090 {
13091 /* Set the thumb's position and size. */
13092 set_vertical_scroll_bar (w);
13093
13094 /* Note that we actually used the scroll bar attached to this
13095 window, so it shouldn't be deleted at the end of redisplay. */
13096 redeem_scroll_bar_hook (w);
13097 }
13098
13099 /* Restore current_buffer and value of point in it. */
13100 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
13101 set_buffer_internal_1 (old);
13102 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
13103
13104 unbind_to (count, Qnil);
13105 }
13106
13107
13108 /* Build the complete desired matrix of WINDOW with a window start
13109 buffer position POS.
13110
13111 Value is 1 if successful. It is zero if fonts were loaded during
13112 redisplay which makes re-adjusting glyph matrices necessary, and -1
13113 if point would appear in the scroll margins.
13114 (We check that only if CHECK_MARGINS is nonzero. */
13115
13116 int
13117 try_window (window, pos, check_margins)
13118 Lisp_Object window;
13119 struct text_pos pos;
13120 int check_margins;
13121 {
13122 struct window *w = XWINDOW (window);
13123 struct it it;
13124 struct glyph_row *last_text_row = NULL;
13125
13126 /* Make POS the new window start. */
13127 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
13128
13129 /* Mark cursor position as unknown. No overlay arrow seen. */
13130 w->cursor.vpos = -1;
13131 overlay_arrow_seen = 0;
13132
13133 /* Initialize iterator and info to start at POS. */
13134 start_display (&it, w, pos);
13135
13136 /* Display all lines of W. */
13137 while (it.current_y < it.last_visible_y)
13138 {
13139 if (display_line (&it))
13140 last_text_row = it.glyph_row - 1;
13141 if (fonts_changed_p)
13142 return 0;
13143 }
13144
13145 /* Don't let the cursor end in the scroll margins. */
13146 if (check_margins
13147 && !MINI_WINDOW_P (w))
13148 {
13149 int this_scroll_margin;
13150
13151 this_scroll_margin = max (0, scroll_margin);
13152 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13153 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13154
13155 if ((w->cursor.y < this_scroll_margin
13156 && CHARPOS (pos) > BEGV
13157 && IT_CHARPOS (it) < ZV)
13158 /* rms: considering make_cursor_line_fully_visible_p here
13159 seems to give wrong results. We don't want to recenter
13160 when the last line is partly visible, we want to allow
13161 that case to be handled in the usual way. */
13162 || (w->cursor.y + 1) > it.last_visible_y)
13163 {
13164 w->cursor.vpos = -1;
13165 clear_glyph_matrix (w->desired_matrix);
13166 return -1;
13167 }
13168 }
13169
13170 /* If bottom moved off end of frame, change mode line percentage. */
13171 if (XFASTINT (w->window_end_pos) <= 0
13172 && Z != IT_CHARPOS (it))
13173 w->update_mode_line = Qt;
13174
13175 /* Set window_end_pos to the offset of the last character displayed
13176 on the window from the end of current_buffer. Set
13177 window_end_vpos to its row number. */
13178 if (last_text_row)
13179 {
13180 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
13181 w->window_end_bytepos
13182 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13183 w->window_end_pos
13184 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13185 w->window_end_vpos
13186 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13187 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
13188 ->displays_text_p);
13189 }
13190 else
13191 {
13192 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13193 w->window_end_pos = make_number (Z - ZV);
13194 w->window_end_vpos = make_number (0);
13195 }
13196
13197 /* But that is not valid info until redisplay finishes. */
13198 w->window_end_valid = Qnil;
13199 return 1;
13200 }
13201
13202
13203 \f
13204 /************************************************************************
13205 Window redisplay reusing current matrix when buffer has not changed
13206 ************************************************************************/
13207
13208 /* Try redisplay of window W showing an unchanged buffer with a
13209 different window start than the last time it was displayed by
13210 reusing its current matrix. Value is non-zero if successful.
13211 W->start is the new window start. */
13212
13213 static int
13214 try_window_reusing_current_matrix (w)
13215 struct window *w;
13216 {
13217 struct frame *f = XFRAME (w->frame);
13218 struct glyph_row *row, *bottom_row;
13219 struct it it;
13220 struct run run;
13221 struct text_pos start, new_start;
13222 int nrows_scrolled, i;
13223 struct glyph_row *last_text_row;
13224 struct glyph_row *last_reused_text_row;
13225 struct glyph_row *start_row;
13226 int start_vpos, min_y, max_y;
13227
13228 #if GLYPH_DEBUG
13229 if (inhibit_try_window_reusing)
13230 return 0;
13231 #endif
13232
13233 if (/* This function doesn't handle terminal frames. */
13234 !FRAME_WINDOW_P (f)
13235 /* Don't try to reuse the display if windows have been split
13236 or such. */
13237 || windows_or_buffers_changed
13238 || cursor_type_changed)
13239 return 0;
13240
13241 /* Can't do this if region may have changed. */
13242 if ((!NILP (Vtransient_mark_mode)
13243 && !NILP (current_buffer->mark_active))
13244 || !NILP (w->region_showing)
13245 || !NILP (Vshow_trailing_whitespace))
13246 return 0;
13247
13248 /* If top-line visibility has changed, give up. */
13249 if (WINDOW_WANTS_HEADER_LINE_P (w)
13250 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
13251 return 0;
13252
13253 /* Give up if old or new display is scrolled vertically. We could
13254 make this function handle this, but right now it doesn't. */
13255 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13256 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
13257 return 0;
13258
13259 /* The variable new_start now holds the new window start. The old
13260 start `start' can be determined from the current matrix. */
13261 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
13262 start = start_row->start.pos;
13263 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13264
13265 /* Clear the desired matrix for the display below. */
13266 clear_glyph_matrix (w->desired_matrix);
13267
13268 if (CHARPOS (new_start) <= CHARPOS (start))
13269 {
13270 int first_row_y;
13271
13272 /* Don't use this method if the display starts with an ellipsis
13273 displayed for invisible text. It's not easy to handle that case
13274 below, and it's certainly not worth the effort since this is
13275 not a frequent case. */
13276 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
13277 return 0;
13278
13279 IF_DEBUG (debug_method_add (w, "twu1"));
13280
13281 /* Display up to a row that can be reused. The variable
13282 last_text_row is set to the last row displayed that displays
13283 text. Note that it.vpos == 0 if or if not there is a
13284 header-line; it's not the same as the MATRIX_ROW_VPOS! */
13285 start_display (&it, w, new_start);
13286 first_row_y = it.current_y;
13287 w->cursor.vpos = -1;
13288 last_text_row = last_reused_text_row = NULL;
13289
13290 while (it.current_y < it.last_visible_y
13291 && !fonts_changed_p)
13292 {
13293 /* If we have reached into the characters in the START row,
13294 that means the line boundaries have changed. So we
13295 can't start copying with the row START. Maybe it will
13296 work to start copying with the following row. */
13297 while (IT_CHARPOS (it) > CHARPOS (start))
13298 {
13299 /* Advance to the next row as the "start". */
13300 start_row++;
13301 start = start_row->start.pos;
13302 /* If there are no more rows to try, or just one, give up. */
13303 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
13304 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
13305 || CHARPOS (start) == ZV)
13306 {
13307 clear_glyph_matrix (w->desired_matrix);
13308 return 0;
13309 }
13310
13311 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13312 }
13313 /* If we have reached alignment,
13314 we can copy the rest of the rows. */
13315 if (IT_CHARPOS (it) == CHARPOS (start))
13316 break;
13317
13318 if (display_line (&it))
13319 last_text_row = it.glyph_row - 1;
13320 }
13321
13322 /* A value of current_y < last_visible_y means that we stopped
13323 at the previous window start, which in turn means that we
13324 have at least one reusable row. */
13325 if (it.current_y < it.last_visible_y)
13326 {
13327 /* IT.vpos always starts from 0; it counts text lines. */
13328 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
13329
13330 /* Find PT if not already found in the lines displayed. */
13331 if (w->cursor.vpos < 0)
13332 {
13333 int dy = it.current_y - start_row->y;
13334
13335 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13336 row = row_containing_pos (w, PT, row, NULL, dy);
13337 if (row)
13338 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
13339 dy, nrows_scrolled);
13340 else
13341 {
13342 clear_glyph_matrix (w->desired_matrix);
13343 return 0;
13344 }
13345 }
13346
13347 /* Scroll the display. Do it before the current matrix is
13348 changed. The problem here is that update has not yet
13349 run, i.e. part of the current matrix is not up to date.
13350 scroll_run_hook will clear the cursor, and use the
13351 current matrix to get the height of the row the cursor is
13352 in. */
13353 run.current_y = start_row->y;
13354 run.desired_y = it.current_y;
13355 run.height = it.last_visible_y - it.current_y;
13356
13357 if (run.height > 0 && run.current_y != run.desired_y)
13358 {
13359 update_begin (f);
13360 rif->update_window_begin_hook (w);
13361 rif->clear_window_mouse_face (w);
13362 rif->scroll_run_hook (w, &run);
13363 rif->update_window_end_hook (w, 0, 0);
13364 update_end (f);
13365 }
13366
13367 /* Shift current matrix down by nrows_scrolled lines. */
13368 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13369 rotate_matrix (w->current_matrix,
13370 start_vpos,
13371 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13372 nrows_scrolled);
13373
13374 /* Disable lines that must be updated. */
13375 for (i = 0; i < it.vpos; ++i)
13376 (start_row + i)->enabled_p = 0;
13377
13378 /* Re-compute Y positions. */
13379 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13380 max_y = it.last_visible_y;
13381 for (row = start_row + nrows_scrolled;
13382 row < bottom_row;
13383 ++row)
13384 {
13385 row->y = it.current_y;
13386 row->visible_height = row->height;
13387
13388 if (row->y < min_y)
13389 row->visible_height -= min_y - row->y;
13390 if (row->y + row->height > max_y)
13391 row->visible_height -= row->y + row->height - max_y;
13392 row->redraw_fringe_bitmaps_p = 1;
13393
13394 it.current_y += row->height;
13395
13396 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13397 last_reused_text_row = row;
13398 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
13399 break;
13400 }
13401
13402 /* Disable lines in the current matrix which are now
13403 below the window. */
13404 for (++row; row < bottom_row; ++row)
13405 row->enabled_p = row->mode_line_p = 0;
13406 }
13407
13408 /* Update window_end_pos etc.; last_reused_text_row is the last
13409 reused row from the current matrix containing text, if any.
13410 The value of last_text_row is the last displayed line
13411 containing text. */
13412 if (last_reused_text_row)
13413 {
13414 w->window_end_bytepos
13415 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
13416 w->window_end_pos
13417 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
13418 w->window_end_vpos
13419 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
13420 w->current_matrix));
13421 }
13422 else if (last_text_row)
13423 {
13424 w->window_end_bytepos
13425 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13426 w->window_end_pos
13427 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13428 w->window_end_vpos
13429 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13430 }
13431 else
13432 {
13433 /* This window must be completely empty. */
13434 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13435 w->window_end_pos = make_number (Z - ZV);
13436 w->window_end_vpos = make_number (0);
13437 }
13438 w->window_end_valid = Qnil;
13439
13440 /* Update hint: don't try scrolling again in update_window. */
13441 w->desired_matrix->no_scrolling_p = 1;
13442
13443 #if GLYPH_DEBUG
13444 debug_method_add (w, "try_window_reusing_current_matrix 1");
13445 #endif
13446 return 1;
13447 }
13448 else if (CHARPOS (new_start) > CHARPOS (start))
13449 {
13450 struct glyph_row *pt_row, *row;
13451 struct glyph_row *first_reusable_row;
13452 struct glyph_row *first_row_to_display;
13453 int dy;
13454 int yb = window_text_bottom_y (w);
13455
13456 /* Find the row starting at new_start, if there is one. Don't
13457 reuse a partially visible line at the end. */
13458 first_reusable_row = start_row;
13459 while (first_reusable_row->enabled_p
13460 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
13461 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13462 < CHARPOS (new_start)))
13463 ++first_reusable_row;
13464
13465 /* Give up if there is no row to reuse. */
13466 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
13467 || !first_reusable_row->enabled_p
13468 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13469 != CHARPOS (new_start)))
13470 return 0;
13471
13472 /* We can reuse fully visible rows beginning with
13473 first_reusable_row to the end of the window. Set
13474 first_row_to_display to the first row that cannot be reused.
13475 Set pt_row to the row containing point, if there is any. */
13476 pt_row = NULL;
13477 for (first_row_to_display = first_reusable_row;
13478 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
13479 ++first_row_to_display)
13480 {
13481 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
13482 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
13483 pt_row = first_row_to_display;
13484 }
13485
13486 /* Start displaying at the start of first_row_to_display. */
13487 xassert (first_row_to_display->y < yb);
13488 init_to_row_start (&it, w, first_row_to_display);
13489
13490 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
13491 - start_vpos);
13492 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
13493 - nrows_scrolled);
13494 it.current_y = (first_row_to_display->y - first_reusable_row->y
13495 + WINDOW_HEADER_LINE_HEIGHT (w));
13496
13497 /* Display lines beginning with first_row_to_display in the
13498 desired matrix. Set last_text_row to the last row displayed
13499 that displays text. */
13500 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
13501 if (pt_row == NULL)
13502 w->cursor.vpos = -1;
13503 last_text_row = NULL;
13504 while (it.current_y < it.last_visible_y && !fonts_changed_p)
13505 if (display_line (&it))
13506 last_text_row = it.glyph_row - 1;
13507
13508 /* Give up If point isn't in a row displayed or reused. */
13509 if (w->cursor.vpos < 0)
13510 {
13511 clear_glyph_matrix (w->desired_matrix);
13512 return 0;
13513 }
13514
13515 /* If point is in a reused row, adjust y and vpos of the cursor
13516 position. */
13517 if (pt_row)
13518 {
13519 w->cursor.vpos -= nrows_scrolled;
13520 w->cursor.y -= first_reusable_row->y - start_row->y;
13521 }
13522
13523 /* Scroll the display. */
13524 run.current_y = first_reusable_row->y;
13525 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
13526 run.height = it.last_visible_y - run.current_y;
13527 dy = run.current_y - run.desired_y;
13528
13529 if (run.height)
13530 {
13531 update_begin (f);
13532 rif->update_window_begin_hook (w);
13533 rif->clear_window_mouse_face (w);
13534 rif->scroll_run_hook (w, &run);
13535 rif->update_window_end_hook (w, 0, 0);
13536 update_end (f);
13537 }
13538
13539 /* Adjust Y positions of reused rows. */
13540 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13541 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13542 max_y = it.last_visible_y;
13543 for (row = first_reusable_row; row < first_row_to_display; ++row)
13544 {
13545 row->y -= dy;
13546 row->visible_height = row->height;
13547 if (row->y < min_y)
13548 row->visible_height -= min_y - row->y;
13549 if (row->y + row->height > max_y)
13550 row->visible_height -= row->y + row->height - max_y;
13551 row->redraw_fringe_bitmaps_p = 1;
13552 }
13553
13554 /* Scroll the current matrix. */
13555 xassert (nrows_scrolled > 0);
13556 rotate_matrix (w->current_matrix,
13557 start_vpos,
13558 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13559 -nrows_scrolled);
13560
13561 /* Disable rows not reused. */
13562 for (row -= nrows_scrolled; row < bottom_row; ++row)
13563 row->enabled_p = 0;
13564
13565 /* Point may have moved to a different line, so we cannot assume that
13566 the previous cursor position is valid; locate the correct row. */
13567 if (pt_row)
13568 {
13569 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
13570 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
13571 row++)
13572 {
13573 w->cursor.vpos++;
13574 w->cursor.y = row->y;
13575 }
13576 if (row < bottom_row)
13577 {
13578 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
13579 while (glyph->charpos < PT)
13580 {
13581 w->cursor.hpos++;
13582 w->cursor.x += glyph->pixel_width;
13583 glyph++;
13584 }
13585 }
13586 }
13587
13588 /* Adjust window end. A null value of last_text_row means that
13589 the window end is in reused rows which in turn means that
13590 only its vpos can have changed. */
13591 if (last_text_row)
13592 {
13593 w->window_end_bytepos
13594 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13595 w->window_end_pos
13596 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13597 w->window_end_vpos
13598 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13599 }
13600 else
13601 {
13602 w->window_end_vpos
13603 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
13604 }
13605
13606 w->window_end_valid = Qnil;
13607 w->desired_matrix->no_scrolling_p = 1;
13608
13609 #if GLYPH_DEBUG
13610 debug_method_add (w, "try_window_reusing_current_matrix 2");
13611 #endif
13612 return 1;
13613 }
13614
13615 return 0;
13616 }
13617
13618
13619 \f
13620 /************************************************************************
13621 Window redisplay reusing current matrix when buffer has changed
13622 ************************************************************************/
13623
13624 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
13625 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
13626 int *, int *));
13627 static struct glyph_row *
13628 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
13629 struct glyph_row *));
13630
13631
13632 /* Return the last row in MATRIX displaying text. If row START is
13633 non-null, start searching with that row. IT gives the dimensions
13634 of the display. Value is null if matrix is empty; otherwise it is
13635 a pointer to the row found. */
13636
13637 static struct glyph_row *
13638 find_last_row_displaying_text (matrix, it, start)
13639 struct glyph_matrix *matrix;
13640 struct it *it;
13641 struct glyph_row *start;
13642 {
13643 struct glyph_row *row, *row_found;
13644
13645 /* Set row_found to the last row in IT->w's current matrix
13646 displaying text. The loop looks funny but think of partially
13647 visible lines. */
13648 row_found = NULL;
13649 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
13650 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13651 {
13652 xassert (row->enabled_p);
13653 row_found = row;
13654 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
13655 break;
13656 ++row;
13657 }
13658
13659 return row_found;
13660 }
13661
13662
13663 /* Return the last row in the current matrix of W that is not affected
13664 by changes at the start of current_buffer that occurred since W's
13665 current matrix was built. Value is null if no such row exists.
13666
13667 BEG_UNCHANGED us the number of characters unchanged at the start of
13668 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
13669 first changed character in current_buffer. Characters at positions <
13670 BEG + BEG_UNCHANGED are at the same buffer positions as they were
13671 when the current matrix was built. */
13672
13673 static struct glyph_row *
13674 find_last_unchanged_at_beg_row (w)
13675 struct window *w;
13676 {
13677 int first_changed_pos = BEG + BEG_UNCHANGED;
13678 struct glyph_row *row;
13679 struct glyph_row *row_found = NULL;
13680 int yb = window_text_bottom_y (w);
13681
13682 /* Find the last row displaying unchanged text. */
13683 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13684 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13685 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
13686 {
13687 if (/* If row ends before first_changed_pos, it is unchanged,
13688 except in some case. */
13689 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
13690 /* When row ends in ZV and we write at ZV it is not
13691 unchanged. */
13692 && !row->ends_at_zv_p
13693 /* When first_changed_pos is the end of a continued line,
13694 row is not unchanged because it may be no longer
13695 continued. */
13696 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
13697 && (row->continued_p
13698 || row->exact_window_width_line_p)))
13699 row_found = row;
13700
13701 /* Stop if last visible row. */
13702 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
13703 break;
13704
13705 ++row;
13706 }
13707
13708 return row_found;
13709 }
13710
13711
13712 /* Find the first glyph row in the current matrix of W that is not
13713 affected by changes at the end of current_buffer since the
13714 time W's current matrix was built.
13715
13716 Return in *DELTA the number of chars by which buffer positions in
13717 unchanged text at the end of current_buffer must be adjusted.
13718
13719 Return in *DELTA_BYTES the corresponding number of bytes.
13720
13721 Value is null if no such row exists, i.e. all rows are affected by
13722 changes. */
13723
13724 static struct glyph_row *
13725 find_first_unchanged_at_end_row (w, delta, delta_bytes)
13726 struct window *w;
13727 int *delta, *delta_bytes;
13728 {
13729 struct glyph_row *row;
13730 struct glyph_row *row_found = NULL;
13731
13732 *delta = *delta_bytes = 0;
13733
13734 /* Display must not have been paused, otherwise the current matrix
13735 is not up to date. */
13736 if (NILP (w->window_end_valid))
13737 abort ();
13738
13739 /* A value of window_end_pos >= END_UNCHANGED means that the window
13740 end is in the range of changed text. If so, there is no
13741 unchanged row at the end of W's current matrix. */
13742 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
13743 return NULL;
13744
13745 /* Set row to the last row in W's current matrix displaying text. */
13746 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13747
13748 /* If matrix is entirely empty, no unchanged row exists. */
13749 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13750 {
13751 /* The value of row is the last glyph row in the matrix having a
13752 meaningful buffer position in it. The end position of row
13753 corresponds to window_end_pos. This allows us to translate
13754 buffer positions in the current matrix to current buffer
13755 positions for characters not in changed text. */
13756 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13757 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13758 int last_unchanged_pos, last_unchanged_pos_old;
13759 struct glyph_row *first_text_row
13760 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13761
13762 *delta = Z - Z_old;
13763 *delta_bytes = Z_BYTE - Z_BYTE_old;
13764
13765 /* Set last_unchanged_pos to the buffer position of the last
13766 character in the buffer that has not been changed. Z is the
13767 index + 1 of the last character in current_buffer, i.e. by
13768 subtracting END_UNCHANGED we get the index of the last
13769 unchanged character, and we have to add BEG to get its buffer
13770 position. */
13771 last_unchanged_pos = Z - END_UNCHANGED + BEG;
13772 last_unchanged_pos_old = last_unchanged_pos - *delta;
13773
13774 /* Search backward from ROW for a row displaying a line that
13775 starts at a minimum position >= last_unchanged_pos_old. */
13776 for (; row > first_text_row; --row)
13777 {
13778 /* This used to abort, but it can happen.
13779 It is ok to just stop the search instead here. KFS. */
13780 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13781 break;
13782
13783 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13784 row_found = row;
13785 }
13786 }
13787
13788 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
13789 abort ();
13790
13791 return row_found;
13792 }
13793
13794
13795 /* Make sure that glyph rows in the current matrix of window W
13796 reference the same glyph memory as corresponding rows in the
13797 frame's frame matrix. This function is called after scrolling W's
13798 current matrix on a terminal frame in try_window_id and
13799 try_window_reusing_current_matrix. */
13800
13801 static void
13802 sync_frame_with_window_matrix_rows (w)
13803 struct window *w;
13804 {
13805 struct frame *f = XFRAME (w->frame);
13806 struct glyph_row *window_row, *window_row_end, *frame_row;
13807
13808 /* Preconditions: W must be a leaf window and full-width. Its frame
13809 must have a frame matrix. */
13810 xassert (NILP (w->hchild) && NILP (w->vchild));
13811 xassert (WINDOW_FULL_WIDTH_P (w));
13812 xassert (!FRAME_WINDOW_P (f));
13813
13814 /* If W is a full-width window, glyph pointers in W's current matrix
13815 have, by definition, to be the same as glyph pointers in the
13816 corresponding frame matrix. Note that frame matrices have no
13817 marginal areas (see build_frame_matrix). */
13818 window_row = w->current_matrix->rows;
13819 window_row_end = window_row + w->current_matrix->nrows;
13820 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
13821 while (window_row < window_row_end)
13822 {
13823 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
13824 struct glyph *end = window_row->glyphs[LAST_AREA];
13825
13826 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
13827 frame_row->glyphs[TEXT_AREA] = start;
13828 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
13829 frame_row->glyphs[LAST_AREA] = end;
13830
13831 /* Disable frame rows whose corresponding window rows have
13832 been disabled in try_window_id. */
13833 if (!window_row->enabled_p)
13834 frame_row->enabled_p = 0;
13835
13836 ++window_row, ++frame_row;
13837 }
13838 }
13839
13840
13841 /* Find the glyph row in window W containing CHARPOS. Consider all
13842 rows between START and END (not inclusive). END null means search
13843 all rows to the end of the display area of W. Value is the row
13844 containing CHARPOS or null. */
13845
13846 struct glyph_row *
13847 row_containing_pos (w, charpos, start, end, dy)
13848 struct window *w;
13849 int charpos;
13850 struct glyph_row *start, *end;
13851 int dy;
13852 {
13853 struct glyph_row *row = start;
13854 int last_y;
13855
13856 /* If we happen to start on a header-line, skip that. */
13857 if (row->mode_line_p)
13858 ++row;
13859
13860 if ((end && row >= end) || !row->enabled_p)
13861 return NULL;
13862
13863 last_y = window_text_bottom_y (w) - dy;
13864
13865 while (1)
13866 {
13867 /* Give up if we have gone too far. */
13868 if (end && row >= end)
13869 return NULL;
13870 /* This formerly returned if they were equal.
13871 I think that both quantities are of a "last plus one" type;
13872 if so, when they are equal, the row is within the screen. -- rms. */
13873 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13874 return NULL;
13875
13876 /* If it is in this row, return this row. */
13877 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13878 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13879 /* The end position of a row equals the start
13880 position of the next row. If CHARPOS is there, we
13881 would rather display it in the next line, except
13882 when this line ends in ZV. */
13883 && !row->ends_at_zv_p
13884 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13885 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13886 return row;
13887 ++row;
13888 }
13889 }
13890
13891
13892 /* Try to redisplay window W by reusing its existing display. W's
13893 current matrix must be up to date when this function is called,
13894 i.e. window_end_valid must not be nil.
13895
13896 Value is
13897
13898 1 if display has been updated
13899 0 if otherwise unsuccessful
13900 -1 if redisplay with same window start is known not to succeed
13901
13902 The following steps are performed:
13903
13904 1. Find the last row in the current matrix of W that is not
13905 affected by changes at the start of current_buffer. If no such row
13906 is found, give up.
13907
13908 2. Find the first row in W's current matrix that is not affected by
13909 changes at the end of current_buffer. Maybe there is no such row.
13910
13911 3. Display lines beginning with the row + 1 found in step 1 to the
13912 row found in step 2 or, if step 2 didn't find a row, to the end of
13913 the window.
13914
13915 4. If cursor is not known to appear on the window, give up.
13916
13917 5. If display stopped at the row found in step 2, scroll the
13918 display and current matrix as needed.
13919
13920 6. Maybe display some lines at the end of W, if we must. This can
13921 happen under various circumstances, like a partially visible line
13922 becoming fully visible, or because newly displayed lines are displayed
13923 in smaller font sizes.
13924
13925 7. Update W's window end information. */
13926
13927 static int
13928 try_window_id (w)
13929 struct window *w;
13930 {
13931 struct frame *f = XFRAME (w->frame);
13932 struct glyph_matrix *current_matrix = w->current_matrix;
13933 struct glyph_matrix *desired_matrix = w->desired_matrix;
13934 struct glyph_row *last_unchanged_at_beg_row;
13935 struct glyph_row *first_unchanged_at_end_row;
13936 struct glyph_row *row;
13937 struct glyph_row *bottom_row;
13938 int bottom_vpos;
13939 struct it it;
13940 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13941 struct text_pos start_pos;
13942 struct run run;
13943 int first_unchanged_at_end_vpos = 0;
13944 struct glyph_row *last_text_row, *last_text_row_at_end;
13945 struct text_pos start;
13946 int first_changed_charpos, last_changed_charpos;
13947
13948 #if GLYPH_DEBUG
13949 if (inhibit_try_window_id)
13950 return 0;
13951 #endif
13952
13953 /* This is handy for debugging. */
13954 #if 0
13955 #define GIVE_UP(X) \
13956 do { \
13957 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13958 return 0; \
13959 } while (0)
13960 #else
13961 #define GIVE_UP(X) return 0
13962 #endif
13963
13964 SET_TEXT_POS_FROM_MARKER (start, w->start);
13965
13966 /* Don't use this for mini-windows because these can show
13967 messages and mini-buffers, and we don't handle that here. */
13968 if (MINI_WINDOW_P (w))
13969 GIVE_UP (1);
13970
13971 /* This flag is used to prevent redisplay optimizations. */
13972 if (windows_or_buffers_changed || cursor_type_changed)
13973 GIVE_UP (2);
13974
13975 /* Verify that narrowing has not changed.
13976 Also verify that we were not told to prevent redisplay optimizations.
13977 It would be nice to further
13978 reduce the number of cases where this prevents try_window_id. */
13979 if (current_buffer->clip_changed
13980 || current_buffer->prevent_redisplay_optimizations_p)
13981 GIVE_UP (3);
13982
13983 /* Window must either use window-based redisplay or be full width. */
13984 if (!FRAME_WINDOW_P (f)
13985 && (!line_ins_del_ok
13986 || !WINDOW_FULL_WIDTH_P (w)))
13987 GIVE_UP (4);
13988
13989 /* Give up if point is not known NOT to appear in W. */
13990 if (PT < CHARPOS (start))
13991 GIVE_UP (5);
13992
13993 /* Another way to prevent redisplay optimizations. */
13994 if (XFASTINT (w->last_modified) == 0)
13995 GIVE_UP (6);
13996
13997 /* Verify that window is not hscrolled. */
13998 if (XFASTINT (w->hscroll) != 0)
13999 GIVE_UP (7);
14000
14001 /* Verify that display wasn't paused. */
14002 if (NILP (w->window_end_valid))
14003 GIVE_UP (8);
14004
14005 /* Can't use this if highlighting a region because a cursor movement
14006 will do more than just set the cursor. */
14007 if (!NILP (Vtransient_mark_mode)
14008 && !NILP (current_buffer->mark_active))
14009 GIVE_UP (9);
14010
14011 /* Likewise if highlighting trailing whitespace. */
14012 if (!NILP (Vshow_trailing_whitespace))
14013 GIVE_UP (11);
14014
14015 /* Likewise if showing a region. */
14016 if (!NILP (w->region_showing))
14017 GIVE_UP (10);
14018
14019 /* Can use this if overlay arrow position and or string have changed. */
14020 if (overlay_arrows_changed_p ())
14021 GIVE_UP (12);
14022
14023
14024 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
14025 only if buffer has really changed. The reason is that the gap is
14026 initially at Z for freshly visited files. The code below would
14027 set end_unchanged to 0 in that case. */
14028 if (MODIFF > SAVE_MODIFF
14029 /* This seems to happen sometimes after saving a buffer. */
14030 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
14031 {
14032 if (GPT - BEG < BEG_UNCHANGED)
14033 BEG_UNCHANGED = GPT - BEG;
14034 if (Z - GPT < END_UNCHANGED)
14035 END_UNCHANGED = Z - GPT;
14036 }
14037
14038 /* The position of the first and last character that has been changed. */
14039 first_changed_charpos = BEG + BEG_UNCHANGED;
14040 last_changed_charpos = Z - END_UNCHANGED;
14041
14042 /* If window starts after a line end, and the last change is in
14043 front of that newline, then changes don't affect the display.
14044 This case happens with stealth-fontification. Note that although
14045 the display is unchanged, glyph positions in the matrix have to
14046 be adjusted, of course. */
14047 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14048 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14049 && ((last_changed_charpos < CHARPOS (start)
14050 && CHARPOS (start) == BEGV)
14051 || (last_changed_charpos < CHARPOS (start) - 1
14052 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
14053 {
14054 int Z_old, delta, Z_BYTE_old, delta_bytes;
14055 struct glyph_row *r0;
14056
14057 /* Compute how many chars/bytes have been added to or removed
14058 from the buffer. */
14059 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14060 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14061 delta = Z - Z_old;
14062 delta_bytes = Z_BYTE - Z_BYTE_old;
14063
14064 /* Give up if PT is not in the window. Note that it already has
14065 been checked at the start of try_window_id that PT is not in
14066 front of the window start. */
14067 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
14068 GIVE_UP (13);
14069
14070 /* If window start is unchanged, we can reuse the whole matrix
14071 as is, after adjusting glyph positions. No need to compute
14072 the window end again, since its offset from Z hasn't changed. */
14073 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14074 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
14075 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
14076 /* PT must not be in a partially visible line. */
14077 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
14078 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14079 {
14080 /* Adjust positions in the glyph matrix. */
14081 if (delta || delta_bytes)
14082 {
14083 struct glyph_row *r1
14084 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14085 increment_matrix_positions (w->current_matrix,
14086 MATRIX_ROW_VPOS (r0, current_matrix),
14087 MATRIX_ROW_VPOS (r1, current_matrix),
14088 delta, delta_bytes);
14089 }
14090
14091 /* Set the cursor. */
14092 row = row_containing_pos (w, PT, r0, NULL, 0);
14093 if (row)
14094 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14095 else
14096 abort ();
14097 return 1;
14098 }
14099 }
14100
14101 /* Handle the case that changes are all below what is displayed in
14102 the window, and that PT is in the window. This shortcut cannot
14103 be taken if ZV is visible in the window, and text has been added
14104 there that is visible in the window. */
14105 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
14106 /* ZV is not visible in the window, or there are no
14107 changes at ZV, actually. */
14108 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
14109 || first_changed_charpos == last_changed_charpos))
14110 {
14111 struct glyph_row *r0;
14112
14113 /* Give up if PT is not in the window. Note that it already has
14114 been checked at the start of try_window_id that PT is not in
14115 front of the window start. */
14116 if (PT >= MATRIX_ROW_END_CHARPOS (row))
14117 GIVE_UP (14);
14118
14119 /* If window start is unchanged, we can reuse the whole matrix
14120 as is, without changing glyph positions since no text has
14121 been added/removed in front of the window end. */
14122 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14123 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
14124 /* PT must not be in a partially visible line. */
14125 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
14126 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14127 {
14128 /* We have to compute the window end anew since text
14129 can have been added/removed after it. */
14130 w->window_end_pos
14131 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14132 w->window_end_bytepos
14133 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14134
14135 /* Set the cursor. */
14136 row = row_containing_pos (w, PT, r0, NULL, 0);
14137 if (row)
14138 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14139 else
14140 abort ();
14141 return 2;
14142 }
14143 }
14144
14145 /* Give up if window start is in the changed area.
14146
14147 The condition used to read
14148
14149 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
14150
14151 but why that was tested escapes me at the moment. */
14152 if (CHARPOS (start) >= first_changed_charpos
14153 && CHARPOS (start) <= last_changed_charpos)
14154 GIVE_UP (15);
14155
14156 /* Check that window start agrees with the start of the first glyph
14157 row in its current matrix. Check this after we know the window
14158 start is not in changed text, otherwise positions would not be
14159 comparable. */
14160 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
14161 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
14162 GIVE_UP (16);
14163
14164 /* Give up if the window ends in strings. Overlay strings
14165 at the end are difficult to handle, so don't try. */
14166 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
14167 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
14168 GIVE_UP (20);
14169
14170 /* Compute the position at which we have to start displaying new
14171 lines. Some of the lines at the top of the window might be
14172 reusable because they are not displaying changed text. Find the
14173 last row in W's current matrix not affected by changes at the
14174 start of current_buffer. Value is null if changes start in the
14175 first line of window. */
14176 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
14177 if (last_unchanged_at_beg_row)
14178 {
14179 /* Avoid starting to display in the moddle of a character, a TAB
14180 for instance. This is easier than to set up the iterator
14181 exactly, and it's not a frequent case, so the additional
14182 effort wouldn't really pay off. */
14183 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
14184 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
14185 && last_unchanged_at_beg_row > w->current_matrix->rows)
14186 --last_unchanged_at_beg_row;
14187
14188 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
14189 GIVE_UP (17);
14190
14191 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
14192 GIVE_UP (18);
14193 start_pos = it.current.pos;
14194
14195 /* Start displaying new lines in the desired matrix at the same
14196 vpos we would use in the current matrix, i.e. below
14197 last_unchanged_at_beg_row. */
14198 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
14199 current_matrix);
14200 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14201 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
14202
14203 xassert (it.hpos == 0 && it.current_x == 0);
14204 }
14205 else
14206 {
14207 /* There are no reusable lines at the start of the window.
14208 Start displaying in the first text line. */
14209 start_display (&it, w, start);
14210 it.vpos = it.first_vpos;
14211 start_pos = it.current.pos;
14212 }
14213
14214 /* Find the first row that is not affected by changes at the end of
14215 the buffer. Value will be null if there is no unchanged row, in
14216 which case we must redisplay to the end of the window. delta
14217 will be set to the value by which buffer positions beginning with
14218 first_unchanged_at_end_row have to be adjusted due to text
14219 changes. */
14220 first_unchanged_at_end_row
14221 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
14222 IF_DEBUG (debug_delta = delta);
14223 IF_DEBUG (debug_delta_bytes = delta_bytes);
14224
14225 /* Set stop_pos to the buffer position up to which we will have to
14226 display new lines. If first_unchanged_at_end_row != NULL, this
14227 is the buffer position of the start of the line displayed in that
14228 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
14229 that we don't stop at a buffer position. */
14230 stop_pos = 0;
14231 if (first_unchanged_at_end_row)
14232 {
14233 xassert (last_unchanged_at_beg_row == NULL
14234 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
14235
14236 /* If this is a continuation line, move forward to the next one
14237 that isn't. Changes in lines above affect this line.
14238 Caution: this may move first_unchanged_at_end_row to a row
14239 not displaying text. */
14240 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
14241 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14242 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14243 < it.last_visible_y))
14244 ++first_unchanged_at_end_row;
14245
14246 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14247 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14248 >= it.last_visible_y))
14249 first_unchanged_at_end_row = NULL;
14250 else
14251 {
14252 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
14253 + delta);
14254 first_unchanged_at_end_vpos
14255 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
14256 xassert (stop_pos >= Z - END_UNCHANGED);
14257 }
14258 }
14259 else if (last_unchanged_at_beg_row == NULL)
14260 GIVE_UP (19);
14261
14262
14263 #if GLYPH_DEBUG
14264
14265 /* Either there is no unchanged row at the end, or the one we have
14266 now displays text. This is a necessary condition for the window
14267 end pos calculation at the end of this function. */
14268 xassert (first_unchanged_at_end_row == NULL
14269 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
14270
14271 debug_last_unchanged_at_beg_vpos
14272 = (last_unchanged_at_beg_row
14273 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
14274 : -1);
14275 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
14276
14277 #endif /* GLYPH_DEBUG != 0 */
14278
14279
14280 /* Display new lines. Set last_text_row to the last new line
14281 displayed which has text on it, i.e. might end up as being the
14282 line where the window_end_vpos is. */
14283 w->cursor.vpos = -1;
14284 last_text_row = NULL;
14285 overlay_arrow_seen = 0;
14286 while (it.current_y < it.last_visible_y
14287 && !fonts_changed_p
14288 && (first_unchanged_at_end_row == NULL
14289 || IT_CHARPOS (it) < stop_pos))
14290 {
14291 if (display_line (&it))
14292 last_text_row = it.glyph_row - 1;
14293 }
14294
14295 if (fonts_changed_p)
14296 return -1;
14297
14298
14299 /* Compute differences in buffer positions, y-positions etc. for
14300 lines reused at the bottom of the window. Compute what we can
14301 scroll. */
14302 if (first_unchanged_at_end_row
14303 /* No lines reused because we displayed everything up to the
14304 bottom of the window. */
14305 && it.current_y < it.last_visible_y)
14306 {
14307 dvpos = (it.vpos
14308 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
14309 current_matrix));
14310 dy = it.current_y - first_unchanged_at_end_row->y;
14311 run.current_y = first_unchanged_at_end_row->y;
14312 run.desired_y = run.current_y + dy;
14313 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
14314 }
14315 else
14316 {
14317 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
14318 first_unchanged_at_end_row = NULL;
14319 }
14320 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
14321
14322
14323 /* Find the cursor if not already found. We have to decide whether
14324 PT will appear on this window (it sometimes doesn't, but this is
14325 not a very frequent case.) This decision has to be made before
14326 the current matrix is altered. A value of cursor.vpos < 0 means
14327 that PT is either in one of the lines beginning at
14328 first_unchanged_at_end_row or below the window. Don't care for
14329 lines that might be displayed later at the window end; as
14330 mentioned, this is not a frequent case. */
14331 if (w->cursor.vpos < 0)
14332 {
14333 /* Cursor in unchanged rows at the top? */
14334 if (PT < CHARPOS (start_pos)
14335 && last_unchanged_at_beg_row)
14336 {
14337 row = row_containing_pos (w, PT,
14338 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
14339 last_unchanged_at_beg_row + 1, 0);
14340 if (row)
14341 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14342 }
14343
14344 /* Start from first_unchanged_at_end_row looking for PT. */
14345 else if (first_unchanged_at_end_row)
14346 {
14347 row = row_containing_pos (w, PT - delta,
14348 first_unchanged_at_end_row, NULL, 0);
14349 if (row)
14350 set_cursor_from_row (w, row, w->current_matrix, delta,
14351 delta_bytes, dy, dvpos);
14352 }
14353
14354 /* Give up if cursor was not found. */
14355 if (w->cursor.vpos < 0)
14356 {
14357 clear_glyph_matrix (w->desired_matrix);
14358 return -1;
14359 }
14360 }
14361
14362 /* Don't let the cursor end in the scroll margins. */
14363 {
14364 int this_scroll_margin, cursor_height;
14365
14366 this_scroll_margin = max (0, scroll_margin);
14367 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14368 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
14369 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
14370
14371 if ((w->cursor.y < this_scroll_margin
14372 && CHARPOS (start) > BEGV)
14373 /* Old redisplay didn't take scroll margin into account at the bottom,
14374 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
14375 || (w->cursor.y + (make_cursor_line_fully_visible_p
14376 ? cursor_height + this_scroll_margin
14377 : 1)) > it.last_visible_y)
14378 {
14379 w->cursor.vpos = -1;
14380 clear_glyph_matrix (w->desired_matrix);
14381 return -1;
14382 }
14383 }
14384
14385 /* Scroll the display. Do it before changing the current matrix so
14386 that xterm.c doesn't get confused about where the cursor glyph is
14387 found. */
14388 if (dy && run.height)
14389 {
14390 update_begin (f);
14391
14392 if (FRAME_WINDOW_P (f))
14393 {
14394 rif->update_window_begin_hook (w);
14395 rif->clear_window_mouse_face (w);
14396 rif->scroll_run_hook (w, &run);
14397 rif->update_window_end_hook (w, 0, 0);
14398 }
14399 else
14400 {
14401 /* Terminal frame. In this case, dvpos gives the number of
14402 lines to scroll by; dvpos < 0 means scroll up. */
14403 int first_unchanged_at_end_vpos
14404 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
14405 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
14406 int end = (WINDOW_TOP_EDGE_LINE (w)
14407 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
14408 + window_internal_height (w));
14409
14410 /* Perform the operation on the screen. */
14411 if (dvpos > 0)
14412 {
14413 /* Scroll last_unchanged_at_beg_row to the end of the
14414 window down dvpos lines. */
14415 set_terminal_window (end);
14416
14417 /* On dumb terminals delete dvpos lines at the end
14418 before inserting dvpos empty lines. */
14419 if (!scroll_region_ok)
14420 ins_del_lines (end - dvpos, -dvpos);
14421
14422 /* Insert dvpos empty lines in front of
14423 last_unchanged_at_beg_row. */
14424 ins_del_lines (from, dvpos);
14425 }
14426 else if (dvpos < 0)
14427 {
14428 /* Scroll up last_unchanged_at_beg_vpos to the end of
14429 the window to last_unchanged_at_beg_vpos - |dvpos|. */
14430 set_terminal_window (end);
14431
14432 /* Delete dvpos lines in front of
14433 last_unchanged_at_beg_vpos. ins_del_lines will set
14434 the cursor to the given vpos and emit |dvpos| delete
14435 line sequences. */
14436 ins_del_lines (from + dvpos, dvpos);
14437
14438 /* On a dumb terminal insert dvpos empty lines at the
14439 end. */
14440 if (!scroll_region_ok)
14441 ins_del_lines (end + dvpos, -dvpos);
14442 }
14443
14444 set_terminal_window (0);
14445 }
14446
14447 update_end (f);
14448 }
14449
14450 /* Shift reused rows of the current matrix to the right position.
14451 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
14452 text. */
14453 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14454 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
14455 if (dvpos < 0)
14456 {
14457 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
14458 bottom_vpos, dvpos);
14459 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
14460 bottom_vpos, 0);
14461 }
14462 else if (dvpos > 0)
14463 {
14464 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
14465 bottom_vpos, dvpos);
14466 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
14467 first_unchanged_at_end_vpos + dvpos, 0);
14468 }
14469
14470 /* For frame-based redisplay, make sure that current frame and window
14471 matrix are in sync with respect to glyph memory. */
14472 if (!FRAME_WINDOW_P (f))
14473 sync_frame_with_window_matrix_rows (w);
14474
14475 /* Adjust buffer positions in reused rows. */
14476 if (delta)
14477 increment_matrix_positions (current_matrix,
14478 first_unchanged_at_end_vpos + dvpos,
14479 bottom_vpos, delta, delta_bytes);
14480
14481 /* Adjust Y positions. */
14482 if (dy)
14483 shift_glyph_matrix (w, current_matrix,
14484 first_unchanged_at_end_vpos + dvpos,
14485 bottom_vpos, dy);
14486
14487 if (first_unchanged_at_end_row)
14488 {
14489 first_unchanged_at_end_row += dvpos;
14490 if (first_unchanged_at_end_row->y >= it.last_visible_y
14491 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
14492 first_unchanged_at_end_row = NULL;
14493 }
14494
14495 /* If scrolling up, there may be some lines to display at the end of
14496 the window. */
14497 last_text_row_at_end = NULL;
14498 if (dy < 0)
14499 {
14500 /* Scrolling up can leave for example a partially visible line
14501 at the end of the window to be redisplayed. */
14502 /* Set last_row to the glyph row in the current matrix where the
14503 window end line is found. It has been moved up or down in
14504 the matrix by dvpos. */
14505 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
14506 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
14507
14508 /* If last_row is the window end line, it should display text. */
14509 xassert (last_row->displays_text_p);
14510
14511 /* If window end line was partially visible before, begin
14512 displaying at that line. Otherwise begin displaying with the
14513 line following it. */
14514 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
14515 {
14516 init_to_row_start (&it, w, last_row);
14517 it.vpos = last_vpos;
14518 it.current_y = last_row->y;
14519 }
14520 else
14521 {
14522 init_to_row_end (&it, w, last_row);
14523 it.vpos = 1 + last_vpos;
14524 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
14525 ++last_row;
14526 }
14527
14528 /* We may start in a continuation line. If so, we have to
14529 get the right continuation_lines_width and current_x. */
14530 it.continuation_lines_width = last_row->continuation_lines_width;
14531 it.hpos = it.current_x = 0;
14532
14533 /* Display the rest of the lines at the window end. */
14534 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14535 while (it.current_y < it.last_visible_y
14536 && !fonts_changed_p)
14537 {
14538 /* Is it always sure that the display agrees with lines in
14539 the current matrix? I don't think so, so we mark rows
14540 displayed invalid in the current matrix by setting their
14541 enabled_p flag to zero. */
14542 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
14543 if (display_line (&it))
14544 last_text_row_at_end = it.glyph_row - 1;
14545 }
14546 }
14547
14548 /* Update window_end_pos and window_end_vpos. */
14549 if (first_unchanged_at_end_row
14550 && !last_text_row_at_end)
14551 {
14552 /* Window end line if one of the preserved rows from the current
14553 matrix. Set row to the last row displaying text in current
14554 matrix starting at first_unchanged_at_end_row, after
14555 scrolling. */
14556 xassert (first_unchanged_at_end_row->displays_text_p);
14557 row = find_last_row_displaying_text (w->current_matrix, &it,
14558 first_unchanged_at_end_row);
14559 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
14560
14561 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14562 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14563 w->window_end_vpos
14564 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
14565 xassert (w->window_end_bytepos >= 0);
14566 IF_DEBUG (debug_method_add (w, "A"));
14567 }
14568 else if (last_text_row_at_end)
14569 {
14570 w->window_end_pos
14571 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
14572 w->window_end_bytepos
14573 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
14574 w->window_end_vpos
14575 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
14576 xassert (w->window_end_bytepos >= 0);
14577 IF_DEBUG (debug_method_add (w, "B"));
14578 }
14579 else if (last_text_row)
14580 {
14581 /* We have displayed either to the end of the window or at the
14582 end of the window, i.e. the last row with text is to be found
14583 in the desired matrix. */
14584 w->window_end_pos
14585 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14586 w->window_end_bytepos
14587 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14588 w->window_end_vpos
14589 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
14590 xassert (w->window_end_bytepos >= 0);
14591 }
14592 else if (first_unchanged_at_end_row == NULL
14593 && last_text_row == NULL
14594 && last_text_row_at_end == NULL)
14595 {
14596 /* Displayed to end of window, but no line containing text was
14597 displayed. Lines were deleted at the end of the window. */
14598 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
14599 int vpos = XFASTINT (w->window_end_vpos);
14600 struct glyph_row *current_row = current_matrix->rows + vpos;
14601 struct glyph_row *desired_row = desired_matrix->rows + vpos;
14602
14603 for (row = NULL;
14604 row == NULL && vpos >= first_vpos;
14605 --vpos, --current_row, --desired_row)
14606 {
14607 if (desired_row->enabled_p)
14608 {
14609 if (desired_row->displays_text_p)
14610 row = desired_row;
14611 }
14612 else if (current_row->displays_text_p)
14613 row = current_row;
14614 }
14615
14616 xassert (row != NULL);
14617 w->window_end_vpos = make_number (vpos + 1);
14618 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14619 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14620 xassert (w->window_end_bytepos >= 0);
14621 IF_DEBUG (debug_method_add (w, "C"));
14622 }
14623 else
14624 abort ();
14625
14626 #if 0 /* This leads to problems, for instance when the cursor is
14627 at ZV, and the cursor line displays no text. */
14628 /* Disable rows below what's displayed in the window. This makes
14629 debugging easier. */
14630 enable_glyph_matrix_rows (current_matrix,
14631 XFASTINT (w->window_end_vpos) + 1,
14632 bottom_vpos, 0);
14633 #endif
14634
14635 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
14636 debug_end_vpos = XFASTINT (w->window_end_vpos));
14637
14638 /* Record that display has not been completed. */
14639 w->window_end_valid = Qnil;
14640 w->desired_matrix->no_scrolling_p = 1;
14641 return 3;
14642
14643 #undef GIVE_UP
14644 }
14645
14646
14647 \f
14648 /***********************************************************************
14649 More debugging support
14650 ***********************************************************************/
14651
14652 #if GLYPH_DEBUG
14653
14654 void dump_glyph_row P_ ((struct glyph_row *, int, int));
14655 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
14656 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
14657
14658
14659 /* Dump the contents of glyph matrix MATRIX on stderr.
14660
14661 GLYPHS 0 means don't show glyph contents.
14662 GLYPHS 1 means show glyphs in short form
14663 GLYPHS > 1 means show glyphs in long form. */
14664
14665 void
14666 dump_glyph_matrix (matrix, glyphs)
14667 struct glyph_matrix *matrix;
14668 int glyphs;
14669 {
14670 int i;
14671 for (i = 0; i < matrix->nrows; ++i)
14672 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
14673 }
14674
14675
14676 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
14677 the glyph row and area where the glyph comes from. */
14678
14679 void
14680 dump_glyph (row, glyph, area)
14681 struct glyph_row *row;
14682 struct glyph *glyph;
14683 int area;
14684 {
14685 if (glyph->type == CHAR_GLYPH)
14686 {
14687 fprintf (stderr,
14688 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14689 glyph - row->glyphs[TEXT_AREA],
14690 'C',
14691 glyph->charpos,
14692 (BUFFERP (glyph->object)
14693 ? 'B'
14694 : (STRINGP (glyph->object)
14695 ? 'S'
14696 : '-')),
14697 glyph->pixel_width,
14698 glyph->u.ch,
14699 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
14700 ? glyph->u.ch
14701 : '.'),
14702 glyph->face_id,
14703 glyph->left_box_line_p,
14704 glyph->right_box_line_p);
14705 }
14706 else if (glyph->type == STRETCH_GLYPH)
14707 {
14708 fprintf (stderr,
14709 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14710 glyph - row->glyphs[TEXT_AREA],
14711 'S',
14712 glyph->charpos,
14713 (BUFFERP (glyph->object)
14714 ? 'B'
14715 : (STRINGP (glyph->object)
14716 ? 'S'
14717 : '-')),
14718 glyph->pixel_width,
14719 0,
14720 '.',
14721 glyph->face_id,
14722 glyph->left_box_line_p,
14723 glyph->right_box_line_p);
14724 }
14725 else if (glyph->type == IMAGE_GLYPH)
14726 {
14727 fprintf (stderr,
14728 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14729 glyph - row->glyphs[TEXT_AREA],
14730 'I',
14731 glyph->charpos,
14732 (BUFFERP (glyph->object)
14733 ? 'B'
14734 : (STRINGP (glyph->object)
14735 ? 'S'
14736 : '-')),
14737 glyph->pixel_width,
14738 glyph->u.img_id,
14739 '.',
14740 glyph->face_id,
14741 glyph->left_box_line_p,
14742 glyph->right_box_line_p);
14743 }
14744 }
14745
14746
14747 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
14748 GLYPHS 0 means don't show glyph contents.
14749 GLYPHS 1 means show glyphs in short form
14750 GLYPHS > 1 means show glyphs in long form. */
14751
14752 void
14753 dump_glyph_row (row, vpos, glyphs)
14754 struct glyph_row *row;
14755 int vpos, glyphs;
14756 {
14757 if (glyphs != 1)
14758 {
14759 fprintf (stderr, "Row Start End Used oEI><\\CTZFesm X Y W H V A P\n");
14760 fprintf (stderr, "======================================================================\n");
14761
14762 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
14763 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
14764 vpos,
14765 MATRIX_ROW_START_CHARPOS (row),
14766 MATRIX_ROW_END_CHARPOS (row),
14767 row->used[TEXT_AREA],
14768 row->contains_overlapping_glyphs_p,
14769 row->enabled_p,
14770 row->truncated_on_left_p,
14771 row->truncated_on_right_p,
14772 row->continued_p,
14773 MATRIX_ROW_CONTINUATION_LINE_P (row),
14774 row->displays_text_p,
14775 row->ends_at_zv_p,
14776 row->fill_line_p,
14777 row->ends_in_middle_of_char_p,
14778 row->starts_in_middle_of_char_p,
14779 row->mouse_face_p,
14780 row->x,
14781 row->y,
14782 row->pixel_width,
14783 row->height,
14784 row->visible_height,
14785 row->ascent,
14786 row->phys_ascent);
14787 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
14788 row->end.overlay_string_index,
14789 row->continuation_lines_width);
14790 fprintf (stderr, "%9d %5d\n",
14791 CHARPOS (row->start.string_pos),
14792 CHARPOS (row->end.string_pos));
14793 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
14794 row->end.dpvec_index);
14795 }
14796
14797 if (glyphs > 1)
14798 {
14799 int area;
14800
14801 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14802 {
14803 struct glyph *glyph = row->glyphs[area];
14804 struct glyph *glyph_end = glyph + row->used[area];
14805
14806 /* Glyph for a line end in text. */
14807 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
14808 ++glyph_end;
14809
14810 if (glyph < glyph_end)
14811 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
14812
14813 for (; glyph < glyph_end; ++glyph)
14814 dump_glyph (row, glyph, area);
14815 }
14816 }
14817 else if (glyphs == 1)
14818 {
14819 int area;
14820
14821 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14822 {
14823 char *s = (char *) alloca (row->used[area] + 1);
14824 int i;
14825
14826 for (i = 0; i < row->used[area]; ++i)
14827 {
14828 struct glyph *glyph = row->glyphs[area] + i;
14829 if (glyph->type == CHAR_GLYPH
14830 && glyph->u.ch < 0x80
14831 && glyph->u.ch >= ' ')
14832 s[i] = glyph->u.ch;
14833 else
14834 s[i] = '.';
14835 }
14836
14837 s[i] = '\0';
14838 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14839 }
14840 }
14841 }
14842
14843
14844 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14845 Sdump_glyph_matrix, 0, 1, "p",
14846 doc: /* Dump the current matrix of the selected window to stderr.
14847 Shows contents of glyph row structures. With non-nil
14848 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14849 glyphs in short form, otherwise show glyphs in long form. */)
14850 (glyphs)
14851 Lisp_Object glyphs;
14852 {
14853 struct window *w = XWINDOW (selected_window);
14854 struct buffer *buffer = XBUFFER (w->buffer);
14855
14856 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14857 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14858 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14859 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14860 fprintf (stderr, "=============================================\n");
14861 dump_glyph_matrix (w->current_matrix,
14862 NILP (glyphs) ? 0 : XINT (glyphs));
14863 return Qnil;
14864 }
14865
14866
14867 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14868 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14869 ()
14870 {
14871 struct frame *f = XFRAME (selected_frame);
14872 dump_glyph_matrix (f->current_matrix, 1);
14873 return Qnil;
14874 }
14875
14876
14877 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14878 doc: /* Dump glyph row ROW to stderr.
14879 GLYPH 0 means don't dump glyphs.
14880 GLYPH 1 means dump glyphs in short form.
14881 GLYPH > 1 or omitted means dump glyphs in long form. */)
14882 (row, glyphs)
14883 Lisp_Object row, glyphs;
14884 {
14885 struct glyph_matrix *matrix;
14886 int vpos;
14887
14888 CHECK_NUMBER (row);
14889 matrix = XWINDOW (selected_window)->current_matrix;
14890 vpos = XINT (row);
14891 if (vpos >= 0 && vpos < matrix->nrows)
14892 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14893 vpos,
14894 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14895 return Qnil;
14896 }
14897
14898
14899 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14900 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14901 GLYPH 0 means don't dump glyphs.
14902 GLYPH 1 means dump glyphs in short form.
14903 GLYPH > 1 or omitted means dump glyphs in long form. */)
14904 (row, glyphs)
14905 Lisp_Object row, glyphs;
14906 {
14907 struct frame *sf = SELECTED_FRAME ();
14908 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14909 int vpos;
14910
14911 CHECK_NUMBER (row);
14912 vpos = XINT (row);
14913 if (vpos >= 0 && vpos < m->nrows)
14914 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14915 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14916 return Qnil;
14917 }
14918
14919
14920 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14921 doc: /* Toggle tracing of redisplay.
14922 With ARG, turn tracing on if and only if ARG is positive. */)
14923 (arg)
14924 Lisp_Object arg;
14925 {
14926 if (NILP (arg))
14927 trace_redisplay_p = !trace_redisplay_p;
14928 else
14929 {
14930 arg = Fprefix_numeric_value (arg);
14931 trace_redisplay_p = XINT (arg) > 0;
14932 }
14933
14934 return Qnil;
14935 }
14936
14937
14938 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14939 doc: /* Like `format', but print result to stderr.
14940 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14941 (nargs, args)
14942 int nargs;
14943 Lisp_Object *args;
14944 {
14945 Lisp_Object s = Fformat (nargs, args);
14946 fprintf (stderr, "%s", SDATA (s));
14947 return Qnil;
14948 }
14949
14950 #endif /* GLYPH_DEBUG */
14951
14952
14953 \f
14954 /***********************************************************************
14955 Building Desired Matrix Rows
14956 ***********************************************************************/
14957
14958 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14959 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14960
14961 static struct glyph_row *
14962 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14963 struct window *w;
14964 Lisp_Object overlay_arrow_string;
14965 {
14966 struct frame *f = XFRAME (WINDOW_FRAME (w));
14967 struct buffer *buffer = XBUFFER (w->buffer);
14968 struct buffer *old = current_buffer;
14969 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14970 int arrow_len = SCHARS (overlay_arrow_string);
14971 const unsigned char *arrow_end = arrow_string + arrow_len;
14972 const unsigned char *p;
14973 struct it it;
14974 int multibyte_p;
14975 int n_glyphs_before;
14976
14977 set_buffer_temp (buffer);
14978 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14979 it.glyph_row->used[TEXT_AREA] = 0;
14980 SET_TEXT_POS (it.position, 0, 0);
14981
14982 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14983 p = arrow_string;
14984 while (p < arrow_end)
14985 {
14986 Lisp_Object face, ilisp;
14987
14988 /* Get the next character. */
14989 if (multibyte_p)
14990 it.c = string_char_and_length (p, arrow_len, &it.len);
14991 else
14992 it.c = *p, it.len = 1;
14993 p += it.len;
14994
14995 /* Get its face. */
14996 ilisp = make_number (p - arrow_string);
14997 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14998 it.face_id = compute_char_face (f, it.c, face);
14999
15000 /* Compute its width, get its glyphs. */
15001 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
15002 SET_TEXT_POS (it.position, -1, -1);
15003 PRODUCE_GLYPHS (&it);
15004
15005 /* If this character doesn't fit any more in the line, we have
15006 to remove some glyphs. */
15007 if (it.current_x > it.last_visible_x)
15008 {
15009 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
15010 break;
15011 }
15012 }
15013
15014 set_buffer_temp (old);
15015 return it.glyph_row;
15016 }
15017
15018
15019 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
15020 glyphs are only inserted for terminal frames since we can't really
15021 win with truncation glyphs when partially visible glyphs are
15022 involved. Which glyphs to insert is determined by
15023 produce_special_glyphs. */
15024
15025 static void
15026 insert_left_trunc_glyphs (it)
15027 struct it *it;
15028 {
15029 struct it truncate_it;
15030 struct glyph *from, *end, *to, *toend;
15031
15032 xassert (!FRAME_WINDOW_P (it->f));
15033
15034 /* Get the truncation glyphs. */
15035 truncate_it = *it;
15036 truncate_it.current_x = 0;
15037 truncate_it.face_id = DEFAULT_FACE_ID;
15038 truncate_it.glyph_row = &scratch_glyph_row;
15039 truncate_it.glyph_row->used[TEXT_AREA] = 0;
15040 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
15041 truncate_it.object = make_number (0);
15042 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
15043
15044 /* Overwrite glyphs from IT with truncation glyphs. */
15045 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15046 end = from + truncate_it.glyph_row->used[TEXT_AREA];
15047 to = it->glyph_row->glyphs[TEXT_AREA];
15048 toend = to + it->glyph_row->used[TEXT_AREA];
15049
15050 while (from < end)
15051 *to++ = *from++;
15052
15053 /* There may be padding glyphs left over. Overwrite them too. */
15054 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
15055 {
15056 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15057 while (from < end)
15058 *to++ = *from++;
15059 }
15060
15061 if (to > toend)
15062 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
15063 }
15064
15065
15066 /* Compute the pixel height and width of IT->glyph_row.
15067
15068 Most of the time, ascent and height of a display line will be equal
15069 to the max_ascent and max_height values of the display iterator
15070 structure. This is not the case if
15071
15072 1. We hit ZV without displaying anything. In this case, max_ascent
15073 and max_height will be zero.
15074
15075 2. We have some glyphs that don't contribute to the line height.
15076 (The glyph row flag contributes_to_line_height_p is for future
15077 pixmap extensions).
15078
15079 The first case is easily covered by using default values because in
15080 these cases, the line height does not really matter, except that it
15081 must not be zero. */
15082
15083 static void
15084 compute_line_metrics (it)
15085 struct it *it;
15086 {
15087 struct glyph_row *row = it->glyph_row;
15088 int area, i;
15089
15090 if (FRAME_WINDOW_P (it->f))
15091 {
15092 int i, min_y, max_y;
15093
15094 /* The line may consist of one space only, that was added to
15095 place the cursor on it. If so, the row's height hasn't been
15096 computed yet. */
15097 if (row->height == 0)
15098 {
15099 if (it->max_ascent + it->max_descent == 0)
15100 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
15101 row->ascent = it->max_ascent;
15102 row->height = it->max_ascent + it->max_descent;
15103 row->phys_ascent = it->max_phys_ascent;
15104 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15105 row->extra_line_spacing = it->max_extra_line_spacing;
15106 }
15107
15108 /* Compute the width of this line. */
15109 row->pixel_width = row->x;
15110 for (i = 0; i < row->used[TEXT_AREA]; ++i)
15111 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
15112
15113 xassert (row->pixel_width >= 0);
15114 xassert (row->ascent >= 0 && row->height > 0);
15115
15116 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
15117 || MATRIX_ROW_OVERLAPS_PRED_P (row));
15118
15119 /* If first line's physical ascent is larger than its logical
15120 ascent, use the physical ascent, and make the row taller.
15121 This makes accented characters fully visible. */
15122 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
15123 && row->phys_ascent > row->ascent)
15124 {
15125 row->height += row->phys_ascent - row->ascent;
15126 row->ascent = row->phys_ascent;
15127 }
15128
15129 /* Compute how much of the line is visible. */
15130 row->visible_height = row->height;
15131
15132 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
15133 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
15134
15135 if (row->y < min_y)
15136 row->visible_height -= min_y - row->y;
15137 if (row->y + row->height > max_y)
15138 row->visible_height -= row->y + row->height - max_y;
15139 }
15140 else
15141 {
15142 row->pixel_width = row->used[TEXT_AREA];
15143 if (row->continued_p)
15144 row->pixel_width -= it->continuation_pixel_width;
15145 else if (row->truncated_on_right_p)
15146 row->pixel_width -= it->truncation_pixel_width;
15147 row->ascent = row->phys_ascent = 0;
15148 row->height = row->phys_height = row->visible_height = 1;
15149 row->extra_line_spacing = 0;
15150 }
15151
15152 /* Compute a hash code for this row. */
15153 row->hash = 0;
15154 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15155 for (i = 0; i < row->used[area]; ++i)
15156 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
15157 + row->glyphs[area][i].u.val
15158 + row->glyphs[area][i].face_id
15159 + row->glyphs[area][i].padding_p
15160 + (row->glyphs[area][i].type << 2));
15161
15162 it->max_ascent = it->max_descent = 0;
15163 it->max_phys_ascent = it->max_phys_descent = 0;
15164 }
15165
15166
15167 /* Append one space to the glyph row of iterator IT if doing a
15168 window-based redisplay. The space has the same face as
15169 IT->face_id. Value is non-zero if a space was added.
15170
15171 This function is called to make sure that there is always one glyph
15172 at the end of a glyph row that the cursor can be set on under
15173 window-systems. (If there weren't such a glyph we would not know
15174 how wide and tall a box cursor should be displayed).
15175
15176 At the same time this space let's a nicely handle clearing to the
15177 end of the line if the row ends in italic text. */
15178
15179 static int
15180 append_space_for_newline (it, default_face_p)
15181 struct it *it;
15182 int default_face_p;
15183 {
15184 if (FRAME_WINDOW_P (it->f))
15185 {
15186 int n = it->glyph_row->used[TEXT_AREA];
15187
15188 if (it->glyph_row->glyphs[TEXT_AREA] + n
15189 < it->glyph_row->glyphs[1 + TEXT_AREA])
15190 {
15191 /* Save some values that must not be changed.
15192 Must save IT->c and IT->len because otherwise
15193 ITERATOR_AT_END_P wouldn't work anymore after
15194 append_space_for_newline has been called. */
15195 enum display_element_type saved_what = it->what;
15196 int saved_c = it->c, saved_len = it->len;
15197 int saved_x = it->current_x;
15198 int saved_face_id = it->face_id;
15199 struct text_pos saved_pos;
15200 Lisp_Object saved_object;
15201 struct face *face;
15202
15203 saved_object = it->object;
15204 saved_pos = it->position;
15205
15206 it->what = IT_CHARACTER;
15207 bzero (&it->position, sizeof it->position);
15208 it->object = make_number (0);
15209 it->c = ' ';
15210 it->len = 1;
15211
15212 if (default_face_p)
15213 it->face_id = DEFAULT_FACE_ID;
15214 else if (it->face_before_selective_p)
15215 it->face_id = it->saved_face_id;
15216 face = FACE_FROM_ID (it->f, it->face_id);
15217 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
15218
15219 PRODUCE_GLYPHS (it);
15220
15221 it->override_ascent = -1;
15222 it->constrain_row_ascent_descent_p = 0;
15223 it->current_x = saved_x;
15224 it->object = saved_object;
15225 it->position = saved_pos;
15226 it->what = saved_what;
15227 it->face_id = saved_face_id;
15228 it->len = saved_len;
15229 it->c = saved_c;
15230 return 1;
15231 }
15232 }
15233
15234 return 0;
15235 }
15236
15237
15238 /* Extend the face of the last glyph in the text area of IT->glyph_row
15239 to the end of the display line. Called from display_line.
15240 If the glyph row is empty, add a space glyph to it so that we
15241 know the face to draw. Set the glyph row flag fill_line_p. */
15242
15243 static void
15244 extend_face_to_end_of_line (it)
15245 struct it *it;
15246 {
15247 struct face *face;
15248 struct frame *f = it->f;
15249
15250 /* If line is already filled, do nothing. */
15251 if (it->current_x >= it->last_visible_x)
15252 return;
15253
15254 /* Face extension extends the background and box of IT->face_id
15255 to the end of the line. If the background equals the background
15256 of the frame, we don't have to do anything. */
15257 if (it->face_before_selective_p)
15258 face = FACE_FROM_ID (it->f, it->saved_face_id);
15259 else
15260 face = FACE_FROM_ID (f, it->face_id);
15261
15262 if (FRAME_WINDOW_P (f)
15263 && face->box == FACE_NO_BOX
15264 && face->background == FRAME_BACKGROUND_PIXEL (f)
15265 && !face->stipple)
15266 return;
15267
15268 /* Set the glyph row flag indicating that the face of the last glyph
15269 in the text area has to be drawn to the end of the text area. */
15270 it->glyph_row->fill_line_p = 1;
15271
15272 /* If current character of IT is not ASCII, make sure we have the
15273 ASCII face. This will be automatically undone the next time
15274 get_next_display_element returns a multibyte character. Note
15275 that the character will always be single byte in unibyte text. */
15276 if (!SINGLE_BYTE_CHAR_P (it->c))
15277 {
15278 it->face_id = FACE_FOR_CHAR (f, face, 0);
15279 }
15280
15281 if (FRAME_WINDOW_P (f))
15282 {
15283 /* If the row is empty, add a space with the current face of IT,
15284 so that we know which face to draw. */
15285 if (it->glyph_row->used[TEXT_AREA] == 0)
15286 {
15287 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
15288 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
15289 it->glyph_row->used[TEXT_AREA] = 1;
15290 }
15291 }
15292 else
15293 {
15294 /* Save some values that must not be changed. */
15295 int saved_x = it->current_x;
15296 struct text_pos saved_pos;
15297 Lisp_Object saved_object;
15298 enum display_element_type saved_what = it->what;
15299 int saved_face_id = it->face_id;
15300
15301 saved_object = it->object;
15302 saved_pos = it->position;
15303
15304 it->what = IT_CHARACTER;
15305 bzero (&it->position, sizeof it->position);
15306 it->object = make_number (0);
15307 it->c = ' ';
15308 it->len = 1;
15309 it->face_id = face->id;
15310
15311 PRODUCE_GLYPHS (it);
15312
15313 while (it->current_x <= it->last_visible_x)
15314 PRODUCE_GLYPHS (it);
15315
15316 /* Don't count these blanks really. It would let us insert a left
15317 truncation glyph below and make us set the cursor on them, maybe. */
15318 it->current_x = saved_x;
15319 it->object = saved_object;
15320 it->position = saved_pos;
15321 it->what = saved_what;
15322 it->face_id = saved_face_id;
15323 }
15324 }
15325
15326
15327 /* Value is non-zero if text starting at CHARPOS in current_buffer is
15328 trailing whitespace. */
15329
15330 static int
15331 trailing_whitespace_p (charpos)
15332 int charpos;
15333 {
15334 int bytepos = CHAR_TO_BYTE (charpos);
15335 int c = 0;
15336
15337 while (bytepos < ZV_BYTE
15338 && (c = FETCH_CHAR (bytepos),
15339 c == ' ' || c == '\t'))
15340 ++bytepos;
15341
15342 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
15343 {
15344 if (bytepos != PT_BYTE)
15345 return 1;
15346 }
15347 return 0;
15348 }
15349
15350
15351 /* Highlight trailing whitespace, if any, in ROW. */
15352
15353 void
15354 highlight_trailing_whitespace (f, row)
15355 struct frame *f;
15356 struct glyph_row *row;
15357 {
15358 int used = row->used[TEXT_AREA];
15359
15360 if (used)
15361 {
15362 struct glyph *start = row->glyphs[TEXT_AREA];
15363 struct glyph *glyph = start + used - 1;
15364
15365 /* Skip over glyphs inserted to display the cursor at the
15366 end of a line, for extending the face of the last glyph
15367 to the end of the line on terminals, and for truncation
15368 and continuation glyphs. */
15369 while (glyph >= start
15370 && glyph->type == CHAR_GLYPH
15371 && INTEGERP (glyph->object))
15372 --glyph;
15373
15374 /* If last glyph is a space or stretch, and it's trailing
15375 whitespace, set the face of all trailing whitespace glyphs in
15376 IT->glyph_row to `trailing-whitespace'. */
15377 if (glyph >= start
15378 && BUFFERP (glyph->object)
15379 && (glyph->type == STRETCH_GLYPH
15380 || (glyph->type == CHAR_GLYPH
15381 && glyph->u.ch == ' '))
15382 && trailing_whitespace_p (glyph->charpos))
15383 {
15384 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
15385 if (face_id < 0)
15386 return;
15387
15388 while (glyph >= start
15389 && BUFFERP (glyph->object)
15390 && (glyph->type == STRETCH_GLYPH
15391 || (glyph->type == CHAR_GLYPH
15392 && glyph->u.ch == ' ')))
15393 (glyph--)->face_id = face_id;
15394 }
15395 }
15396 }
15397
15398
15399 /* Value is non-zero if glyph row ROW in window W should be
15400 used to hold the cursor. */
15401
15402 static int
15403 cursor_row_p (w, row)
15404 struct window *w;
15405 struct glyph_row *row;
15406 {
15407 int cursor_row_p = 1;
15408
15409 if (PT == MATRIX_ROW_END_CHARPOS (row))
15410 {
15411 /* If the row ends with a newline from a string, we don't want
15412 the cursor there, but we still want it at the start of the
15413 string if the string starts in this row.
15414 If the row is continued it doesn't end in a newline. */
15415 if (CHARPOS (row->end.string_pos) >= 0)
15416 cursor_row_p = (row->continued_p
15417 || PT >= MATRIX_ROW_START_CHARPOS (row));
15418 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15419 {
15420 /* If the row ends in middle of a real character,
15421 and the line is continued, we want the cursor here.
15422 That's because MATRIX_ROW_END_CHARPOS would equal
15423 PT if PT is before the character. */
15424 if (!row->ends_in_ellipsis_p)
15425 cursor_row_p = row->continued_p;
15426 else
15427 /* If the row ends in an ellipsis, then
15428 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
15429 We want that position to be displayed after the ellipsis. */
15430 cursor_row_p = 0;
15431 }
15432 /* If the row ends at ZV, display the cursor at the end of that
15433 row instead of at the start of the row below. */
15434 else if (row->ends_at_zv_p)
15435 cursor_row_p = 1;
15436 else
15437 cursor_row_p = 0;
15438 }
15439
15440 return cursor_row_p;
15441 }
15442
15443
15444 /* Construct the glyph row IT->glyph_row in the desired matrix of
15445 IT->w from text at the current position of IT. See dispextern.h
15446 for an overview of struct it. Value is non-zero if
15447 IT->glyph_row displays text, as opposed to a line displaying ZV
15448 only. */
15449
15450 static int
15451 display_line (it)
15452 struct it *it;
15453 {
15454 struct glyph_row *row = it->glyph_row;
15455 Lisp_Object overlay_arrow_string;
15456
15457 /* We always start displaying at hpos zero even if hscrolled. */
15458 xassert (it->hpos == 0 && it->current_x == 0);
15459
15460 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
15461 >= it->w->desired_matrix->nrows)
15462 {
15463 it->w->nrows_scale_factor++;
15464 fonts_changed_p = 1;
15465 return 0;
15466 }
15467
15468 /* Is IT->w showing the region? */
15469 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
15470
15471 /* Clear the result glyph row and enable it. */
15472 prepare_desired_row (row);
15473
15474 row->y = it->current_y;
15475 row->start = it->start;
15476 row->continuation_lines_width = it->continuation_lines_width;
15477 row->displays_text_p = 1;
15478 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
15479 it->starts_in_middle_of_char_p = 0;
15480
15481 /* Arrange the overlays nicely for our purposes. Usually, we call
15482 display_line on only one line at a time, in which case this
15483 can't really hurt too much, or we call it on lines which appear
15484 one after another in the buffer, in which case all calls to
15485 recenter_overlay_lists but the first will be pretty cheap. */
15486 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
15487
15488 /* Move over display elements that are not visible because we are
15489 hscrolled. This may stop at an x-position < IT->first_visible_x
15490 if the first glyph is partially visible or if we hit a line end. */
15491 if (it->current_x < it->first_visible_x)
15492 {
15493 move_it_in_display_line_to (it, ZV, it->first_visible_x,
15494 MOVE_TO_POS | MOVE_TO_X);
15495 }
15496
15497 /* Get the initial row height. This is either the height of the
15498 text hscrolled, if there is any, or zero. */
15499 row->ascent = it->max_ascent;
15500 row->height = it->max_ascent + it->max_descent;
15501 row->phys_ascent = it->max_phys_ascent;
15502 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15503 row->extra_line_spacing = it->max_extra_line_spacing;
15504
15505 /* Loop generating characters. The loop is left with IT on the next
15506 character to display. */
15507 while (1)
15508 {
15509 int n_glyphs_before, hpos_before, x_before;
15510 int x, i, nglyphs;
15511 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
15512
15513 /* Retrieve the next thing to display. Value is zero if end of
15514 buffer reached. */
15515 if (!get_next_display_element (it))
15516 {
15517 /* Maybe add a space at the end of this line that is used to
15518 display the cursor there under X. Set the charpos of the
15519 first glyph of blank lines not corresponding to any text
15520 to -1. */
15521 #ifdef HAVE_WINDOW_SYSTEM
15522 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15523 row->exact_window_width_line_p = 1;
15524 else
15525 #endif /* HAVE_WINDOW_SYSTEM */
15526 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
15527 || row->used[TEXT_AREA] == 0)
15528 {
15529 row->glyphs[TEXT_AREA]->charpos = -1;
15530 row->displays_text_p = 0;
15531
15532 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
15533 && (!MINI_WINDOW_P (it->w)
15534 || (minibuf_level && EQ (it->window, minibuf_window))))
15535 row->indicate_empty_line_p = 1;
15536 }
15537
15538 it->continuation_lines_width = 0;
15539 row->ends_at_zv_p = 1;
15540 break;
15541 }
15542
15543 /* Now, get the metrics of what we want to display. This also
15544 generates glyphs in `row' (which is IT->glyph_row). */
15545 n_glyphs_before = row->used[TEXT_AREA];
15546 x = it->current_x;
15547
15548 /* Remember the line height so far in case the next element doesn't
15549 fit on the line. */
15550 if (!it->truncate_lines_p)
15551 {
15552 ascent = it->max_ascent;
15553 descent = it->max_descent;
15554 phys_ascent = it->max_phys_ascent;
15555 phys_descent = it->max_phys_descent;
15556 }
15557
15558 PRODUCE_GLYPHS (it);
15559
15560 /* If this display element was in marginal areas, continue with
15561 the next one. */
15562 if (it->area != TEXT_AREA)
15563 {
15564 row->ascent = max (row->ascent, it->max_ascent);
15565 row->height = max (row->height, it->max_ascent + it->max_descent);
15566 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15567 row->phys_height = max (row->phys_height,
15568 it->max_phys_ascent + it->max_phys_descent);
15569 row->extra_line_spacing = max (row->extra_line_spacing,
15570 it->max_extra_line_spacing);
15571 set_iterator_to_next (it, 1);
15572 continue;
15573 }
15574
15575 /* Does the display element fit on the line? If we truncate
15576 lines, we should draw past the right edge of the window. If
15577 we don't truncate, we want to stop so that we can display the
15578 continuation glyph before the right margin. If lines are
15579 continued, there are two possible strategies for characters
15580 resulting in more than 1 glyph (e.g. tabs): Display as many
15581 glyphs as possible in this line and leave the rest for the
15582 continuation line, or display the whole element in the next
15583 line. Original redisplay did the former, so we do it also. */
15584 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
15585 hpos_before = it->hpos;
15586 x_before = x;
15587
15588 if (/* Not a newline. */
15589 nglyphs > 0
15590 /* Glyphs produced fit entirely in the line. */
15591 && it->current_x < it->last_visible_x)
15592 {
15593 it->hpos += nglyphs;
15594 row->ascent = max (row->ascent, it->max_ascent);
15595 row->height = max (row->height, it->max_ascent + it->max_descent);
15596 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15597 row->phys_height = max (row->phys_height,
15598 it->max_phys_ascent + it->max_phys_descent);
15599 row->extra_line_spacing = max (row->extra_line_spacing,
15600 it->max_extra_line_spacing);
15601 if (it->current_x - it->pixel_width < it->first_visible_x)
15602 row->x = x - it->first_visible_x;
15603 }
15604 else
15605 {
15606 int new_x;
15607 struct glyph *glyph;
15608
15609 for (i = 0; i < nglyphs; ++i, x = new_x)
15610 {
15611 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
15612 new_x = x + glyph->pixel_width;
15613
15614 if (/* Lines are continued. */
15615 !it->truncate_lines_p
15616 && (/* Glyph doesn't fit on the line. */
15617 new_x > it->last_visible_x
15618 /* Or it fits exactly on a window system frame. */
15619 || (new_x == it->last_visible_x
15620 && FRAME_WINDOW_P (it->f))))
15621 {
15622 /* End of a continued line. */
15623
15624 if (it->hpos == 0
15625 || (new_x == it->last_visible_x
15626 && FRAME_WINDOW_P (it->f)))
15627 {
15628 /* Current glyph is the only one on the line or
15629 fits exactly on the line. We must continue
15630 the line because we can't draw the cursor
15631 after the glyph. */
15632 row->continued_p = 1;
15633 it->current_x = new_x;
15634 it->continuation_lines_width += new_x;
15635 ++it->hpos;
15636 if (i == nglyphs - 1)
15637 {
15638 set_iterator_to_next (it, 1);
15639 #ifdef HAVE_WINDOW_SYSTEM
15640 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15641 {
15642 if (!get_next_display_element (it))
15643 {
15644 row->exact_window_width_line_p = 1;
15645 it->continuation_lines_width = 0;
15646 row->continued_p = 0;
15647 row->ends_at_zv_p = 1;
15648 }
15649 else if (ITERATOR_AT_END_OF_LINE_P (it))
15650 {
15651 row->continued_p = 0;
15652 row->exact_window_width_line_p = 1;
15653 }
15654 }
15655 #endif /* HAVE_WINDOW_SYSTEM */
15656 }
15657 }
15658 else if (CHAR_GLYPH_PADDING_P (*glyph)
15659 && !FRAME_WINDOW_P (it->f))
15660 {
15661 /* A padding glyph that doesn't fit on this line.
15662 This means the whole character doesn't fit
15663 on the line. */
15664 row->used[TEXT_AREA] = n_glyphs_before;
15665
15666 /* Fill the rest of the row with continuation
15667 glyphs like in 20.x. */
15668 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
15669 < row->glyphs[1 + TEXT_AREA])
15670 produce_special_glyphs (it, IT_CONTINUATION);
15671
15672 row->continued_p = 1;
15673 it->current_x = x_before;
15674 it->continuation_lines_width += x_before;
15675
15676 /* Restore the height to what it was before the
15677 element not fitting on the line. */
15678 it->max_ascent = ascent;
15679 it->max_descent = descent;
15680 it->max_phys_ascent = phys_ascent;
15681 it->max_phys_descent = phys_descent;
15682 }
15683 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
15684 {
15685 /* A TAB that extends past the right edge of the
15686 window. This produces a single glyph on
15687 window system frames. We leave the glyph in
15688 this row and let it fill the row, but don't
15689 consume the TAB. */
15690 it->continuation_lines_width += it->last_visible_x;
15691 row->ends_in_middle_of_char_p = 1;
15692 row->continued_p = 1;
15693 glyph->pixel_width = it->last_visible_x - x;
15694 it->starts_in_middle_of_char_p = 1;
15695 }
15696 else
15697 {
15698 /* Something other than a TAB that draws past
15699 the right edge of the window. Restore
15700 positions to values before the element. */
15701 row->used[TEXT_AREA] = n_glyphs_before + i;
15702
15703 /* Display continuation glyphs. */
15704 if (!FRAME_WINDOW_P (it->f))
15705 produce_special_glyphs (it, IT_CONTINUATION);
15706 row->continued_p = 1;
15707
15708 it->current_x = x_before;
15709 it->continuation_lines_width += x;
15710 extend_face_to_end_of_line (it);
15711
15712 if (nglyphs > 1 && i > 0)
15713 {
15714 row->ends_in_middle_of_char_p = 1;
15715 it->starts_in_middle_of_char_p = 1;
15716 }
15717
15718 /* Restore the height to what it was before the
15719 element not fitting on the line. */
15720 it->max_ascent = ascent;
15721 it->max_descent = descent;
15722 it->max_phys_ascent = phys_ascent;
15723 it->max_phys_descent = phys_descent;
15724 }
15725
15726 break;
15727 }
15728 else if (new_x > it->first_visible_x)
15729 {
15730 /* Increment number of glyphs actually displayed. */
15731 ++it->hpos;
15732
15733 if (x < it->first_visible_x)
15734 /* Glyph is partially visible, i.e. row starts at
15735 negative X position. */
15736 row->x = x - it->first_visible_x;
15737 }
15738 else
15739 {
15740 /* Glyph is completely off the left margin of the
15741 window. This should not happen because of the
15742 move_it_in_display_line at the start of this
15743 function, unless the text display area of the
15744 window is empty. */
15745 xassert (it->first_visible_x <= it->last_visible_x);
15746 }
15747 }
15748
15749 row->ascent = max (row->ascent, it->max_ascent);
15750 row->height = max (row->height, it->max_ascent + it->max_descent);
15751 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15752 row->phys_height = max (row->phys_height,
15753 it->max_phys_ascent + it->max_phys_descent);
15754 row->extra_line_spacing = max (row->extra_line_spacing,
15755 it->max_extra_line_spacing);
15756
15757 /* End of this display line if row is continued. */
15758 if (row->continued_p || row->ends_at_zv_p)
15759 break;
15760 }
15761
15762 at_end_of_line:
15763 /* Is this a line end? If yes, we're also done, after making
15764 sure that a non-default face is extended up to the right
15765 margin of the window. */
15766 if (ITERATOR_AT_END_OF_LINE_P (it))
15767 {
15768 int used_before = row->used[TEXT_AREA];
15769
15770 row->ends_in_newline_from_string_p = STRINGP (it->object);
15771
15772 #ifdef HAVE_WINDOW_SYSTEM
15773 /* Add a space at the end of the line that is used to
15774 display the cursor there. */
15775 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15776 append_space_for_newline (it, 0);
15777 #endif /* HAVE_WINDOW_SYSTEM */
15778
15779 /* Extend the face to the end of the line. */
15780 extend_face_to_end_of_line (it);
15781
15782 /* Make sure we have the position. */
15783 if (used_before == 0)
15784 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
15785
15786 /* Consume the line end. This skips over invisible lines. */
15787 set_iterator_to_next (it, 1);
15788 it->continuation_lines_width = 0;
15789 break;
15790 }
15791
15792 /* Proceed with next display element. Note that this skips
15793 over lines invisible because of selective display. */
15794 set_iterator_to_next (it, 1);
15795
15796 /* If we truncate lines, we are done when the last displayed
15797 glyphs reach past the right margin of the window. */
15798 if (it->truncate_lines_p
15799 && (FRAME_WINDOW_P (it->f)
15800 ? (it->current_x >= it->last_visible_x)
15801 : (it->current_x > it->last_visible_x)))
15802 {
15803 /* Maybe add truncation glyphs. */
15804 if (!FRAME_WINDOW_P (it->f))
15805 {
15806 int i, n;
15807
15808 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
15809 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
15810 break;
15811
15812 for (n = row->used[TEXT_AREA]; i < n; ++i)
15813 {
15814 row->used[TEXT_AREA] = i;
15815 produce_special_glyphs (it, IT_TRUNCATION);
15816 }
15817 }
15818 #ifdef HAVE_WINDOW_SYSTEM
15819 else
15820 {
15821 /* Don't truncate if we can overflow newline into fringe. */
15822 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15823 {
15824 if (!get_next_display_element (it))
15825 {
15826 it->continuation_lines_width = 0;
15827 row->ends_at_zv_p = 1;
15828 row->exact_window_width_line_p = 1;
15829 break;
15830 }
15831 if (ITERATOR_AT_END_OF_LINE_P (it))
15832 {
15833 row->exact_window_width_line_p = 1;
15834 goto at_end_of_line;
15835 }
15836 }
15837 }
15838 #endif /* HAVE_WINDOW_SYSTEM */
15839
15840 row->truncated_on_right_p = 1;
15841 it->continuation_lines_width = 0;
15842 reseat_at_next_visible_line_start (it, 0);
15843 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
15844 it->hpos = hpos_before;
15845 it->current_x = x_before;
15846 break;
15847 }
15848 }
15849
15850 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15851 at the left window margin. */
15852 if (it->first_visible_x
15853 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
15854 {
15855 if (!FRAME_WINDOW_P (it->f))
15856 insert_left_trunc_glyphs (it);
15857 row->truncated_on_left_p = 1;
15858 }
15859
15860 /* If the start of this line is the overlay arrow-position, then
15861 mark this glyph row as the one containing the overlay arrow.
15862 This is clearly a mess with variable size fonts. It would be
15863 better to let it be displayed like cursors under X. */
15864 if ((row->displays_text_p || !overlay_arrow_seen)
15865 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
15866 !NILP (overlay_arrow_string)))
15867 {
15868 /* Overlay arrow in window redisplay is a fringe bitmap. */
15869 if (STRINGP (overlay_arrow_string))
15870 {
15871 struct glyph_row *arrow_row
15872 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
15873 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15874 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15875 struct glyph *p = row->glyphs[TEXT_AREA];
15876 struct glyph *p2, *end;
15877
15878 /* Copy the arrow glyphs. */
15879 while (glyph < arrow_end)
15880 *p++ = *glyph++;
15881
15882 /* Throw away padding glyphs. */
15883 p2 = p;
15884 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15885 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15886 ++p2;
15887 if (p2 > p)
15888 {
15889 while (p2 < end)
15890 *p++ = *p2++;
15891 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15892 }
15893 }
15894 else
15895 {
15896 xassert (INTEGERP (overlay_arrow_string));
15897 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
15898 }
15899 overlay_arrow_seen = 1;
15900 }
15901
15902 /* Compute pixel dimensions of this line. */
15903 compute_line_metrics (it);
15904
15905 /* Remember the position at which this line ends. */
15906 row->end = it->current;
15907
15908 /* Record whether this row ends inside an ellipsis. */
15909 row->ends_in_ellipsis_p
15910 = (it->method == GET_FROM_DISPLAY_VECTOR
15911 && it->ellipsis_p);
15912
15913 /* Save fringe bitmaps in this row. */
15914 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15915 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15916 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15917 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15918
15919 it->left_user_fringe_bitmap = 0;
15920 it->left_user_fringe_face_id = 0;
15921 it->right_user_fringe_bitmap = 0;
15922 it->right_user_fringe_face_id = 0;
15923
15924 /* Maybe set the cursor. */
15925 if (it->w->cursor.vpos < 0
15926 && PT >= MATRIX_ROW_START_CHARPOS (row)
15927 && PT <= MATRIX_ROW_END_CHARPOS (row)
15928 && cursor_row_p (it->w, row))
15929 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15930
15931 /* Highlight trailing whitespace. */
15932 if (!NILP (Vshow_trailing_whitespace))
15933 highlight_trailing_whitespace (it->f, it->glyph_row);
15934
15935 /* Prepare for the next line. This line starts horizontally at (X
15936 HPOS) = (0 0). Vertical positions are incremented. As a
15937 convenience for the caller, IT->glyph_row is set to the next
15938 row to be used. */
15939 it->current_x = it->hpos = 0;
15940 it->current_y += row->height;
15941 ++it->vpos;
15942 ++it->glyph_row;
15943 it->start = it->current;
15944 return row->displays_text_p;
15945 }
15946
15947
15948 \f
15949 /***********************************************************************
15950 Menu Bar
15951 ***********************************************************************/
15952
15953 /* Redisplay the menu bar in the frame for window W.
15954
15955 The menu bar of X frames that don't have X toolkit support is
15956 displayed in a special window W->frame->menu_bar_window.
15957
15958 The menu bar of terminal frames is treated specially as far as
15959 glyph matrices are concerned. Menu bar lines are not part of
15960 windows, so the update is done directly on the frame matrix rows
15961 for the menu bar. */
15962
15963 static void
15964 display_menu_bar (w)
15965 struct window *w;
15966 {
15967 struct frame *f = XFRAME (WINDOW_FRAME (w));
15968 struct it it;
15969 Lisp_Object items;
15970 int i;
15971
15972 /* Don't do all this for graphical frames. */
15973 #ifdef HAVE_NTGUI
15974 if (!NILP (Vwindow_system))
15975 return;
15976 #endif
15977 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15978 if (FRAME_X_P (f))
15979 return;
15980 #endif
15981 #ifdef MAC_OS
15982 if (FRAME_MAC_P (f))
15983 return;
15984 #endif
15985
15986 #ifdef USE_X_TOOLKIT
15987 xassert (!FRAME_WINDOW_P (f));
15988 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15989 it.first_visible_x = 0;
15990 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15991 #else /* not USE_X_TOOLKIT */
15992 if (FRAME_WINDOW_P (f))
15993 {
15994 /* Menu bar lines are displayed in the desired matrix of the
15995 dummy window menu_bar_window. */
15996 struct window *menu_w;
15997 xassert (WINDOWP (f->menu_bar_window));
15998 menu_w = XWINDOW (f->menu_bar_window);
15999 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
16000 MENU_FACE_ID);
16001 it.first_visible_x = 0;
16002 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16003 }
16004 else
16005 {
16006 /* This is a TTY frame, i.e. character hpos/vpos are used as
16007 pixel x/y. */
16008 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
16009 MENU_FACE_ID);
16010 it.first_visible_x = 0;
16011 it.last_visible_x = FRAME_COLS (f);
16012 }
16013 #endif /* not USE_X_TOOLKIT */
16014
16015 if (! mode_line_inverse_video)
16016 /* Force the menu-bar to be displayed in the default face. */
16017 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16018
16019 /* Clear all rows of the menu bar. */
16020 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
16021 {
16022 struct glyph_row *row = it.glyph_row + i;
16023 clear_glyph_row (row);
16024 row->enabled_p = 1;
16025 row->full_width_p = 1;
16026 }
16027
16028 /* Display all items of the menu bar. */
16029 items = FRAME_MENU_BAR_ITEMS (it.f);
16030 for (i = 0; i < XVECTOR (items)->size; i += 4)
16031 {
16032 Lisp_Object string;
16033
16034 /* Stop at nil string. */
16035 string = AREF (items, i + 1);
16036 if (NILP (string))
16037 break;
16038
16039 /* Remember where item was displayed. */
16040 AREF (items, i + 3) = make_number (it.hpos);
16041
16042 /* Display the item, pad with one space. */
16043 if (it.current_x < it.last_visible_x)
16044 display_string (NULL, string, Qnil, 0, 0, &it,
16045 SCHARS (string) + 1, 0, 0, -1);
16046 }
16047
16048 /* Fill out the line with spaces. */
16049 if (it.current_x < it.last_visible_x)
16050 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
16051
16052 /* Compute the total height of the lines. */
16053 compute_line_metrics (&it);
16054 }
16055
16056
16057 \f
16058 /***********************************************************************
16059 Mode Line
16060 ***********************************************************************/
16061
16062 /* Redisplay mode lines in the window tree whose root is WINDOW. If
16063 FORCE is non-zero, redisplay mode lines unconditionally.
16064 Otherwise, redisplay only mode lines that are garbaged. Value is
16065 the number of windows whose mode lines were redisplayed. */
16066
16067 static int
16068 redisplay_mode_lines (window, force)
16069 Lisp_Object window;
16070 int force;
16071 {
16072 int nwindows = 0;
16073
16074 while (!NILP (window))
16075 {
16076 struct window *w = XWINDOW (window);
16077
16078 if (WINDOWP (w->hchild))
16079 nwindows += redisplay_mode_lines (w->hchild, force);
16080 else if (WINDOWP (w->vchild))
16081 nwindows += redisplay_mode_lines (w->vchild, force);
16082 else if (force
16083 || FRAME_GARBAGED_P (XFRAME (w->frame))
16084 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
16085 {
16086 struct text_pos lpoint;
16087 struct buffer *old = current_buffer;
16088
16089 /* Set the window's buffer for the mode line display. */
16090 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16091 set_buffer_internal_1 (XBUFFER (w->buffer));
16092
16093 /* Point refers normally to the selected window. For any
16094 other window, set up appropriate value. */
16095 if (!EQ (window, selected_window))
16096 {
16097 struct text_pos pt;
16098
16099 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
16100 if (CHARPOS (pt) < BEGV)
16101 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16102 else if (CHARPOS (pt) > (ZV - 1))
16103 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
16104 else
16105 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
16106 }
16107
16108 /* Display mode lines. */
16109 clear_glyph_matrix (w->desired_matrix);
16110 if (display_mode_lines (w))
16111 {
16112 ++nwindows;
16113 w->must_be_updated_p = 1;
16114 }
16115
16116 /* Restore old settings. */
16117 set_buffer_internal_1 (old);
16118 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16119 }
16120
16121 window = w->next;
16122 }
16123
16124 return nwindows;
16125 }
16126
16127
16128 /* Display the mode and/or top line of window W. Value is the number
16129 of mode lines displayed. */
16130
16131 static int
16132 display_mode_lines (w)
16133 struct window *w;
16134 {
16135 Lisp_Object old_selected_window, old_selected_frame;
16136 int n = 0;
16137
16138 old_selected_frame = selected_frame;
16139 selected_frame = w->frame;
16140 old_selected_window = selected_window;
16141 XSETWINDOW (selected_window, w);
16142
16143 /* These will be set while the mode line specs are processed. */
16144 line_number_displayed = 0;
16145 w->column_number_displayed = Qnil;
16146
16147 if (WINDOW_WANTS_MODELINE_P (w))
16148 {
16149 struct window *sel_w = XWINDOW (old_selected_window);
16150
16151 /* Select mode line face based on the real selected window. */
16152 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
16153 current_buffer->mode_line_format);
16154 ++n;
16155 }
16156
16157 if (WINDOW_WANTS_HEADER_LINE_P (w))
16158 {
16159 display_mode_line (w, HEADER_LINE_FACE_ID,
16160 current_buffer->header_line_format);
16161 ++n;
16162 }
16163
16164 selected_frame = old_selected_frame;
16165 selected_window = old_selected_window;
16166 return n;
16167 }
16168
16169
16170 /* Display mode or top line of window W. FACE_ID specifies which line
16171 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
16172 FORMAT is the mode line format to display. Value is the pixel
16173 height of the mode line displayed. */
16174
16175 static int
16176 display_mode_line (w, face_id, format)
16177 struct window *w;
16178 enum face_id face_id;
16179 Lisp_Object format;
16180 {
16181 struct it it;
16182 struct face *face;
16183 int count = SPECPDL_INDEX ();
16184
16185 init_iterator (&it, w, -1, -1, NULL, face_id);
16186 prepare_desired_row (it.glyph_row);
16187
16188 it.glyph_row->mode_line_p = 1;
16189
16190 if (! mode_line_inverse_video)
16191 /* Force the mode-line to be displayed in the default face. */
16192 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16193
16194 record_unwind_protect (unwind_format_mode_line,
16195 format_mode_line_unwind_data (NULL, 0));
16196
16197 mode_line_target = MODE_LINE_DISPLAY;
16198
16199 /* Temporarily make frame's keyboard the current kboard so that
16200 kboard-local variables in the mode_line_format will get the right
16201 values. */
16202 push_frame_kboard (it.f);
16203 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16204 pop_frame_kboard ();
16205
16206 unbind_to (count, Qnil);
16207
16208 /* Fill up with spaces. */
16209 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
16210
16211 compute_line_metrics (&it);
16212 it.glyph_row->full_width_p = 1;
16213 it.glyph_row->continued_p = 0;
16214 it.glyph_row->truncated_on_left_p = 0;
16215 it.glyph_row->truncated_on_right_p = 0;
16216
16217 /* Make a 3D mode-line have a shadow at its right end. */
16218 face = FACE_FROM_ID (it.f, face_id);
16219 extend_face_to_end_of_line (&it);
16220 if (face->box != FACE_NO_BOX)
16221 {
16222 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
16223 + it.glyph_row->used[TEXT_AREA] - 1);
16224 last->right_box_line_p = 1;
16225 }
16226
16227 return it.glyph_row->height;
16228 }
16229
16230 /* Move element ELT in LIST to the front of LIST.
16231 Return the updated list. */
16232
16233 static Lisp_Object
16234 move_elt_to_front (elt, list)
16235 Lisp_Object elt, list;
16236 {
16237 register Lisp_Object tail, prev;
16238 register Lisp_Object tem;
16239
16240 tail = list;
16241 prev = Qnil;
16242 while (CONSP (tail))
16243 {
16244 tem = XCAR (tail);
16245
16246 if (EQ (elt, tem))
16247 {
16248 /* Splice out the link TAIL. */
16249 if (NILP (prev))
16250 list = XCDR (tail);
16251 else
16252 Fsetcdr (prev, XCDR (tail));
16253
16254 /* Now make it the first. */
16255 Fsetcdr (tail, list);
16256 return tail;
16257 }
16258 else
16259 prev = tail;
16260 tail = XCDR (tail);
16261 QUIT;
16262 }
16263
16264 /* Not found--return unchanged LIST. */
16265 return list;
16266 }
16267
16268 /* Contribute ELT to the mode line for window IT->w. How it
16269 translates into text depends on its data type.
16270
16271 IT describes the display environment in which we display, as usual.
16272
16273 DEPTH is the depth in recursion. It is used to prevent
16274 infinite recursion here.
16275
16276 FIELD_WIDTH is the number of characters the display of ELT should
16277 occupy in the mode line, and PRECISION is the maximum number of
16278 characters to display from ELT's representation. See
16279 display_string for details.
16280
16281 Returns the hpos of the end of the text generated by ELT.
16282
16283 PROPS is a property list to add to any string we encounter.
16284
16285 If RISKY is nonzero, remove (disregard) any properties in any string
16286 we encounter, and ignore :eval and :propertize.
16287
16288 The global variable `mode_line_target' determines whether the
16289 output is passed to `store_mode_line_noprop',
16290 `store_mode_line_string', or `display_string'. */
16291
16292 static int
16293 display_mode_element (it, depth, field_width, precision, elt, props, risky)
16294 struct it *it;
16295 int depth;
16296 int field_width, precision;
16297 Lisp_Object elt, props;
16298 int risky;
16299 {
16300 int n = 0, field, prec;
16301 int literal = 0;
16302
16303 tail_recurse:
16304 if (depth > 100)
16305 elt = build_string ("*too-deep*");
16306
16307 depth++;
16308
16309 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
16310 {
16311 case Lisp_String:
16312 {
16313 /* A string: output it and check for %-constructs within it. */
16314 unsigned char c;
16315 int offset = 0;
16316
16317 if (SCHARS (elt) > 0
16318 && (!NILP (props) || risky))
16319 {
16320 Lisp_Object oprops, aelt;
16321 oprops = Ftext_properties_at (make_number (0), elt);
16322
16323 /* If the starting string's properties are not what
16324 we want, translate the string. Also, if the string
16325 is risky, do that anyway. */
16326
16327 if (NILP (Fequal (props, oprops)) || risky)
16328 {
16329 /* If the starting string has properties,
16330 merge the specified ones onto the existing ones. */
16331 if (! NILP (oprops) && !risky)
16332 {
16333 Lisp_Object tem;
16334
16335 oprops = Fcopy_sequence (oprops);
16336 tem = props;
16337 while (CONSP (tem))
16338 {
16339 oprops = Fplist_put (oprops, XCAR (tem),
16340 XCAR (XCDR (tem)));
16341 tem = XCDR (XCDR (tem));
16342 }
16343 props = oprops;
16344 }
16345
16346 aelt = Fassoc (elt, mode_line_proptrans_alist);
16347 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
16348 {
16349 /* AELT is what we want. Move it to the front
16350 without consing. */
16351 elt = XCAR (aelt);
16352 mode_line_proptrans_alist
16353 = move_elt_to_front (aelt, mode_line_proptrans_alist);
16354 }
16355 else
16356 {
16357 Lisp_Object tem;
16358
16359 /* If AELT has the wrong props, it is useless.
16360 so get rid of it. */
16361 if (! NILP (aelt))
16362 mode_line_proptrans_alist
16363 = Fdelq (aelt, mode_line_proptrans_alist);
16364
16365 elt = Fcopy_sequence (elt);
16366 Fset_text_properties (make_number (0), Flength (elt),
16367 props, elt);
16368 /* Add this item to mode_line_proptrans_alist. */
16369 mode_line_proptrans_alist
16370 = Fcons (Fcons (elt, props),
16371 mode_line_proptrans_alist);
16372 /* Truncate mode_line_proptrans_alist
16373 to at most 50 elements. */
16374 tem = Fnthcdr (make_number (50),
16375 mode_line_proptrans_alist);
16376 if (! NILP (tem))
16377 XSETCDR (tem, Qnil);
16378 }
16379 }
16380 }
16381
16382 offset = 0;
16383
16384 if (literal)
16385 {
16386 prec = precision - n;
16387 switch (mode_line_target)
16388 {
16389 case MODE_LINE_NOPROP:
16390 case MODE_LINE_TITLE:
16391 n += store_mode_line_noprop (SDATA (elt), -1, prec);
16392 break;
16393 case MODE_LINE_STRING:
16394 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
16395 break;
16396 case MODE_LINE_DISPLAY:
16397 n += display_string (NULL, elt, Qnil, 0, 0, it,
16398 0, prec, 0, STRING_MULTIBYTE (elt));
16399 break;
16400 }
16401
16402 break;
16403 }
16404
16405 /* Handle the non-literal case. */
16406
16407 while ((precision <= 0 || n < precision)
16408 && SREF (elt, offset) != 0
16409 && (mode_line_target != MODE_LINE_DISPLAY
16410 || it->current_x < it->last_visible_x))
16411 {
16412 int last_offset = offset;
16413
16414 /* Advance to end of string or next format specifier. */
16415 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
16416 ;
16417
16418 if (offset - 1 != last_offset)
16419 {
16420 int nchars, nbytes;
16421
16422 /* Output to end of string or up to '%'. Field width
16423 is length of string. Don't output more than
16424 PRECISION allows us. */
16425 offset--;
16426
16427 prec = c_string_width (SDATA (elt) + last_offset,
16428 offset - last_offset, precision - n,
16429 &nchars, &nbytes);
16430
16431 switch (mode_line_target)
16432 {
16433 case MODE_LINE_NOPROP:
16434 case MODE_LINE_TITLE:
16435 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
16436 break;
16437 case MODE_LINE_STRING:
16438 {
16439 int bytepos = last_offset;
16440 int charpos = string_byte_to_char (elt, bytepos);
16441 int endpos = (precision <= 0
16442 ? string_byte_to_char (elt, offset)
16443 : charpos + nchars);
16444
16445 n += store_mode_line_string (NULL,
16446 Fsubstring (elt, make_number (charpos),
16447 make_number (endpos)),
16448 0, 0, 0, Qnil);
16449 }
16450 break;
16451 case MODE_LINE_DISPLAY:
16452 {
16453 int bytepos = last_offset;
16454 int charpos = string_byte_to_char (elt, bytepos);
16455 n += display_string (NULL, elt, Qnil, 0, charpos,
16456 it, 0, prec, 0,
16457 STRING_MULTIBYTE (elt));
16458 }
16459 break;
16460 }
16461 }
16462 else /* c == '%' */
16463 {
16464 int percent_position = offset;
16465
16466 /* Get the specified minimum width. Zero means
16467 don't pad. */
16468 field = 0;
16469 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
16470 field = field * 10 + c - '0';
16471
16472 /* Don't pad beyond the total padding allowed. */
16473 if (field_width - n > 0 && field > field_width - n)
16474 field = field_width - n;
16475
16476 /* Note that either PRECISION <= 0 or N < PRECISION. */
16477 prec = precision - n;
16478
16479 if (c == 'M')
16480 n += display_mode_element (it, depth, field, prec,
16481 Vglobal_mode_string, props,
16482 risky);
16483 else if (c != 0)
16484 {
16485 int multibyte;
16486 int bytepos, charpos;
16487 unsigned char *spec;
16488
16489 bytepos = percent_position;
16490 charpos = (STRING_MULTIBYTE (elt)
16491 ? string_byte_to_char (elt, bytepos)
16492 : bytepos);
16493
16494 spec
16495 = decode_mode_spec (it->w, c, field, prec, &multibyte);
16496
16497 switch (mode_line_target)
16498 {
16499 case MODE_LINE_NOPROP:
16500 case MODE_LINE_TITLE:
16501 n += store_mode_line_noprop (spec, field, prec);
16502 break;
16503 case MODE_LINE_STRING:
16504 {
16505 int len = strlen (spec);
16506 Lisp_Object tem = make_string (spec, len);
16507 props = Ftext_properties_at (make_number (charpos), elt);
16508 /* Should only keep face property in props */
16509 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
16510 }
16511 break;
16512 case MODE_LINE_DISPLAY:
16513 {
16514 int nglyphs_before, nwritten;
16515
16516 nglyphs_before = it->glyph_row->used[TEXT_AREA];
16517 nwritten = display_string (spec, Qnil, elt,
16518 charpos, 0, it,
16519 field, prec, 0,
16520 multibyte);
16521
16522 /* Assign to the glyphs written above the
16523 string where the `%x' came from, position
16524 of the `%'. */
16525 if (nwritten > 0)
16526 {
16527 struct glyph *glyph
16528 = (it->glyph_row->glyphs[TEXT_AREA]
16529 + nglyphs_before);
16530 int i;
16531
16532 for (i = 0; i < nwritten; ++i)
16533 {
16534 glyph[i].object = elt;
16535 glyph[i].charpos = charpos;
16536 }
16537
16538 n += nwritten;
16539 }
16540 }
16541 break;
16542 }
16543 }
16544 else /* c == 0 */
16545 break;
16546 }
16547 }
16548 }
16549 break;
16550
16551 case Lisp_Symbol:
16552 /* A symbol: process the value of the symbol recursively
16553 as if it appeared here directly. Avoid error if symbol void.
16554 Special case: if value of symbol is a string, output the string
16555 literally. */
16556 {
16557 register Lisp_Object tem;
16558
16559 /* If the variable is not marked as risky to set
16560 then its contents are risky to use. */
16561 if (NILP (Fget (elt, Qrisky_local_variable)))
16562 risky = 1;
16563
16564 tem = Fboundp (elt);
16565 if (!NILP (tem))
16566 {
16567 tem = Fsymbol_value (elt);
16568 /* If value is a string, output that string literally:
16569 don't check for % within it. */
16570 if (STRINGP (tem))
16571 literal = 1;
16572
16573 if (!EQ (tem, elt))
16574 {
16575 /* Give up right away for nil or t. */
16576 elt = tem;
16577 goto tail_recurse;
16578 }
16579 }
16580 }
16581 break;
16582
16583 case Lisp_Cons:
16584 {
16585 register Lisp_Object car, tem;
16586
16587 /* A cons cell: five distinct cases.
16588 If first element is :eval or :propertize, do something special.
16589 If first element is a string or a cons, process all the elements
16590 and effectively concatenate them.
16591 If first element is a negative number, truncate displaying cdr to
16592 at most that many characters. If positive, pad (with spaces)
16593 to at least that many characters.
16594 If first element is a symbol, process the cadr or caddr recursively
16595 according to whether the symbol's value is non-nil or nil. */
16596 car = XCAR (elt);
16597 if (EQ (car, QCeval))
16598 {
16599 /* An element of the form (:eval FORM) means evaluate FORM
16600 and use the result as mode line elements. */
16601
16602 if (risky)
16603 break;
16604
16605 if (CONSP (XCDR (elt)))
16606 {
16607 Lisp_Object spec;
16608 spec = safe_eval (XCAR (XCDR (elt)));
16609 n += display_mode_element (it, depth, field_width - n,
16610 precision - n, spec, props,
16611 risky);
16612 }
16613 }
16614 else if (EQ (car, QCpropertize))
16615 {
16616 /* An element of the form (:propertize ELT PROPS...)
16617 means display ELT but applying properties PROPS. */
16618
16619 if (risky)
16620 break;
16621
16622 if (CONSP (XCDR (elt)))
16623 n += display_mode_element (it, depth, field_width - n,
16624 precision - n, XCAR (XCDR (elt)),
16625 XCDR (XCDR (elt)), risky);
16626 }
16627 else if (SYMBOLP (car))
16628 {
16629 tem = Fboundp (car);
16630 elt = XCDR (elt);
16631 if (!CONSP (elt))
16632 goto invalid;
16633 /* elt is now the cdr, and we know it is a cons cell.
16634 Use its car if CAR has a non-nil value. */
16635 if (!NILP (tem))
16636 {
16637 tem = Fsymbol_value (car);
16638 if (!NILP (tem))
16639 {
16640 elt = XCAR (elt);
16641 goto tail_recurse;
16642 }
16643 }
16644 /* Symbol's value is nil (or symbol is unbound)
16645 Get the cddr of the original list
16646 and if possible find the caddr and use that. */
16647 elt = XCDR (elt);
16648 if (NILP (elt))
16649 break;
16650 else if (!CONSP (elt))
16651 goto invalid;
16652 elt = XCAR (elt);
16653 goto tail_recurse;
16654 }
16655 else if (INTEGERP (car))
16656 {
16657 register int lim = XINT (car);
16658 elt = XCDR (elt);
16659 if (lim < 0)
16660 {
16661 /* Negative int means reduce maximum width. */
16662 if (precision <= 0)
16663 precision = -lim;
16664 else
16665 precision = min (precision, -lim);
16666 }
16667 else if (lim > 0)
16668 {
16669 /* Padding specified. Don't let it be more than
16670 current maximum. */
16671 if (precision > 0)
16672 lim = min (precision, lim);
16673
16674 /* If that's more padding than already wanted, queue it.
16675 But don't reduce padding already specified even if
16676 that is beyond the current truncation point. */
16677 field_width = max (lim, field_width);
16678 }
16679 goto tail_recurse;
16680 }
16681 else if (STRINGP (car) || CONSP (car))
16682 {
16683 register int limit = 50;
16684 /* Limit is to protect against circular lists. */
16685 while (CONSP (elt)
16686 && --limit > 0
16687 && (precision <= 0 || n < precision))
16688 {
16689 n += display_mode_element (it, depth,
16690 /* Do padding only after the last
16691 element in the list. */
16692 (! CONSP (XCDR (elt))
16693 ? field_width - n
16694 : 0),
16695 precision - n, XCAR (elt),
16696 props, risky);
16697 elt = XCDR (elt);
16698 }
16699 }
16700 }
16701 break;
16702
16703 default:
16704 invalid:
16705 elt = build_string ("*invalid*");
16706 goto tail_recurse;
16707 }
16708
16709 /* Pad to FIELD_WIDTH. */
16710 if (field_width > 0 && n < field_width)
16711 {
16712 switch (mode_line_target)
16713 {
16714 case MODE_LINE_NOPROP:
16715 case MODE_LINE_TITLE:
16716 n += store_mode_line_noprop ("", field_width - n, 0);
16717 break;
16718 case MODE_LINE_STRING:
16719 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
16720 break;
16721 case MODE_LINE_DISPLAY:
16722 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
16723 0, 0, 0);
16724 break;
16725 }
16726 }
16727
16728 return n;
16729 }
16730
16731 /* Store a mode-line string element in mode_line_string_list.
16732
16733 If STRING is non-null, display that C string. Otherwise, the Lisp
16734 string LISP_STRING is displayed.
16735
16736 FIELD_WIDTH is the minimum number of output glyphs to produce.
16737 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16738 with spaces. FIELD_WIDTH <= 0 means don't pad.
16739
16740 PRECISION is the maximum number of characters to output from
16741 STRING. PRECISION <= 0 means don't truncate the string.
16742
16743 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
16744 properties to the string.
16745
16746 PROPS are the properties to add to the string.
16747 The mode_line_string_face face property is always added to the string.
16748 */
16749
16750 static int
16751 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
16752 char *string;
16753 Lisp_Object lisp_string;
16754 int copy_string;
16755 int field_width;
16756 int precision;
16757 Lisp_Object props;
16758 {
16759 int len;
16760 int n = 0;
16761
16762 if (string != NULL)
16763 {
16764 len = strlen (string);
16765 if (precision > 0 && len > precision)
16766 len = precision;
16767 lisp_string = make_string (string, len);
16768 if (NILP (props))
16769 props = mode_line_string_face_prop;
16770 else if (!NILP (mode_line_string_face))
16771 {
16772 Lisp_Object face = Fplist_get (props, Qface);
16773 props = Fcopy_sequence (props);
16774 if (NILP (face))
16775 face = mode_line_string_face;
16776 else
16777 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16778 props = Fplist_put (props, Qface, face);
16779 }
16780 Fadd_text_properties (make_number (0), make_number (len),
16781 props, lisp_string);
16782 }
16783 else
16784 {
16785 len = XFASTINT (Flength (lisp_string));
16786 if (precision > 0 && len > precision)
16787 {
16788 len = precision;
16789 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
16790 precision = -1;
16791 }
16792 if (!NILP (mode_line_string_face))
16793 {
16794 Lisp_Object face;
16795 if (NILP (props))
16796 props = Ftext_properties_at (make_number (0), lisp_string);
16797 face = Fplist_get (props, Qface);
16798 if (NILP (face))
16799 face = mode_line_string_face;
16800 else
16801 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16802 props = Fcons (Qface, Fcons (face, Qnil));
16803 if (copy_string)
16804 lisp_string = Fcopy_sequence (lisp_string);
16805 }
16806 if (!NILP (props))
16807 Fadd_text_properties (make_number (0), make_number (len),
16808 props, lisp_string);
16809 }
16810
16811 if (len > 0)
16812 {
16813 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16814 n += len;
16815 }
16816
16817 if (field_width > len)
16818 {
16819 field_width -= len;
16820 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
16821 if (!NILP (props))
16822 Fadd_text_properties (make_number (0), make_number (field_width),
16823 props, lisp_string);
16824 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16825 n += field_width;
16826 }
16827
16828 return n;
16829 }
16830
16831
16832 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
16833 1, 4, 0,
16834 doc: /* Format a string out of a mode line format specification.
16835 First arg FORMAT specifies the mode line format (see `mode-line-format'
16836 for details) to use.
16837
16838 Optional second arg FACE specifies the face property to put
16839 on all characters for which no face is specified.
16840 t means whatever face the window's mode line currently uses
16841 \(either `mode-line' or `mode-line-inactive', depending).
16842 nil means the default is no face property.
16843 If FACE is an integer, the value string has no text properties.
16844
16845 Optional third and fourth args WINDOW and BUFFER specify the window
16846 and buffer to use as the context for the formatting (defaults
16847 are the selected window and the window's buffer). */)
16848 (format, face, window, buffer)
16849 Lisp_Object format, face, window, buffer;
16850 {
16851 struct it it;
16852 int len;
16853 struct window *w;
16854 struct buffer *old_buffer = NULL;
16855 int face_id = -1;
16856 int no_props = INTEGERP (face);
16857 int count = SPECPDL_INDEX ();
16858 Lisp_Object str;
16859 int string_start = 0;
16860
16861 if (NILP (window))
16862 window = selected_window;
16863 CHECK_WINDOW (window);
16864 w = XWINDOW (window);
16865
16866 if (NILP (buffer))
16867 buffer = w->buffer;
16868 CHECK_BUFFER (buffer);
16869
16870 if (NILP (format))
16871 return build_string ("");
16872
16873 if (no_props)
16874 face = Qnil;
16875
16876 if (!NILP (face))
16877 {
16878 if (EQ (face, Qt))
16879 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
16880 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
16881 }
16882
16883 if (face_id < 0)
16884 face_id = DEFAULT_FACE_ID;
16885
16886 if (XBUFFER (buffer) != current_buffer)
16887 old_buffer = current_buffer;
16888
16889 /* Save things including mode_line_proptrans_alist,
16890 and set that to nil so that we don't alter the outer value. */
16891 record_unwind_protect (unwind_format_mode_line,
16892 format_mode_line_unwind_data (old_buffer, 1));
16893 mode_line_proptrans_alist = Qnil;
16894
16895 if (old_buffer)
16896 set_buffer_internal_1 (XBUFFER (buffer));
16897
16898 init_iterator (&it, w, -1, -1, NULL, face_id);
16899
16900 if (no_props)
16901 {
16902 mode_line_target = MODE_LINE_NOPROP;
16903 mode_line_string_face_prop = Qnil;
16904 mode_line_string_list = Qnil;
16905 string_start = MODE_LINE_NOPROP_LEN (0);
16906 }
16907 else
16908 {
16909 mode_line_target = MODE_LINE_STRING;
16910 mode_line_string_list = Qnil;
16911 mode_line_string_face = face;
16912 mode_line_string_face_prop
16913 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
16914 }
16915
16916 push_frame_kboard (it.f);
16917 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16918 pop_frame_kboard ();
16919
16920 if (no_props)
16921 {
16922 len = MODE_LINE_NOPROP_LEN (string_start);
16923 str = make_string (mode_line_noprop_buf + string_start, len);
16924 }
16925 else
16926 {
16927 mode_line_string_list = Fnreverse (mode_line_string_list);
16928 str = Fmapconcat (intern ("identity"), mode_line_string_list,
16929 make_string ("", 0));
16930 }
16931
16932 unbind_to (count, Qnil);
16933 return str;
16934 }
16935
16936 /* Write a null-terminated, right justified decimal representation of
16937 the positive integer D to BUF using a minimal field width WIDTH. */
16938
16939 static void
16940 pint2str (buf, width, d)
16941 register char *buf;
16942 register int width;
16943 register int d;
16944 {
16945 register char *p = buf;
16946
16947 if (d <= 0)
16948 *p++ = '0';
16949 else
16950 {
16951 while (d > 0)
16952 {
16953 *p++ = d % 10 + '0';
16954 d /= 10;
16955 }
16956 }
16957
16958 for (width -= (int) (p - buf); width > 0; --width)
16959 *p++ = ' ';
16960 *p-- = '\0';
16961 while (p > buf)
16962 {
16963 d = *buf;
16964 *buf++ = *p;
16965 *p-- = d;
16966 }
16967 }
16968
16969 /* Write a null-terminated, right justified decimal and "human
16970 readable" representation of the nonnegative integer D to BUF using
16971 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16972
16973 static const char power_letter[] =
16974 {
16975 0, /* not used */
16976 'k', /* kilo */
16977 'M', /* mega */
16978 'G', /* giga */
16979 'T', /* tera */
16980 'P', /* peta */
16981 'E', /* exa */
16982 'Z', /* zetta */
16983 'Y' /* yotta */
16984 };
16985
16986 static void
16987 pint2hrstr (buf, width, d)
16988 char *buf;
16989 int width;
16990 int d;
16991 {
16992 /* We aim to represent the nonnegative integer D as
16993 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16994 int quotient = d;
16995 int remainder = 0;
16996 /* -1 means: do not use TENTHS. */
16997 int tenths = -1;
16998 int exponent = 0;
16999
17000 /* Length of QUOTIENT.TENTHS as a string. */
17001 int length;
17002
17003 char * psuffix;
17004 char * p;
17005
17006 if (1000 <= quotient)
17007 {
17008 /* Scale to the appropriate EXPONENT. */
17009 do
17010 {
17011 remainder = quotient % 1000;
17012 quotient /= 1000;
17013 exponent++;
17014 }
17015 while (1000 <= quotient);
17016
17017 /* Round to nearest and decide whether to use TENTHS or not. */
17018 if (quotient <= 9)
17019 {
17020 tenths = remainder / 100;
17021 if (50 <= remainder % 100)
17022 {
17023 if (tenths < 9)
17024 tenths++;
17025 else
17026 {
17027 quotient++;
17028 if (quotient == 10)
17029 tenths = -1;
17030 else
17031 tenths = 0;
17032 }
17033 }
17034 }
17035 else
17036 if (500 <= remainder)
17037 {
17038 if (quotient < 999)
17039 quotient++;
17040 else
17041 {
17042 quotient = 1;
17043 exponent++;
17044 tenths = 0;
17045 }
17046 }
17047 }
17048
17049 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
17050 if (tenths == -1 && quotient <= 99)
17051 if (quotient <= 9)
17052 length = 1;
17053 else
17054 length = 2;
17055 else
17056 length = 3;
17057 p = psuffix = buf + max (width, length);
17058
17059 /* Print EXPONENT. */
17060 if (exponent)
17061 *psuffix++ = power_letter[exponent];
17062 *psuffix = '\0';
17063
17064 /* Print TENTHS. */
17065 if (tenths >= 0)
17066 {
17067 *--p = '0' + tenths;
17068 *--p = '.';
17069 }
17070
17071 /* Print QUOTIENT. */
17072 do
17073 {
17074 int digit = quotient % 10;
17075 *--p = '0' + digit;
17076 }
17077 while ((quotient /= 10) != 0);
17078
17079 /* Print leading spaces. */
17080 while (buf < p)
17081 *--p = ' ';
17082 }
17083
17084 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
17085 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
17086 type of CODING_SYSTEM. Return updated pointer into BUF. */
17087
17088 static unsigned char invalid_eol_type[] = "(*invalid*)";
17089
17090 static char *
17091 decode_mode_spec_coding (coding_system, buf, eol_flag)
17092 Lisp_Object coding_system;
17093 register char *buf;
17094 int eol_flag;
17095 {
17096 Lisp_Object val;
17097 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
17098 const unsigned char *eol_str;
17099 int eol_str_len;
17100 /* The EOL conversion we are using. */
17101 Lisp_Object eoltype;
17102
17103 val = Fget (coding_system, Qcoding_system);
17104 eoltype = Qnil;
17105
17106 if (!VECTORP (val)) /* Not yet decided. */
17107 {
17108 if (multibyte)
17109 *buf++ = '-';
17110 if (eol_flag)
17111 eoltype = eol_mnemonic_undecided;
17112 /* Don't mention EOL conversion if it isn't decided. */
17113 }
17114 else
17115 {
17116 Lisp_Object eolvalue;
17117
17118 eolvalue = Fget (coding_system, Qeol_type);
17119
17120 if (multibyte)
17121 *buf++ = XFASTINT (AREF (val, 1));
17122
17123 if (eol_flag)
17124 {
17125 /* The EOL conversion that is normal on this system. */
17126
17127 if (NILP (eolvalue)) /* Not yet decided. */
17128 eoltype = eol_mnemonic_undecided;
17129 else if (VECTORP (eolvalue)) /* Not yet decided. */
17130 eoltype = eol_mnemonic_undecided;
17131 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
17132 eoltype = (XFASTINT (eolvalue) == 0
17133 ? eol_mnemonic_unix
17134 : (XFASTINT (eolvalue) == 1
17135 ? eol_mnemonic_dos : eol_mnemonic_mac));
17136 }
17137 }
17138
17139 if (eol_flag)
17140 {
17141 /* Mention the EOL conversion if it is not the usual one. */
17142 if (STRINGP (eoltype))
17143 {
17144 eol_str = SDATA (eoltype);
17145 eol_str_len = SBYTES (eoltype);
17146 }
17147 else if (INTEGERP (eoltype)
17148 && CHAR_VALID_P (XINT (eoltype), 0))
17149 {
17150 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
17151 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
17152 eol_str = tmp;
17153 }
17154 else
17155 {
17156 eol_str = invalid_eol_type;
17157 eol_str_len = sizeof (invalid_eol_type) - 1;
17158 }
17159 bcopy (eol_str, buf, eol_str_len);
17160 buf += eol_str_len;
17161 }
17162
17163 return buf;
17164 }
17165
17166 /* Return a string for the output of a mode line %-spec for window W,
17167 generated by character C. PRECISION >= 0 means don't return a
17168 string longer than that value. FIELD_WIDTH > 0 means pad the
17169 string returned with spaces to that value. Return 1 in *MULTIBYTE
17170 if the result is multibyte text.
17171
17172 Note we operate on the current buffer for most purposes,
17173 the exception being w->base_line_pos. */
17174
17175 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
17176
17177 static char *
17178 decode_mode_spec (w, c, field_width, precision, multibyte)
17179 struct window *w;
17180 register int c;
17181 int field_width, precision;
17182 int *multibyte;
17183 {
17184 Lisp_Object obj;
17185 struct frame *f = XFRAME (WINDOW_FRAME (w));
17186 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
17187 struct buffer *b = current_buffer;
17188
17189 obj = Qnil;
17190 *multibyte = 0;
17191
17192 switch (c)
17193 {
17194 case '*':
17195 if (!NILP (b->read_only))
17196 return "%";
17197 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17198 return "*";
17199 return "-";
17200
17201 case '+':
17202 /* This differs from %* only for a modified read-only buffer. */
17203 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17204 return "*";
17205 if (!NILP (b->read_only))
17206 return "%";
17207 return "-";
17208
17209 case '&':
17210 /* This differs from %* in ignoring read-only-ness. */
17211 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17212 return "*";
17213 return "-";
17214
17215 case '%':
17216 return "%";
17217
17218 case '[':
17219 {
17220 int i;
17221 char *p;
17222
17223 if (command_loop_level > 5)
17224 return "[[[... ";
17225 p = decode_mode_spec_buf;
17226 for (i = 0; i < command_loop_level; i++)
17227 *p++ = '[';
17228 *p = 0;
17229 return decode_mode_spec_buf;
17230 }
17231
17232 case ']':
17233 {
17234 int i;
17235 char *p;
17236
17237 if (command_loop_level > 5)
17238 return " ...]]]";
17239 p = decode_mode_spec_buf;
17240 for (i = 0; i < command_loop_level; i++)
17241 *p++ = ']';
17242 *p = 0;
17243 return decode_mode_spec_buf;
17244 }
17245
17246 case '-':
17247 {
17248 register int i;
17249
17250 /* Let lots_of_dashes be a string of infinite length. */
17251 if (mode_line_target == MODE_LINE_NOPROP ||
17252 mode_line_target == MODE_LINE_STRING)
17253 return "--";
17254 if (field_width <= 0
17255 || field_width > sizeof (lots_of_dashes))
17256 {
17257 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
17258 decode_mode_spec_buf[i] = '-';
17259 decode_mode_spec_buf[i] = '\0';
17260 return decode_mode_spec_buf;
17261 }
17262 else
17263 return lots_of_dashes;
17264 }
17265
17266 case 'b':
17267 obj = b->name;
17268 break;
17269
17270 case 'c':
17271 {
17272 int col = (int) current_column (); /* iftc */
17273 w->column_number_displayed = make_number (col);
17274 pint2str (decode_mode_spec_buf, field_width, col);
17275 return decode_mode_spec_buf;
17276 }
17277
17278 case 'e':
17279 #ifndef SYSTEM_MALLOC
17280 {
17281 if (NILP (Vmemory_full))
17282 return "";
17283 else
17284 return "!MEM FULL! ";
17285 }
17286 #else
17287 return "";
17288 #endif
17289
17290 case 'F':
17291 /* %F displays the frame name. */
17292 if (!NILP (f->title))
17293 return (char *) SDATA (f->title);
17294 if (f->explicit_name || ! FRAME_WINDOW_P (f))
17295 return (char *) SDATA (f->name);
17296 return "Emacs";
17297
17298 case 'f':
17299 obj = b->filename;
17300 break;
17301
17302 case 'i':
17303 {
17304 int size = ZV - BEGV;
17305 pint2str (decode_mode_spec_buf, field_width, size);
17306 return decode_mode_spec_buf;
17307 }
17308
17309 case 'I':
17310 {
17311 int size = ZV - BEGV;
17312 pint2hrstr (decode_mode_spec_buf, field_width, size);
17313 return decode_mode_spec_buf;
17314 }
17315
17316 case 'l':
17317 {
17318 int startpos = XMARKER (w->start)->charpos;
17319 int startpos_byte = marker_byte_position (w->start);
17320 int line, linepos, linepos_byte, topline;
17321 int nlines, junk;
17322 int height = WINDOW_TOTAL_LINES (w);
17323
17324 /* If we decided that this buffer isn't suitable for line numbers,
17325 don't forget that too fast. */
17326 if (EQ (w->base_line_pos, w->buffer))
17327 goto no_value;
17328 /* But do forget it, if the window shows a different buffer now. */
17329 else if (BUFFERP (w->base_line_pos))
17330 w->base_line_pos = Qnil;
17331
17332 /* If the buffer is very big, don't waste time. */
17333 if (INTEGERP (Vline_number_display_limit)
17334 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
17335 {
17336 w->base_line_pos = Qnil;
17337 w->base_line_number = Qnil;
17338 goto no_value;
17339 }
17340
17341 if (!NILP (w->base_line_number)
17342 && !NILP (w->base_line_pos)
17343 && XFASTINT (w->base_line_pos) <= startpos)
17344 {
17345 line = XFASTINT (w->base_line_number);
17346 linepos = XFASTINT (w->base_line_pos);
17347 linepos_byte = buf_charpos_to_bytepos (b, linepos);
17348 }
17349 else
17350 {
17351 line = 1;
17352 linepos = BUF_BEGV (b);
17353 linepos_byte = BUF_BEGV_BYTE (b);
17354 }
17355
17356 /* Count lines from base line to window start position. */
17357 nlines = display_count_lines (linepos, linepos_byte,
17358 startpos_byte,
17359 startpos, &junk);
17360
17361 topline = nlines + line;
17362
17363 /* Determine a new base line, if the old one is too close
17364 or too far away, or if we did not have one.
17365 "Too close" means it's plausible a scroll-down would
17366 go back past it. */
17367 if (startpos == BUF_BEGV (b))
17368 {
17369 w->base_line_number = make_number (topline);
17370 w->base_line_pos = make_number (BUF_BEGV (b));
17371 }
17372 else if (nlines < height + 25 || nlines > height * 3 + 50
17373 || linepos == BUF_BEGV (b))
17374 {
17375 int limit = BUF_BEGV (b);
17376 int limit_byte = BUF_BEGV_BYTE (b);
17377 int position;
17378 int distance = (height * 2 + 30) * line_number_display_limit_width;
17379
17380 if (startpos - distance > limit)
17381 {
17382 limit = startpos - distance;
17383 limit_byte = CHAR_TO_BYTE (limit);
17384 }
17385
17386 nlines = display_count_lines (startpos, startpos_byte,
17387 limit_byte,
17388 - (height * 2 + 30),
17389 &position);
17390 /* If we couldn't find the lines we wanted within
17391 line_number_display_limit_width chars per line,
17392 give up on line numbers for this window. */
17393 if (position == limit_byte && limit == startpos - distance)
17394 {
17395 w->base_line_pos = w->buffer;
17396 w->base_line_number = Qnil;
17397 goto no_value;
17398 }
17399
17400 w->base_line_number = make_number (topline - nlines);
17401 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
17402 }
17403
17404 /* Now count lines from the start pos to point. */
17405 nlines = display_count_lines (startpos, startpos_byte,
17406 PT_BYTE, PT, &junk);
17407
17408 /* Record that we did display the line number. */
17409 line_number_displayed = 1;
17410
17411 /* Make the string to show. */
17412 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
17413 return decode_mode_spec_buf;
17414 no_value:
17415 {
17416 char* p = decode_mode_spec_buf;
17417 int pad = field_width - 2;
17418 while (pad-- > 0)
17419 *p++ = ' ';
17420 *p++ = '?';
17421 *p++ = '?';
17422 *p = '\0';
17423 return decode_mode_spec_buf;
17424 }
17425 }
17426 break;
17427
17428 case 'm':
17429 obj = b->mode_name;
17430 break;
17431
17432 case 'n':
17433 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
17434 return " Narrow";
17435 break;
17436
17437 case 'p':
17438 {
17439 int pos = marker_position (w->start);
17440 int total = BUF_ZV (b) - BUF_BEGV (b);
17441
17442 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
17443 {
17444 if (pos <= BUF_BEGV (b))
17445 return "All";
17446 else
17447 return "Bottom";
17448 }
17449 else if (pos <= BUF_BEGV (b))
17450 return "Top";
17451 else
17452 {
17453 if (total > 1000000)
17454 /* Do it differently for a large value, to avoid overflow. */
17455 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
17456 else
17457 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
17458 /* We can't normally display a 3-digit number,
17459 so get us a 2-digit number that is close. */
17460 if (total == 100)
17461 total = 99;
17462 sprintf (decode_mode_spec_buf, "%2d%%", total);
17463 return decode_mode_spec_buf;
17464 }
17465 }
17466
17467 /* Display percentage of size above the bottom of the screen. */
17468 case 'P':
17469 {
17470 int toppos = marker_position (w->start);
17471 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
17472 int total = BUF_ZV (b) - BUF_BEGV (b);
17473
17474 if (botpos >= BUF_ZV (b))
17475 {
17476 if (toppos <= BUF_BEGV (b))
17477 return "All";
17478 else
17479 return "Bottom";
17480 }
17481 else
17482 {
17483 if (total > 1000000)
17484 /* Do it differently for a large value, to avoid overflow. */
17485 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
17486 else
17487 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
17488 /* We can't normally display a 3-digit number,
17489 so get us a 2-digit number that is close. */
17490 if (total == 100)
17491 total = 99;
17492 if (toppos <= BUF_BEGV (b))
17493 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
17494 else
17495 sprintf (decode_mode_spec_buf, "%2d%%", total);
17496 return decode_mode_spec_buf;
17497 }
17498 }
17499
17500 case 's':
17501 /* status of process */
17502 obj = Fget_buffer_process (Fcurrent_buffer ());
17503 if (NILP (obj))
17504 return "no process";
17505 #ifdef subprocesses
17506 obj = Fsymbol_name (Fprocess_status (obj));
17507 #endif
17508 break;
17509
17510 case 't': /* indicate TEXT or BINARY */
17511 #ifdef MODE_LINE_BINARY_TEXT
17512 return MODE_LINE_BINARY_TEXT (b);
17513 #else
17514 return "T";
17515 #endif
17516
17517 case 'z':
17518 /* coding-system (not including end-of-line format) */
17519 case 'Z':
17520 /* coding-system (including end-of-line type) */
17521 {
17522 int eol_flag = (c == 'Z');
17523 char *p = decode_mode_spec_buf;
17524
17525 if (! FRAME_WINDOW_P (f))
17526 {
17527 /* No need to mention EOL here--the terminal never needs
17528 to do EOL conversion. */
17529 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
17530 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
17531 }
17532 p = decode_mode_spec_coding (b->buffer_file_coding_system,
17533 p, eol_flag);
17534
17535 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
17536 #ifdef subprocesses
17537 obj = Fget_buffer_process (Fcurrent_buffer ());
17538 if (PROCESSP (obj))
17539 {
17540 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
17541 p, eol_flag);
17542 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
17543 p, eol_flag);
17544 }
17545 #endif /* subprocesses */
17546 #endif /* 0 */
17547 *p = 0;
17548 return decode_mode_spec_buf;
17549 }
17550 }
17551
17552 if (STRINGP (obj))
17553 {
17554 *multibyte = STRING_MULTIBYTE (obj);
17555 return (char *) SDATA (obj);
17556 }
17557 else
17558 return "";
17559 }
17560
17561
17562 /* Count up to COUNT lines starting from START / START_BYTE.
17563 But don't go beyond LIMIT_BYTE.
17564 Return the number of lines thus found (always nonnegative).
17565
17566 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
17567
17568 static int
17569 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
17570 int start, start_byte, limit_byte, count;
17571 int *byte_pos_ptr;
17572 {
17573 register unsigned char *cursor;
17574 unsigned char *base;
17575
17576 register int ceiling;
17577 register unsigned char *ceiling_addr;
17578 int orig_count = count;
17579
17580 /* If we are not in selective display mode,
17581 check only for newlines. */
17582 int selective_display = (!NILP (current_buffer->selective_display)
17583 && !INTEGERP (current_buffer->selective_display));
17584
17585 if (count > 0)
17586 {
17587 while (start_byte < limit_byte)
17588 {
17589 ceiling = BUFFER_CEILING_OF (start_byte);
17590 ceiling = min (limit_byte - 1, ceiling);
17591 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
17592 base = (cursor = BYTE_POS_ADDR (start_byte));
17593 while (1)
17594 {
17595 if (selective_display)
17596 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
17597 ;
17598 else
17599 while (*cursor != '\n' && ++cursor != ceiling_addr)
17600 ;
17601
17602 if (cursor != ceiling_addr)
17603 {
17604 if (--count == 0)
17605 {
17606 start_byte += cursor - base + 1;
17607 *byte_pos_ptr = start_byte;
17608 return orig_count;
17609 }
17610 else
17611 if (++cursor == ceiling_addr)
17612 break;
17613 }
17614 else
17615 break;
17616 }
17617 start_byte += cursor - base;
17618 }
17619 }
17620 else
17621 {
17622 while (start_byte > limit_byte)
17623 {
17624 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
17625 ceiling = max (limit_byte, ceiling);
17626 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
17627 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
17628 while (1)
17629 {
17630 if (selective_display)
17631 while (--cursor != ceiling_addr
17632 && *cursor != '\n' && *cursor != 015)
17633 ;
17634 else
17635 while (--cursor != ceiling_addr && *cursor != '\n')
17636 ;
17637
17638 if (cursor != ceiling_addr)
17639 {
17640 if (++count == 0)
17641 {
17642 start_byte += cursor - base + 1;
17643 *byte_pos_ptr = start_byte;
17644 /* When scanning backwards, we should
17645 not count the newline posterior to which we stop. */
17646 return - orig_count - 1;
17647 }
17648 }
17649 else
17650 break;
17651 }
17652 /* Here we add 1 to compensate for the last decrement
17653 of CURSOR, which took it past the valid range. */
17654 start_byte += cursor - base + 1;
17655 }
17656 }
17657
17658 *byte_pos_ptr = limit_byte;
17659
17660 if (count < 0)
17661 return - orig_count + count;
17662 return orig_count - count;
17663
17664 }
17665
17666
17667 \f
17668 /***********************************************************************
17669 Displaying strings
17670 ***********************************************************************/
17671
17672 /* Display a NUL-terminated string, starting with index START.
17673
17674 If STRING is non-null, display that C string. Otherwise, the Lisp
17675 string LISP_STRING is displayed.
17676
17677 If FACE_STRING is not nil, FACE_STRING_POS is a position in
17678 FACE_STRING. Display STRING or LISP_STRING with the face at
17679 FACE_STRING_POS in FACE_STRING:
17680
17681 Display the string in the environment given by IT, but use the
17682 standard display table, temporarily.
17683
17684 FIELD_WIDTH is the minimum number of output glyphs to produce.
17685 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17686 with spaces. If STRING has more characters, more than FIELD_WIDTH
17687 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
17688
17689 PRECISION is the maximum number of characters to output from
17690 STRING. PRECISION < 0 means don't truncate the string.
17691
17692 This is roughly equivalent to printf format specifiers:
17693
17694 FIELD_WIDTH PRECISION PRINTF
17695 ----------------------------------------
17696 -1 -1 %s
17697 -1 10 %.10s
17698 10 -1 %10s
17699 20 10 %20.10s
17700
17701 MULTIBYTE zero means do not display multibyte chars, > 0 means do
17702 display them, and < 0 means obey the current buffer's value of
17703 enable_multibyte_characters.
17704
17705 Value is the number of glyphs produced. */
17706
17707 static int
17708 display_string (string, lisp_string, face_string, face_string_pos,
17709 start, it, field_width, precision, max_x, multibyte)
17710 unsigned char *string;
17711 Lisp_Object lisp_string;
17712 Lisp_Object face_string;
17713 int face_string_pos;
17714 int start;
17715 struct it *it;
17716 int field_width, precision, max_x;
17717 int multibyte;
17718 {
17719 int hpos_at_start = it->hpos;
17720 int saved_face_id = it->face_id;
17721 struct glyph_row *row = it->glyph_row;
17722
17723 /* Initialize the iterator IT for iteration over STRING beginning
17724 with index START. */
17725 reseat_to_string (it, string, lisp_string, start,
17726 precision, field_width, multibyte);
17727
17728 /* If displaying STRING, set up the face of the iterator
17729 from LISP_STRING, if that's given. */
17730 if (STRINGP (face_string))
17731 {
17732 int endptr;
17733 struct face *face;
17734
17735 it->face_id
17736 = face_at_string_position (it->w, face_string, face_string_pos,
17737 0, it->region_beg_charpos,
17738 it->region_end_charpos,
17739 &endptr, it->base_face_id, 0);
17740 face = FACE_FROM_ID (it->f, it->face_id);
17741 it->face_box_p = face->box != FACE_NO_BOX;
17742 }
17743
17744 /* Set max_x to the maximum allowed X position. Don't let it go
17745 beyond the right edge of the window. */
17746 if (max_x <= 0)
17747 max_x = it->last_visible_x;
17748 else
17749 max_x = min (max_x, it->last_visible_x);
17750
17751 /* Skip over display elements that are not visible. because IT->w is
17752 hscrolled. */
17753 if (it->current_x < it->first_visible_x)
17754 move_it_in_display_line_to (it, 100000, it->first_visible_x,
17755 MOVE_TO_POS | MOVE_TO_X);
17756
17757 row->ascent = it->max_ascent;
17758 row->height = it->max_ascent + it->max_descent;
17759 row->phys_ascent = it->max_phys_ascent;
17760 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17761 row->extra_line_spacing = it->max_extra_line_spacing;
17762
17763 /* This condition is for the case that we are called with current_x
17764 past last_visible_x. */
17765 while (it->current_x < max_x)
17766 {
17767 int x_before, x, n_glyphs_before, i, nglyphs;
17768
17769 /* Get the next display element. */
17770 if (!get_next_display_element (it))
17771 break;
17772
17773 /* Produce glyphs. */
17774 x_before = it->current_x;
17775 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
17776 PRODUCE_GLYPHS (it);
17777
17778 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
17779 i = 0;
17780 x = x_before;
17781 while (i < nglyphs)
17782 {
17783 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17784
17785 if (!it->truncate_lines_p
17786 && x + glyph->pixel_width > max_x)
17787 {
17788 /* End of continued line or max_x reached. */
17789 if (CHAR_GLYPH_PADDING_P (*glyph))
17790 {
17791 /* A wide character is unbreakable. */
17792 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
17793 it->current_x = x_before;
17794 }
17795 else
17796 {
17797 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
17798 it->current_x = x;
17799 }
17800 break;
17801 }
17802 else if (x + glyph->pixel_width > it->first_visible_x)
17803 {
17804 /* Glyph is at least partially visible. */
17805 ++it->hpos;
17806 if (x < it->first_visible_x)
17807 it->glyph_row->x = x - it->first_visible_x;
17808 }
17809 else
17810 {
17811 /* Glyph is off the left margin of the display area.
17812 Should not happen. */
17813 abort ();
17814 }
17815
17816 row->ascent = max (row->ascent, it->max_ascent);
17817 row->height = max (row->height, it->max_ascent + it->max_descent);
17818 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17819 row->phys_height = max (row->phys_height,
17820 it->max_phys_ascent + it->max_phys_descent);
17821 row->extra_line_spacing = max (row->extra_line_spacing,
17822 it->max_extra_line_spacing);
17823 x += glyph->pixel_width;
17824 ++i;
17825 }
17826
17827 /* Stop if max_x reached. */
17828 if (i < nglyphs)
17829 break;
17830
17831 /* Stop at line ends. */
17832 if (ITERATOR_AT_END_OF_LINE_P (it))
17833 {
17834 it->continuation_lines_width = 0;
17835 break;
17836 }
17837
17838 set_iterator_to_next (it, 1);
17839
17840 /* Stop if truncating at the right edge. */
17841 if (it->truncate_lines_p
17842 && it->current_x >= it->last_visible_x)
17843 {
17844 /* Add truncation mark, but don't do it if the line is
17845 truncated at a padding space. */
17846 if (IT_CHARPOS (*it) < it->string_nchars)
17847 {
17848 if (!FRAME_WINDOW_P (it->f))
17849 {
17850 int i, n;
17851
17852 if (it->current_x > it->last_visible_x)
17853 {
17854 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17855 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17856 break;
17857 for (n = row->used[TEXT_AREA]; i < n; ++i)
17858 {
17859 row->used[TEXT_AREA] = i;
17860 produce_special_glyphs (it, IT_TRUNCATION);
17861 }
17862 }
17863 produce_special_glyphs (it, IT_TRUNCATION);
17864 }
17865 it->glyph_row->truncated_on_right_p = 1;
17866 }
17867 break;
17868 }
17869 }
17870
17871 /* Maybe insert a truncation at the left. */
17872 if (it->first_visible_x
17873 && IT_CHARPOS (*it) > 0)
17874 {
17875 if (!FRAME_WINDOW_P (it->f))
17876 insert_left_trunc_glyphs (it);
17877 it->glyph_row->truncated_on_left_p = 1;
17878 }
17879
17880 it->face_id = saved_face_id;
17881
17882 /* Value is number of columns displayed. */
17883 return it->hpos - hpos_at_start;
17884 }
17885
17886
17887 \f
17888 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
17889 appears as an element of LIST or as the car of an element of LIST.
17890 If PROPVAL is a list, compare each element against LIST in that
17891 way, and return 1/2 if any element of PROPVAL is found in LIST.
17892 Otherwise return 0. This function cannot quit.
17893 The return value is 2 if the text is invisible but with an ellipsis
17894 and 1 if it's invisible and without an ellipsis. */
17895
17896 int
17897 invisible_p (propval, list)
17898 register Lisp_Object propval;
17899 Lisp_Object list;
17900 {
17901 register Lisp_Object tail, proptail;
17902
17903 for (tail = list; CONSP (tail); tail = XCDR (tail))
17904 {
17905 register Lisp_Object tem;
17906 tem = XCAR (tail);
17907 if (EQ (propval, tem))
17908 return 1;
17909 if (CONSP (tem) && EQ (propval, XCAR (tem)))
17910 return NILP (XCDR (tem)) ? 1 : 2;
17911 }
17912
17913 if (CONSP (propval))
17914 {
17915 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
17916 {
17917 Lisp_Object propelt;
17918 propelt = XCAR (proptail);
17919 for (tail = list; CONSP (tail); tail = XCDR (tail))
17920 {
17921 register Lisp_Object tem;
17922 tem = XCAR (tail);
17923 if (EQ (propelt, tem))
17924 return 1;
17925 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
17926 return NILP (XCDR (tem)) ? 1 : 2;
17927 }
17928 }
17929 }
17930
17931 return 0;
17932 }
17933
17934 /* Calculate a width or height in pixels from a specification using
17935 the following elements:
17936
17937 SPEC ::=
17938 NUM - a (fractional) multiple of the default font width/height
17939 (NUM) - specifies exactly NUM pixels
17940 UNIT - a fixed number of pixels, see below.
17941 ELEMENT - size of a display element in pixels, see below.
17942 (NUM . SPEC) - equals NUM * SPEC
17943 (+ SPEC SPEC ...) - add pixel values
17944 (- SPEC SPEC ...) - subtract pixel values
17945 (- SPEC) - negate pixel value
17946
17947 NUM ::=
17948 INT or FLOAT - a number constant
17949 SYMBOL - use symbol's (buffer local) variable binding.
17950
17951 UNIT ::=
17952 in - pixels per inch *)
17953 mm - pixels per 1/1000 meter *)
17954 cm - pixels per 1/100 meter *)
17955 width - width of current font in pixels.
17956 height - height of current font in pixels.
17957
17958 *) using the ratio(s) defined in display-pixels-per-inch.
17959
17960 ELEMENT ::=
17961
17962 left-fringe - left fringe width in pixels
17963 right-fringe - right fringe width in pixels
17964
17965 left-margin - left margin width in pixels
17966 right-margin - right margin width in pixels
17967
17968 scroll-bar - scroll-bar area width in pixels
17969
17970 Examples:
17971
17972 Pixels corresponding to 5 inches:
17973 (5 . in)
17974
17975 Total width of non-text areas on left side of window (if scroll-bar is on left):
17976 '(space :width (+ left-fringe left-margin scroll-bar))
17977
17978 Align to first text column (in header line):
17979 '(space :align-to 0)
17980
17981 Align to middle of text area minus half the width of variable `my-image'
17982 containing a loaded image:
17983 '(space :align-to (0.5 . (- text my-image)))
17984
17985 Width of left margin minus width of 1 character in the default font:
17986 '(space :width (- left-margin 1))
17987
17988 Width of left margin minus width of 2 characters in the current font:
17989 '(space :width (- left-margin (2 . width)))
17990
17991 Center 1 character over left-margin (in header line):
17992 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17993
17994 Different ways to express width of left fringe plus left margin minus one pixel:
17995 '(space :width (- (+ left-fringe left-margin) (1)))
17996 '(space :width (+ left-fringe left-margin (- (1))))
17997 '(space :width (+ left-fringe left-margin (-1)))
17998
17999 */
18000
18001 #define NUMVAL(X) \
18002 ((INTEGERP (X) || FLOATP (X)) \
18003 ? XFLOATINT (X) \
18004 : - 1)
18005
18006 int
18007 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
18008 double *res;
18009 struct it *it;
18010 Lisp_Object prop;
18011 void *font;
18012 int width_p, *align_to;
18013 {
18014 double pixels;
18015
18016 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
18017 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
18018
18019 if (NILP (prop))
18020 return OK_PIXELS (0);
18021
18022 if (SYMBOLP (prop))
18023 {
18024 if (SCHARS (SYMBOL_NAME (prop)) == 2)
18025 {
18026 char *unit = SDATA (SYMBOL_NAME (prop));
18027
18028 if (unit[0] == 'i' && unit[1] == 'n')
18029 pixels = 1.0;
18030 else if (unit[0] == 'm' && unit[1] == 'm')
18031 pixels = 25.4;
18032 else if (unit[0] == 'c' && unit[1] == 'm')
18033 pixels = 2.54;
18034 else
18035 pixels = 0;
18036 if (pixels > 0)
18037 {
18038 double ppi;
18039 #ifdef HAVE_WINDOW_SYSTEM
18040 if (FRAME_WINDOW_P (it->f)
18041 && (ppi = (width_p
18042 ? FRAME_X_DISPLAY_INFO (it->f)->resx
18043 : FRAME_X_DISPLAY_INFO (it->f)->resy),
18044 ppi > 0))
18045 return OK_PIXELS (ppi / pixels);
18046 #endif
18047
18048 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
18049 || (CONSP (Vdisplay_pixels_per_inch)
18050 && (ppi = (width_p
18051 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
18052 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
18053 ppi > 0)))
18054 return OK_PIXELS (ppi / pixels);
18055
18056 return 0;
18057 }
18058 }
18059
18060 #ifdef HAVE_WINDOW_SYSTEM
18061 if (EQ (prop, Qheight))
18062 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
18063 if (EQ (prop, Qwidth))
18064 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
18065 #else
18066 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
18067 return OK_PIXELS (1);
18068 #endif
18069
18070 if (EQ (prop, Qtext))
18071 return OK_PIXELS (width_p
18072 ? window_box_width (it->w, TEXT_AREA)
18073 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
18074
18075 if (align_to && *align_to < 0)
18076 {
18077 *res = 0;
18078 if (EQ (prop, Qleft))
18079 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
18080 if (EQ (prop, Qright))
18081 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
18082 if (EQ (prop, Qcenter))
18083 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
18084 + window_box_width (it->w, TEXT_AREA) / 2);
18085 if (EQ (prop, Qleft_fringe))
18086 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18087 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
18088 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
18089 if (EQ (prop, Qright_fringe))
18090 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18091 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18092 : window_box_right_offset (it->w, TEXT_AREA));
18093 if (EQ (prop, Qleft_margin))
18094 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
18095 if (EQ (prop, Qright_margin))
18096 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
18097 if (EQ (prop, Qscroll_bar))
18098 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18099 ? 0
18100 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18101 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18102 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18103 : 0)));
18104 }
18105 else
18106 {
18107 if (EQ (prop, Qleft_fringe))
18108 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
18109 if (EQ (prop, Qright_fringe))
18110 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
18111 if (EQ (prop, Qleft_margin))
18112 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
18113 if (EQ (prop, Qright_margin))
18114 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
18115 if (EQ (prop, Qscroll_bar))
18116 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
18117 }
18118
18119 prop = Fbuffer_local_value (prop, it->w->buffer);
18120 }
18121
18122 if (INTEGERP (prop) || FLOATP (prop))
18123 {
18124 int base_unit = (width_p
18125 ? FRAME_COLUMN_WIDTH (it->f)
18126 : FRAME_LINE_HEIGHT (it->f));
18127 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18128 }
18129
18130 if (CONSP (prop))
18131 {
18132 Lisp_Object car = XCAR (prop);
18133 Lisp_Object cdr = XCDR (prop);
18134
18135 if (SYMBOLP (car))
18136 {
18137 #ifdef HAVE_WINDOW_SYSTEM
18138 if (valid_image_p (prop))
18139 {
18140 int id = lookup_image (it->f, prop);
18141 struct image *img = IMAGE_FROM_ID (it->f, id);
18142
18143 return OK_PIXELS (width_p ? img->width : img->height);
18144 }
18145 #endif
18146 if (EQ (car, Qplus) || EQ (car, Qminus))
18147 {
18148 int first = 1;
18149 double px;
18150
18151 pixels = 0;
18152 while (CONSP (cdr))
18153 {
18154 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
18155 font, width_p, align_to))
18156 return 0;
18157 if (first)
18158 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18159 else
18160 pixels += px;
18161 cdr = XCDR (cdr);
18162 }
18163 if (EQ (car, Qminus))
18164 pixels = -pixels;
18165 return OK_PIXELS (pixels);
18166 }
18167
18168 car = Fbuffer_local_value (car, it->w->buffer);
18169 }
18170
18171 if (INTEGERP (car) || FLOATP (car))
18172 {
18173 double fact;
18174 pixels = XFLOATINT (car);
18175 if (NILP (cdr))
18176 return OK_PIXELS (pixels);
18177 if (calc_pixel_width_or_height (&fact, it, cdr,
18178 font, width_p, align_to))
18179 return OK_PIXELS (pixels * fact);
18180 return 0;
18181 }
18182
18183 return 0;
18184 }
18185
18186 return 0;
18187 }
18188
18189 \f
18190 /***********************************************************************
18191 Glyph Display
18192 ***********************************************************************/
18193
18194 #ifdef HAVE_WINDOW_SYSTEM
18195
18196 #if GLYPH_DEBUG
18197
18198 void
18199 dump_glyph_string (s)
18200 struct glyph_string *s;
18201 {
18202 fprintf (stderr, "glyph string\n");
18203 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
18204 s->x, s->y, s->width, s->height);
18205 fprintf (stderr, " ybase = %d\n", s->ybase);
18206 fprintf (stderr, " hl = %d\n", s->hl);
18207 fprintf (stderr, " left overhang = %d, right = %d\n",
18208 s->left_overhang, s->right_overhang);
18209 fprintf (stderr, " nchars = %d\n", s->nchars);
18210 fprintf (stderr, " extends to end of line = %d\n",
18211 s->extends_to_end_of_line_p);
18212 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
18213 fprintf (stderr, " bg width = %d\n", s->background_width);
18214 }
18215
18216 #endif /* GLYPH_DEBUG */
18217
18218 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
18219 of XChar2b structures for S; it can't be allocated in
18220 init_glyph_string because it must be allocated via `alloca'. W
18221 is the window on which S is drawn. ROW and AREA are the glyph row
18222 and area within the row from which S is constructed. START is the
18223 index of the first glyph structure covered by S. HL is a
18224 face-override for drawing S. */
18225
18226 #ifdef HAVE_NTGUI
18227 #define OPTIONAL_HDC(hdc) hdc,
18228 #define DECLARE_HDC(hdc) HDC hdc;
18229 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
18230 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
18231 #endif
18232
18233 #ifndef OPTIONAL_HDC
18234 #define OPTIONAL_HDC(hdc)
18235 #define DECLARE_HDC(hdc)
18236 #define ALLOCATE_HDC(hdc, f)
18237 #define RELEASE_HDC(hdc, f)
18238 #endif
18239
18240 static void
18241 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
18242 struct glyph_string *s;
18243 DECLARE_HDC (hdc)
18244 XChar2b *char2b;
18245 struct window *w;
18246 struct glyph_row *row;
18247 enum glyph_row_area area;
18248 int start;
18249 enum draw_glyphs_face hl;
18250 {
18251 bzero (s, sizeof *s);
18252 s->w = w;
18253 s->f = XFRAME (w->frame);
18254 #ifdef HAVE_NTGUI
18255 s->hdc = hdc;
18256 #endif
18257 s->display = FRAME_X_DISPLAY (s->f);
18258 s->window = FRAME_X_WINDOW (s->f);
18259 s->char2b = char2b;
18260 s->hl = hl;
18261 s->row = row;
18262 s->area = area;
18263 s->first_glyph = row->glyphs[area] + start;
18264 s->height = row->height;
18265 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
18266
18267 /* Display the internal border below the tool-bar window. */
18268 if (WINDOWP (s->f->tool_bar_window)
18269 && s->w == XWINDOW (s->f->tool_bar_window))
18270 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
18271
18272 s->ybase = s->y + row->ascent;
18273 }
18274
18275
18276 /* Append the list of glyph strings with head H and tail T to the list
18277 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
18278
18279 static INLINE void
18280 append_glyph_string_lists (head, tail, h, t)
18281 struct glyph_string **head, **tail;
18282 struct glyph_string *h, *t;
18283 {
18284 if (h)
18285 {
18286 if (*head)
18287 (*tail)->next = h;
18288 else
18289 *head = h;
18290 h->prev = *tail;
18291 *tail = t;
18292 }
18293 }
18294
18295
18296 /* Prepend the list of glyph strings with head H and tail T to the
18297 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
18298 result. */
18299
18300 static INLINE void
18301 prepend_glyph_string_lists (head, tail, h, t)
18302 struct glyph_string **head, **tail;
18303 struct glyph_string *h, *t;
18304 {
18305 if (h)
18306 {
18307 if (*head)
18308 (*head)->prev = t;
18309 else
18310 *tail = t;
18311 t->next = *head;
18312 *head = h;
18313 }
18314 }
18315
18316
18317 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
18318 Set *HEAD and *TAIL to the resulting list. */
18319
18320 static INLINE void
18321 append_glyph_string (head, tail, s)
18322 struct glyph_string **head, **tail;
18323 struct glyph_string *s;
18324 {
18325 s->next = s->prev = NULL;
18326 append_glyph_string_lists (head, tail, s, s);
18327 }
18328
18329
18330 /* Get face and two-byte form of character glyph GLYPH on frame F.
18331 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
18332 a pointer to a realized face that is ready for display. */
18333
18334 static INLINE struct face *
18335 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
18336 struct frame *f;
18337 struct glyph *glyph;
18338 XChar2b *char2b;
18339 int *two_byte_p;
18340 {
18341 struct face *face;
18342
18343 xassert (glyph->type == CHAR_GLYPH);
18344 face = FACE_FROM_ID (f, glyph->face_id);
18345
18346 if (two_byte_p)
18347 *two_byte_p = 0;
18348
18349 if (!glyph->multibyte_p)
18350 {
18351 /* Unibyte case. We don't have to encode, but we have to make
18352 sure to use a face suitable for unibyte. */
18353 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
18354 }
18355 else if (glyph->u.ch < 128
18356 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
18357 {
18358 /* Case of ASCII in a face known to fit ASCII. */
18359 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
18360 }
18361 else
18362 {
18363 int c1, c2, charset;
18364
18365 /* Split characters into bytes. If c2 is -1 afterwards, C is
18366 really a one-byte character so that byte1 is zero. */
18367 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
18368 if (c2 > 0)
18369 STORE_XCHAR2B (char2b, c1, c2);
18370 else
18371 STORE_XCHAR2B (char2b, 0, c1);
18372
18373 /* Maybe encode the character in *CHAR2B. */
18374 if (charset != CHARSET_ASCII)
18375 {
18376 struct font_info *font_info
18377 = FONT_INFO_FROM_ID (f, face->font_info_id);
18378 if (font_info)
18379 glyph->font_type
18380 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
18381 }
18382 }
18383
18384 /* Make sure X resources of the face are allocated. */
18385 xassert (face != NULL);
18386 PREPARE_FACE_FOR_DISPLAY (f, face);
18387 return face;
18388 }
18389
18390
18391 /* Fill glyph string S with composition components specified by S->cmp.
18392
18393 FACES is an array of faces for all components of this composition.
18394 S->gidx is the index of the first component for S.
18395
18396 OVERLAPS non-zero means S should draw the foreground only, and use
18397 its physical height for clipping. See also draw_glyphs.
18398
18399 Value is the index of a component not in S. */
18400
18401 static int
18402 fill_composite_glyph_string (s, faces, overlaps)
18403 struct glyph_string *s;
18404 struct face **faces;
18405 int overlaps;
18406 {
18407 int i;
18408
18409 xassert (s);
18410
18411 s->for_overlaps = overlaps;
18412
18413 s->face = faces[s->gidx];
18414 s->font = s->face->font;
18415 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18416
18417 /* For all glyphs of this composition, starting at the offset
18418 S->gidx, until we reach the end of the definition or encounter a
18419 glyph that requires the different face, add it to S. */
18420 ++s->nchars;
18421 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
18422 ++s->nchars;
18423
18424 /* All glyph strings for the same composition has the same width,
18425 i.e. the width set for the first component of the composition. */
18426
18427 s->width = s->first_glyph->pixel_width;
18428
18429 /* If the specified font could not be loaded, use the frame's
18430 default font, but record the fact that we couldn't load it in
18431 the glyph string so that we can draw rectangles for the
18432 characters of the glyph string. */
18433 if (s->font == NULL)
18434 {
18435 s->font_not_found_p = 1;
18436 s->font = FRAME_FONT (s->f);
18437 }
18438
18439 /* Adjust base line for subscript/superscript text. */
18440 s->ybase += s->first_glyph->voffset;
18441
18442 xassert (s->face && s->face->gc);
18443
18444 /* This glyph string must always be drawn with 16-bit functions. */
18445 s->two_byte_p = 1;
18446
18447 return s->gidx + s->nchars;
18448 }
18449
18450
18451 /* Fill glyph string S from a sequence of character glyphs.
18452
18453 FACE_ID is the face id of the string. START is the index of the
18454 first glyph to consider, END is the index of the last + 1.
18455 OVERLAPS non-zero means S should draw the foreground only, and use
18456 its physical height for clipping. See also draw_glyphs.
18457
18458 Value is the index of the first glyph not in S. */
18459
18460 static int
18461 fill_glyph_string (s, face_id, start, end, overlaps)
18462 struct glyph_string *s;
18463 int face_id;
18464 int start, end, overlaps;
18465 {
18466 struct glyph *glyph, *last;
18467 int voffset;
18468 int glyph_not_available_p;
18469
18470 xassert (s->f == XFRAME (s->w->frame));
18471 xassert (s->nchars == 0);
18472 xassert (start >= 0 && end > start);
18473
18474 s->for_overlaps = overlaps,
18475 glyph = s->row->glyphs[s->area] + start;
18476 last = s->row->glyphs[s->area] + end;
18477 voffset = glyph->voffset;
18478
18479 glyph_not_available_p = glyph->glyph_not_available_p;
18480
18481 while (glyph < last
18482 && glyph->type == CHAR_GLYPH
18483 && glyph->voffset == voffset
18484 /* Same face id implies same font, nowadays. */
18485 && glyph->face_id == face_id
18486 && glyph->glyph_not_available_p == glyph_not_available_p)
18487 {
18488 int two_byte_p;
18489
18490 s->face = get_glyph_face_and_encoding (s->f, glyph,
18491 s->char2b + s->nchars,
18492 &two_byte_p);
18493 s->two_byte_p = two_byte_p;
18494 ++s->nchars;
18495 xassert (s->nchars <= end - start);
18496 s->width += glyph->pixel_width;
18497 ++glyph;
18498 }
18499
18500 s->font = s->face->font;
18501 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18502
18503 /* If the specified font could not be loaded, use the frame's font,
18504 but record the fact that we couldn't load it in
18505 S->font_not_found_p so that we can draw rectangles for the
18506 characters of the glyph string. */
18507 if (s->font == NULL || glyph_not_available_p)
18508 {
18509 s->font_not_found_p = 1;
18510 s->font = FRAME_FONT (s->f);
18511 }
18512
18513 /* Adjust base line for subscript/superscript text. */
18514 s->ybase += voffset;
18515
18516 xassert (s->face && s->face->gc);
18517 return glyph - s->row->glyphs[s->area];
18518 }
18519
18520
18521 /* Fill glyph string S from image glyph S->first_glyph. */
18522
18523 static void
18524 fill_image_glyph_string (s)
18525 struct glyph_string *s;
18526 {
18527 xassert (s->first_glyph->type == IMAGE_GLYPH);
18528 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
18529 xassert (s->img);
18530 s->slice = s->first_glyph->slice;
18531 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
18532 s->font = s->face->font;
18533 s->width = s->first_glyph->pixel_width;
18534
18535 /* Adjust base line for subscript/superscript text. */
18536 s->ybase += s->first_glyph->voffset;
18537 }
18538
18539
18540 /* Fill glyph string S from a sequence of stretch glyphs.
18541
18542 ROW is the glyph row in which the glyphs are found, AREA is the
18543 area within the row. START is the index of the first glyph to
18544 consider, END is the index of the last + 1.
18545
18546 Value is the index of the first glyph not in S. */
18547
18548 static int
18549 fill_stretch_glyph_string (s, row, area, start, end)
18550 struct glyph_string *s;
18551 struct glyph_row *row;
18552 enum glyph_row_area area;
18553 int start, end;
18554 {
18555 struct glyph *glyph, *last;
18556 int voffset, face_id;
18557
18558 xassert (s->first_glyph->type == STRETCH_GLYPH);
18559
18560 glyph = s->row->glyphs[s->area] + start;
18561 last = s->row->glyphs[s->area] + end;
18562 face_id = glyph->face_id;
18563 s->face = FACE_FROM_ID (s->f, face_id);
18564 s->font = s->face->font;
18565 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18566 s->width = glyph->pixel_width;
18567 voffset = glyph->voffset;
18568
18569 for (++glyph;
18570 (glyph < last
18571 && glyph->type == STRETCH_GLYPH
18572 && glyph->voffset == voffset
18573 && glyph->face_id == face_id);
18574 ++glyph)
18575 s->width += glyph->pixel_width;
18576
18577 /* Adjust base line for subscript/superscript text. */
18578 s->ybase += voffset;
18579
18580 /* The case that face->gc == 0 is handled when drawing the glyph
18581 string by calling PREPARE_FACE_FOR_DISPLAY. */
18582 xassert (s->face);
18583 return glyph - s->row->glyphs[s->area];
18584 }
18585
18586
18587 /* EXPORT for RIF:
18588 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
18589 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
18590 assumed to be zero. */
18591
18592 void
18593 x_get_glyph_overhangs (glyph, f, left, right)
18594 struct glyph *glyph;
18595 struct frame *f;
18596 int *left, *right;
18597 {
18598 *left = *right = 0;
18599
18600 if (glyph->type == CHAR_GLYPH)
18601 {
18602 XFontStruct *font;
18603 struct face *face;
18604 struct font_info *font_info;
18605 XChar2b char2b;
18606 XCharStruct *pcm;
18607
18608 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
18609 font = face->font;
18610 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
18611 if (font /* ++KFS: Should this be font_info ? */
18612 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
18613 {
18614 if (pcm->rbearing > pcm->width)
18615 *right = pcm->rbearing - pcm->width;
18616 if (pcm->lbearing < 0)
18617 *left = -pcm->lbearing;
18618 }
18619 }
18620 }
18621
18622
18623 /* Return the index of the first glyph preceding glyph string S that
18624 is overwritten by S because of S's left overhang. Value is -1
18625 if no glyphs are overwritten. */
18626
18627 static int
18628 left_overwritten (s)
18629 struct glyph_string *s;
18630 {
18631 int k;
18632
18633 if (s->left_overhang)
18634 {
18635 int x = 0, i;
18636 struct glyph *glyphs = s->row->glyphs[s->area];
18637 int first = s->first_glyph - glyphs;
18638
18639 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
18640 x -= glyphs[i].pixel_width;
18641
18642 k = i + 1;
18643 }
18644 else
18645 k = -1;
18646
18647 return k;
18648 }
18649
18650
18651 /* Return the index of the first glyph preceding glyph string S that
18652 is overwriting S because of its right overhang. Value is -1 if no
18653 glyph in front of S overwrites S. */
18654
18655 static int
18656 left_overwriting (s)
18657 struct glyph_string *s;
18658 {
18659 int i, k, x;
18660 struct glyph *glyphs = s->row->glyphs[s->area];
18661 int first = s->first_glyph - glyphs;
18662
18663 k = -1;
18664 x = 0;
18665 for (i = first - 1; i >= 0; --i)
18666 {
18667 int left, right;
18668 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
18669 if (x + right > 0)
18670 k = i;
18671 x -= glyphs[i].pixel_width;
18672 }
18673
18674 return k;
18675 }
18676
18677
18678 /* Return the index of the last glyph following glyph string S that is
18679 not overwritten by S because of S's right overhang. Value is -1 if
18680 no such glyph is found. */
18681
18682 static int
18683 right_overwritten (s)
18684 struct glyph_string *s;
18685 {
18686 int k = -1;
18687
18688 if (s->right_overhang)
18689 {
18690 int x = 0, i;
18691 struct glyph *glyphs = s->row->glyphs[s->area];
18692 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
18693 int end = s->row->used[s->area];
18694
18695 for (i = first; i < end && s->right_overhang > x; ++i)
18696 x += glyphs[i].pixel_width;
18697
18698 k = i;
18699 }
18700
18701 return k;
18702 }
18703
18704
18705 /* Return the index of the last glyph following glyph string S that
18706 overwrites S because of its left overhang. Value is negative
18707 if no such glyph is found. */
18708
18709 static int
18710 right_overwriting (s)
18711 struct glyph_string *s;
18712 {
18713 int i, k, x;
18714 int end = s->row->used[s->area];
18715 struct glyph *glyphs = s->row->glyphs[s->area];
18716 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
18717
18718 k = -1;
18719 x = 0;
18720 for (i = first; i < end; ++i)
18721 {
18722 int left, right;
18723 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
18724 if (x - left < 0)
18725 k = i;
18726 x += glyphs[i].pixel_width;
18727 }
18728
18729 return k;
18730 }
18731
18732
18733 /* Get face and two-byte form of character C in face FACE_ID on frame
18734 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
18735 means we want to display multibyte text. DISPLAY_P non-zero means
18736 make sure that X resources for the face returned are allocated.
18737 Value is a pointer to a realized face that is ready for display if
18738 DISPLAY_P is non-zero. */
18739
18740 static INLINE struct face *
18741 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
18742 struct frame *f;
18743 int c, face_id;
18744 XChar2b *char2b;
18745 int multibyte_p, display_p;
18746 {
18747 struct face *face = FACE_FROM_ID (f, face_id);
18748
18749 if (!multibyte_p)
18750 {
18751 /* Unibyte case. We don't have to encode, but we have to make
18752 sure to use a face suitable for unibyte. */
18753 STORE_XCHAR2B (char2b, 0, c);
18754 face_id = FACE_FOR_CHAR (f, face, c);
18755 face = FACE_FROM_ID (f, face_id);
18756 }
18757 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
18758 {
18759 /* Case of ASCII in a face known to fit ASCII. */
18760 STORE_XCHAR2B (char2b, 0, c);
18761 }
18762 else
18763 {
18764 int c1, c2, charset;
18765
18766 /* Split characters into bytes. If c2 is -1 afterwards, C is
18767 really a one-byte character so that byte1 is zero. */
18768 SPLIT_CHAR (c, charset, c1, c2);
18769 if (c2 > 0)
18770 STORE_XCHAR2B (char2b, c1, c2);
18771 else
18772 STORE_XCHAR2B (char2b, 0, c1);
18773
18774 /* Maybe encode the character in *CHAR2B. */
18775 if (face->font != NULL)
18776 {
18777 struct font_info *font_info
18778 = FONT_INFO_FROM_ID (f, face->font_info_id);
18779 if (font_info)
18780 rif->encode_char (c, char2b, font_info, 0);
18781 }
18782 }
18783
18784 /* Make sure X resources of the face are allocated. */
18785 #ifdef HAVE_X_WINDOWS
18786 if (display_p)
18787 #endif
18788 {
18789 xassert (face != NULL);
18790 PREPARE_FACE_FOR_DISPLAY (f, face);
18791 }
18792
18793 return face;
18794 }
18795
18796
18797 /* Set background width of glyph string S. START is the index of the
18798 first glyph following S. LAST_X is the right-most x-position + 1
18799 in the drawing area. */
18800
18801 static INLINE void
18802 set_glyph_string_background_width (s, start, last_x)
18803 struct glyph_string *s;
18804 int start;
18805 int last_x;
18806 {
18807 /* If the face of this glyph string has to be drawn to the end of
18808 the drawing area, set S->extends_to_end_of_line_p. */
18809
18810 if (start == s->row->used[s->area]
18811 && s->area == TEXT_AREA
18812 && ((s->row->fill_line_p
18813 && (s->hl == DRAW_NORMAL_TEXT
18814 || s->hl == DRAW_IMAGE_RAISED
18815 || s->hl == DRAW_IMAGE_SUNKEN))
18816 || s->hl == DRAW_MOUSE_FACE))
18817 s->extends_to_end_of_line_p = 1;
18818
18819 /* If S extends its face to the end of the line, set its
18820 background_width to the distance to the right edge of the drawing
18821 area. */
18822 if (s->extends_to_end_of_line_p)
18823 s->background_width = last_x - s->x + 1;
18824 else
18825 s->background_width = s->width;
18826 }
18827
18828
18829 /* Compute overhangs and x-positions for glyph string S and its
18830 predecessors, or successors. X is the starting x-position for S.
18831 BACKWARD_P non-zero means process predecessors. */
18832
18833 static void
18834 compute_overhangs_and_x (s, x, backward_p)
18835 struct glyph_string *s;
18836 int x;
18837 int backward_p;
18838 {
18839 if (backward_p)
18840 {
18841 while (s)
18842 {
18843 if (rif->compute_glyph_string_overhangs)
18844 rif->compute_glyph_string_overhangs (s);
18845 x -= s->width;
18846 s->x = x;
18847 s = s->prev;
18848 }
18849 }
18850 else
18851 {
18852 while (s)
18853 {
18854 if (rif->compute_glyph_string_overhangs)
18855 rif->compute_glyph_string_overhangs (s);
18856 s->x = x;
18857 x += s->width;
18858 s = s->next;
18859 }
18860 }
18861 }
18862
18863
18864
18865 /* The following macros are only called from draw_glyphs below.
18866 They reference the following parameters of that function directly:
18867 `w', `row', `area', and `overlap_p'
18868 as well as the following local variables:
18869 `s', `f', and `hdc' (in W32) */
18870
18871 #ifdef HAVE_NTGUI
18872 /* On W32, silently add local `hdc' variable to argument list of
18873 init_glyph_string. */
18874 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18875 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
18876 #else
18877 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18878 init_glyph_string (s, char2b, w, row, area, start, hl)
18879 #endif
18880
18881 /* Add a glyph string for a stretch glyph to the list of strings
18882 between HEAD and TAIL. START is the index of the stretch glyph in
18883 row area AREA of glyph row ROW. END is the index of the last glyph
18884 in that glyph row area. X is the current output position assigned
18885 to the new glyph string constructed. HL overrides that face of the
18886 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18887 is the right-most x-position of the drawing area. */
18888
18889 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
18890 and below -- keep them on one line. */
18891 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18892 do \
18893 { \
18894 s = (struct glyph_string *) alloca (sizeof *s); \
18895 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18896 START = fill_stretch_glyph_string (s, row, area, START, END); \
18897 append_glyph_string (&HEAD, &TAIL, s); \
18898 s->x = (X); \
18899 } \
18900 while (0)
18901
18902
18903 /* Add a glyph string for an image glyph to the list of strings
18904 between HEAD and TAIL. START is the index of the image glyph in
18905 row area AREA of glyph row ROW. END is the index of the last glyph
18906 in that glyph row area. X is the current output position assigned
18907 to the new glyph string constructed. HL overrides that face of the
18908 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18909 is the right-most x-position of the drawing area. */
18910
18911 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18912 do \
18913 { \
18914 s = (struct glyph_string *) alloca (sizeof *s); \
18915 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18916 fill_image_glyph_string (s); \
18917 append_glyph_string (&HEAD, &TAIL, s); \
18918 ++START; \
18919 s->x = (X); \
18920 } \
18921 while (0)
18922
18923
18924 /* Add a glyph string for a sequence of character glyphs to the list
18925 of strings between HEAD and TAIL. START is the index of the first
18926 glyph in row area AREA of glyph row ROW that is part of the new
18927 glyph string. END is the index of the last glyph in that glyph row
18928 area. X is the current output position assigned to the new glyph
18929 string constructed. HL overrides that face of the glyph; e.g. it
18930 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
18931 right-most x-position of the drawing area. */
18932
18933 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18934 do \
18935 { \
18936 int c, face_id; \
18937 XChar2b *char2b; \
18938 \
18939 c = (row)->glyphs[area][START].u.ch; \
18940 face_id = (row)->glyphs[area][START].face_id; \
18941 \
18942 s = (struct glyph_string *) alloca (sizeof *s); \
18943 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
18944 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
18945 append_glyph_string (&HEAD, &TAIL, s); \
18946 s->x = (X); \
18947 START = fill_glyph_string (s, face_id, START, END, overlaps); \
18948 } \
18949 while (0)
18950
18951
18952 /* Add a glyph string for a composite sequence to the list of strings
18953 between HEAD and TAIL. START is the index of the first glyph in
18954 row area AREA of glyph row ROW that is part of the new glyph
18955 string. END is the index of the last glyph in that glyph row area.
18956 X is the current output position assigned to the new glyph string
18957 constructed. HL overrides that face of the glyph; e.g. it is
18958 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18959 x-position of the drawing area. */
18960
18961 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18962 do { \
18963 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18964 int face_id = (row)->glyphs[area][START].face_id; \
18965 struct face *base_face = FACE_FROM_ID (f, face_id); \
18966 struct composition *cmp = composition_table[cmp_id]; \
18967 int glyph_len = cmp->glyph_len; \
18968 XChar2b *char2b; \
18969 struct face **faces; \
18970 struct glyph_string *first_s = NULL; \
18971 int n; \
18972 \
18973 base_face = base_face->ascii_face; \
18974 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18975 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18976 /* At first, fill in `char2b' and `faces'. */ \
18977 for (n = 0; n < glyph_len; n++) \
18978 { \
18979 int c = COMPOSITION_GLYPH (cmp, n); \
18980 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
18981 faces[n] = FACE_FROM_ID (f, this_face_id); \
18982 get_char_face_and_encoding (f, c, this_face_id, \
18983 char2b + n, 1, 1); \
18984 } \
18985 \
18986 /* Make glyph_strings for each glyph sequence that is drawable by \
18987 the same face, and append them to HEAD/TAIL. */ \
18988 for (n = 0; n < cmp->glyph_len;) \
18989 { \
18990 s = (struct glyph_string *) alloca (sizeof *s); \
18991 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18992 append_glyph_string (&(HEAD), &(TAIL), s); \
18993 s->cmp = cmp; \
18994 s->gidx = n; \
18995 s->x = (X); \
18996 \
18997 if (n == 0) \
18998 first_s = s; \
18999 \
19000 n = fill_composite_glyph_string (s, faces, overlaps); \
19001 } \
19002 \
19003 ++START; \
19004 s = first_s; \
19005 } while (0)
19006
19007
19008 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
19009 of AREA of glyph row ROW on window W between indices START and END.
19010 HL overrides the face for drawing glyph strings, e.g. it is
19011 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
19012 x-positions of the drawing area.
19013
19014 This is an ugly monster macro construct because we must use alloca
19015 to allocate glyph strings (because draw_glyphs can be called
19016 asynchronously). */
19017
19018 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19019 do \
19020 { \
19021 HEAD = TAIL = NULL; \
19022 while (START < END) \
19023 { \
19024 struct glyph *first_glyph = (row)->glyphs[area] + START; \
19025 switch (first_glyph->type) \
19026 { \
19027 case CHAR_GLYPH: \
19028 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
19029 HL, X, LAST_X); \
19030 break; \
19031 \
19032 case COMPOSITE_GLYPH: \
19033 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
19034 HL, X, LAST_X); \
19035 break; \
19036 \
19037 case STRETCH_GLYPH: \
19038 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
19039 HL, X, LAST_X); \
19040 break; \
19041 \
19042 case IMAGE_GLYPH: \
19043 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
19044 HL, X, LAST_X); \
19045 break; \
19046 \
19047 default: \
19048 abort (); \
19049 } \
19050 \
19051 set_glyph_string_background_width (s, START, LAST_X); \
19052 (X) += s->width; \
19053 } \
19054 } \
19055 while (0)
19056
19057
19058 /* Draw glyphs between START and END in AREA of ROW on window W,
19059 starting at x-position X. X is relative to AREA in W. HL is a
19060 face-override with the following meaning:
19061
19062 DRAW_NORMAL_TEXT draw normally
19063 DRAW_CURSOR draw in cursor face
19064 DRAW_MOUSE_FACE draw in mouse face.
19065 DRAW_INVERSE_VIDEO draw in mode line face
19066 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
19067 DRAW_IMAGE_RAISED draw an image with a raised relief around it
19068
19069 If OVERLAPS is non-zero, draw only the foreground of characters and
19070 clip to the physical height of ROW. Non-zero value also defines
19071 the overlapping part to be drawn:
19072
19073 OVERLAPS_PRED overlap with preceding rows
19074 OVERLAPS_SUCC overlap with succeeding rows
19075 OVERLAPS_BOTH overlap with both preceding/succeeding rows
19076 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
19077
19078 Value is the x-position reached, relative to AREA of W. */
19079
19080 static int
19081 draw_glyphs (w, x, row, area, start, end, hl, overlaps)
19082 struct window *w;
19083 int x;
19084 struct glyph_row *row;
19085 enum glyph_row_area area;
19086 int start, end;
19087 enum draw_glyphs_face hl;
19088 int overlaps;
19089 {
19090 struct glyph_string *head, *tail;
19091 struct glyph_string *s;
19092 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
19093 int last_x, area_width;
19094 int x_reached;
19095 int i, j;
19096 struct frame *f = XFRAME (WINDOW_FRAME (w));
19097 DECLARE_HDC (hdc);
19098
19099 ALLOCATE_HDC (hdc, f);
19100
19101 /* Let's rather be paranoid than getting a SEGV. */
19102 end = min (end, row->used[area]);
19103 start = max (0, start);
19104 start = min (end, start);
19105
19106 /* Translate X to frame coordinates. Set last_x to the right
19107 end of the drawing area. */
19108 if (row->full_width_p)
19109 {
19110 /* X is relative to the left edge of W, without scroll bars
19111 or fringes. */
19112 x += WINDOW_LEFT_EDGE_X (w);
19113 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
19114 }
19115 else
19116 {
19117 int area_left = window_box_left (w, area);
19118 x += area_left;
19119 area_width = window_box_width (w, area);
19120 last_x = area_left + area_width;
19121 }
19122
19123 /* Build a doubly-linked list of glyph_string structures between
19124 head and tail from what we have to draw. Note that the macro
19125 BUILD_GLYPH_STRINGS will modify its start parameter. That's
19126 the reason we use a separate variable `i'. */
19127 i = start;
19128 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
19129 if (tail)
19130 x_reached = tail->x + tail->background_width;
19131 else
19132 x_reached = x;
19133
19134 /* If there are any glyphs with lbearing < 0 or rbearing > width in
19135 the row, redraw some glyphs in front or following the glyph
19136 strings built above. */
19137 if (head && !overlaps && row->contains_overlapping_glyphs_p)
19138 {
19139 int dummy_x = 0;
19140 struct glyph_string *h, *t;
19141
19142 /* Compute overhangs for all glyph strings. */
19143 if (rif->compute_glyph_string_overhangs)
19144 for (s = head; s; s = s->next)
19145 rif->compute_glyph_string_overhangs (s);
19146
19147 /* Prepend glyph strings for glyphs in front of the first glyph
19148 string that are overwritten because of the first glyph
19149 string's left overhang. The background of all strings
19150 prepended must be drawn because the first glyph string
19151 draws over it. */
19152 i = left_overwritten (head);
19153 if (i >= 0)
19154 {
19155 j = i;
19156 BUILD_GLYPH_STRINGS (j, start, h, t,
19157 DRAW_NORMAL_TEXT, dummy_x, last_x);
19158 start = i;
19159 compute_overhangs_and_x (t, head->x, 1);
19160 prepend_glyph_string_lists (&head, &tail, h, t);
19161 clip_head = head;
19162 }
19163
19164 /* Prepend glyph strings for glyphs in front of the first glyph
19165 string that overwrite that glyph string because of their
19166 right overhang. For these strings, only the foreground must
19167 be drawn, because it draws over the glyph string at `head'.
19168 The background must not be drawn because this would overwrite
19169 right overhangs of preceding glyphs for which no glyph
19170 strings exist. */
19171 i = left_overwriting (head);
19172 if (i >= 0)
19173 {
19174 clip_head = head;
19175 BUILD_GLYPH_STRINGS (i, start, h, t,
19176 DRAW_NORMAL_TEXT, dummy_x, last_x);
19177 for (s = h; s; s = s->next)
19178 s->background_filled_p = 1;
19179 compute_overhangs_and_x (t, head->x, 1);
19180 prepend_glyph_string_lists (&head, &tail, h, t);
19181 }
19182
19183 /* Append glyphs strings for glyphs following the last glyph
19184 string tail that are overwritten by tail. The background of
19185 these strings has to be drawn because tail's foreground draws
19186 over it. */
19187 i = right_overwritten (tail);
19188 if (i >= 0)
19189 {
19190 BUILD_GLYPH_STRINGS (end, i, h, t,
19191 DRAW_NORMAL_TEXT, x, last_x);
19192 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19193 append_glyph_string_lists (&head, &tail, h, t);
19194 clip_tail = tail;
19195 }
19196
19197 /* Append glyph strings for glyphs following the last glyph
19198 string tail that overwrite tail. The foreground of such
19199 glyphs has to be drawn because it writes into the background
19200 of tail. The background must not be drawn because it could
19201 paint over the foreground of following glyphs. */
19202 i = right_overwriting (tail);
19203 if (i >= 0)
19204 {
19205 clip_tail = tail;
19206 BUILD_GLYPH_STRINGS (end, i, h, t,
19207 DRAW_NORMAL_TEXT, x, last_x);
19208 for (s = h; s; s = s->next)
19209 s->background_filled_p = 1;
19210 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19211 append_glyph_string_lists (&head, &tail, h, t);
19212 }
19213 if (clip_head || clip_tail)
19214 for (s = head; s; s = s->next)
19215 {
19216 s->clip_head = clip_head;
19217 s->clip_tail = clip_tail;
19218 }
19219 }
19220
19221 /* Draw all strings. */
19222 for (s = head; s; s = s->next)
19223 rif->draw_glyph_string (s);
19224
19225 if (area == TEXT_AREA
19226 && !row->full_width_p
19227 /* When drawing overlapping rows, only the glyph strings'
19228 foreground is drawn, which doesn't erase a cursor
19229 completely. */
19230 && !overlaps)
19231 {
19232 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
19233 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
19234 : (tail ? tail->x + tail->background_width : x));
19235
19236 int text_left = window_box_left (w, TEXT_AREA);
19237 x0 -= text_left;
19238 x1 -= text_left;
19239
19240 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
19241 row->y, MATRIX_ROW_BOTTOM_Y (row));
19242 }
19243
19244 /* Value is the x-position up to which drawn, relative to AREA of W.
19245 This doesn't include parts drawn because of overhangs. */
19246 if (row->full_width_p)
19247 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
19248 else
19249 x_reached -= window_box_left (w, area);
19250
19251 RELEASE_HDC (hdc, f);
19252
19253 return x_reached;
19254 }
19255
19256 /* Expand row matrix if too narrow. Don't expand if area
19257 is not present. */
19258
19259 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
19260 { \
19261 if (!fonts_changed_p \
19262 && (it->glyph_row->glyphs[area] \
19263 < it->glyph_row->glyphs[area + 1])) \
19264 { \
19265 it->w->ncols_scale_factor++; \
19266 fonts_changed_p = 1; \
19267 } \
19268 }
19269
19270 /* Store one glyph for IT->char_to_display in IT->glyph_row.
19271 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19272
19273 static INLINE void
19274 append_glyph (it)
19275 struct it *it;
19276 {
19277 struct glyph *glyph;
19278 enum glyph_row_area area = it->area;
19279
19280 xassert (it->glyph_row);
19281 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
19282
19283 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19284 if (glyph < it->glyph_row->glyphs[area + 1])
19285 {
19286 glyph->charpos = CHARPOS (it->position);
19287 glyph->object = it->object;
19288 glyph->pixel_width = it->pixel_width;
19289 glyph->ascent = it->ascent;
19290 glyph->descent = it->descent;
19291 glyph->voffset = it->voffset;
19292 glyph->type = CHAR_GLYPH;
19293 glyph->multibyte_p = it->multibyte_p;
19294 glyph->left_box_line_p = it->start_of_box_run_p;
19295 glyph->right_box_line_p = it->end_of_box_run_p;
19296 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
19297 || it->phys_descent > it->descent);
19298 glyph->padding_p = 0;
19299 glyph->glyph_not_available_p = it->glyph_not_available_p;
19300 glyph->face_id = it->face_id;
19301 glyph->u.ch = it->char_to_display;
19302 glyph->slice = null_glyph_slice;
19303 glyph->font_type = FONT_TYPE_UNKNOWN;
19304 ++it->glyph_row->used[area];
19305 }
19306 else
19307 IT_EXPAND_MATRIX_WIDTH (it, area);
19308 }
19309
19310 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
19311 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19312
19313 static INLINE void
19314 append_composite_glyph (it)
19315 struct it *it;
19316 {
19317 struct glyph *glyph;
19318 enum glyph_row_area area = it->area;
19319
19320 xassert (it->glyph_row);
19321
19322 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19323 if (glyph < it->glyph_row->glyphs[area + 1])
19324 {
19325 glyph->charpos = CHARPOS (it->position);
19326 glyph->object = it->object;
19327 glyph->pixel_width = it->pixel_width;
19328 glyph->ascent = it->ascent;
19329 glyph->descent = it->descent;
19330 glyph->voffset = it->voffset;
19331 glyph->type = COMPOSITE_GLYPH;
19332 glyph->multibyte_p = it->multibyte_p;
19333 glyph->left_box_line_p = it->start_of_box_run_p;
19334 glyph->right_box_line_p = it->end_of_box_run_p;
19335 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
19336 || it->phys_descent > it->descent);
19337 glyph->padding_p = 0;
19338 glyph->glyph_not_available_p = 0;
19339 glyph->face_id = it->face_id;
19340 glyph->u.cmp_id = it->cmp_id;
19341 glyph->slice = null_glyph_slice;
19342 glyph->font_type = FONT_TYPE_UNKNOWN;
19343 ++it->glyph_row->used[area];
19344 }
19345 else
19346 IT_EXPAND_MATRIX_WIDTH (it, area);
19347 }
19348
19349
19350 /* Change IT->ascent and IT->height according to the setting of
19351 IT->voffset. */
19352
19353 static INLINE void
19354 take_vertical_position_into_account (it)
19355 struct it *it;
19356 {
19357 if (it->voffset)
19358 {
19359 if (it->voffset < 0)
19360 /* Increase the ascent so that we can display the text higher
19361 in the line. */
19362 it->ascent -= it->voffset;
19363 else
19364 /* Increase the descent so that we can display the text lower
19365 in the line. */
19366 it->descent += it->voffset;
19367 }
19368 }
19369
19370
19371 /* Produce glyphs/get display metrics for the image IT is loaded with.
19372 See the description of struct display_iterator in dispextern.h for
19373 an overview of struct display_iterator. */
19374
19375 static void
19376 produce_image_glyph (it)
19377 struct it *it;
19378 {
19379 struct image *img;
19380 struct face *face;
19381 int glyph_ascent;
19382 struct glyph_slice slice;
19383
19384 xassert (it->what == IT_IMAGE);
19385
19386 face = FACE_FROM_ID (it->f, it->face_id);
19387 xassert (face);
19388 /* Make sure X resources of the face is loaded. */
19389 PREPARE_FACE_FOR_DISPLAY (it->f, face);
19390
19391 if (it->image_id < 0)
19392 {
19393 /* Fringe bitmap. */
19394 it->ascent = it->phys_ascent = 0;
19395 it->descent = it->phys_descent = 0;
19396 it->pixel_width = 0;
19397 it->nglyphs = 0;
19398 return;
19399 }
19400
19401 img = IMAGE_FROM_ID (it->f, it->image_id);
19402 xassert (img);
19403 /* Make sure X resources of the image is loaded. */
19404 prepare_image_for_display (it->f, img);
19405
19406 slice.x = slice.y = 0;
19407 slice.width = img->width;
19408 slice.height = img->height;
19409
19410 if (INTEGERP (it->slice.x))
19411 slice.x = XINT (it->slice.x);
19412 else if (FLOATP (it->slice.x))
19413 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
19414
19415 if (INTEGERP (it->slice.y))
19416 slice.y = XINT (it->slice.y);
19417 else if (FLOATP (it->slice.y))
19418 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
19419
19420 if (INTEGERP (it->slice.width))
19421 slice.width = XINT (it->slice.width);
19422 else if (FLOATP (it->slice.width))
19423 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
19424
19425 if (INTEGERP (it->slice.height))
19426 slice.height = XINT (it->slice.height);
19427 else if (FLOATP (it->slice.height))
19428 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
19429
19430 if (slice.x >= img->width)
19431 slice.x = img->width;
19432 if (slice.y >= img->height)
19433 slice.y = img->height;
19434 if (slice.x + slice.width >= img->width)
19435 slice.width = img->width - slice.x;
19436 if (slice.y + slice.height > img->height)
19437 slice.height = img->height - slice.y;
19438
19439 if (slice.width == 0 || slice.height == 0)
19440 return;
19441
19442 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
19443
19444 it->descent = slice.height - glyph_ascent;
19445 if (slice.y == 0)
19446 it->descent += img->vmargin;
19447 if (slice.y + slice.height == img->height)
19448 it->descent += img->vmargin;
19449 it->phys_descent = it->descent;
19450
19451 it->pixel_width = slice.width;
19452 if (slice.x == 0)
19453 it->pixel_width += img->hmargin;
19454 if (slice.x + slice.width == img->width)
19455 it->pixel_width += img->hmargin;
19456
19457 /* It's quite possible for images to have an ascent greater than
19458 their height, so don't get confused in that case. */
19459 if (it->descent < 0)
19460 it->descent = 0;
19461
19462 #if 0 /* this breaks image tiling */
19463 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
19464 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
19465 if (face_ascent > it->ascent)
19466 it->ascent = it->phys_ascent = face_ascent;
19467 #endif
19468
19469 it->nglyphs = 1;
19470
19471 if (face->box != FACE_NO_BOX)
19472 {
19473 if (face->box_line_width > 0)
19474 {
19475 if (slice.y == 0)
19476 it->ascent += face->box_line_width;
19477 if (slice.y + slice.height == img->height)
19478 it->descent += face->box_line_width;
19479 }
19480
19481 if (it->start_of_box_run_p && slice.x == 0)
19482 it->pixel_width += abs (face->box_line_width);
19483 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
19484 it->pixel_width += abs (face->box_line_width);
19485 }
19486
19487 take_vertical_position_into_account (it);
19488
19489 if (it->glyph_row)
19490 {
19491 struct glyph *glyph;
19492 enum glyph_row_area area = it->area;
19493
19494 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19495 if (glyph < it->glyph_row->glyphs[area + 1])
19496 {
19497 glyph->charpos = CHARPOS (it->position);
19498 glyph->object = it->object;
19499 glyph->pixel_width = it->pixel_width;
19500 glyph->ascent = glyph_ascent;
19501 glyph->descent = it->descent;
19502 glyph->voffset = it->voffset;
19503 glyph->type = IMAGE_GLYPH;
19504 glyph->multibyte_p = it->multibyte_p;
19505 glyph->left_box_line_p = it->start_of_box_run_p;
19506 glyph->right_box_line_p = it->end_of_box_run_p;
19507 glyph->overlaps_vertically_p = 0;
19508 glyph->padding_p = 0;
19509 glyph->glyph_not_available_p = 0;
19510 glyph->face_id = it->face_id;
19511 glyph->u.img_id = img->id;
19512 glyph->slice = slice;
19513 glyph->font_type = FONT_TYPE_UNKNOWN;
19514 ++it->glyph_row->used[area];
19515 }
19516 else
19517 IT_EXPAND_MATRIX_WIDTH (it, area);
19518 }
19519 }
19520
19521
19522 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
19523 of the glyph, WIDTH and HEIGHT are the width and height of the
19524 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
19525
19526 static void
19527 append_stretch_glyph (it, object, width, height, ascent)
19528 struct it *it;
19529 Lisp_Object object;
19530 int width, height;
19531 int ascent;
19532 {
19533 struct glyph *glyph;
19534 enum glyph_row_area area = it->area;
19535
19536 xassert (ascent >= 0 && ascent <= height);
19537
19538 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19539 if (glyph < it->glyph_row->glyphs[area + 1])
19540 {
19541 glyph->charpos = CHARPOS (it->position);
19542 glyph->object = object;
19543 glyph->pixel_width = width;
19544 glyph->ascent = ascent;
19545 glyph->descent = height - ascent;
19546 glyph->voffset = it->voffset;
19547 glyph->type = STRETCH_GLYPH;
19548 glyph->multibyte_p = it->multibyte_p;
19549 glyph->left_box_line_p = it->start_of_box_run_p;
19550 glyph->right_box_line_p = it->end_of_box_run_p;
19551 glyph->overlaps_vertically_p = 0;
19552 glyph->padding_p = 0;
19553 glyph->glyph_not_available_p = 0;
19554 glyph->face_id = it->face_id;
19555 glyph->u.stretch.ascent = ascent;
19556 glyph->u.stretch.height = height;
19557 glyph->slice = null_glyph_slice;
19558 glyph->font_type = FONT_TYPE_UNKNOWN;
19559 ++it->glyph_row->used[area];
19560 }
19561 else
19562 IT_EXPAND_MATRIX_WIDTH (it, area);
19563 }
19564
19565
19566 /* Produce a stretch glyph for iterator IT. IT->object is the value
19567 of the glyph property displayed. The value must be a list
19568 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
19569 being recognized:
19570
19571 1. `:width WIDTH' specifies that the space should be WIDTH *
19572 canonical char width wide. WIDTH may be an integer or floating
19573 point number.
19574
19575 2. `:relative-width FACTOR' specifies that the width of the stretch
19576 should be computed from the width of the first character having the
19577 `glyph' property, and should be FACTOR times that width.
19578
19579 3. `:align-to HPOS' specifies that the space should be wide enough
19580 to reach HPOS, a value in canonical character units.
19581
19582 Exactly one of the above pairs must be present.
19583
19584 4. `:height HEIGHT' specifies that the height of the stretch produced
19585 should be HEIGHT, measured in canonical character units.
19586
19587 5. `:relative-height FACTOR' specifies that the height of the
19588 stretch should be FACTOR times the height of the characters having
19589 the glyph property.
19590
19591 Either none or exactly one of 4 or 5 must be present.
19592
19593 6. `:ascent ASCENT' specifies that ASCENT percent of the height
19594 of the stretch should be used for the ascent of the stretch.
19595 ASCENT must be in the range 0 <= ASCENT <= 100. */
19596
19597 static void
19598 produce_stretch_glyph (it)
19599 struct it *it;
19600 {
19601 /* (space :width WIDTH :height HEIGHT ...) */
19602 Lisp_Object prop, plist;
19603 int width = 0, height = 0, align_to = -1;
19604 int zero_width_ok_p = 0, zero_height_ok_p = 0;
19605 int ascent = 0;
19606 double tem;
19607 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19608 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
19609
19610 PREPARE_FACE_FOR_DISPLAY (it->f, face);
19611
19612 /* List should start with `space'. */
19613 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
19614 plist = XCDR (it->object);
19615
19616 /* Compute the width of the stretch. */
19617 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
19618 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
19619 {
19620 /* Absolute width `:width WIDTH' specified and valid. */
19621 zero_width_ok_p = 1;
19622 width = (int)tem;
19623 }
19624 else if (prop = Fplist_get (plist, QCrelative_width),
19625 NUMVAL (prop) > 0)
19626 {
19627 /* Relative width `:relative-width FACTOR' specified and valid.
19628 Compute the width of the characters having the `glyph'
19629 property. */
19630 struct it it2;
19631 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
19632
19633 it2 = *it;
19634 if (it->multibyte_p)
19635 {
19636 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
19637 - IT_BYTEPOS (*it));
19638 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
19639 }
19640 else
19641 it2.c = *p, it2.len = 1;
19642
19643 it2.glyph_row = NULL;
19644 it2.what = IT_CHARACTER;
19645 x_produce_glyphs (&it2);
19646 width = NUMVAL (prop) * it2.pixel_width;
19647 }
19648 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
19649 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
19650 {
19651 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
19652 align_to = (align_to < 0
19653 ? 0
19654 : align_to - window_box_left_offset (it->w, TEXT_AREA));
19655 else if (align_to < 0)
19656 align_to = window_box_left_offset (it->w, TEXT_AREA);
19657 width = max (0, (int)tem + align_to - it->current_x);
19658 zero_width_ok_p = 1;
19659 }
19660 else
19661 /* Nothing specified -> width defaults to canonical char width. */
19662 width = FRAME_COLUMN_WIDTH (it->f);
19663
19664 if (width <= 0 && (width < 0 || !zero_width_ok_p))
19665 width = 1;
19666
19667 /* Compute height. */
19668 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
19669 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
19670 {
19671 height = (int)tem;
19672 zero_height_ok_p = 1;
19673 }
19674 else if (prop = Fplist_get (plist, QCrelative_height),
19675 NUMVAL (prop) > 0)
19676 height = FONT_HEIGHT (font) * NUMVAL (prop);
19677 else
19678 height = FONT_HEIGHT (font);
19679
19680 if (height <= 0 && (height < 0 || !zero_height_ok_p))
19681 height = 1;
19682
19683 /* Compute percentage of height used for ascent. If
19684 `:ascent ASCENT' is present and valid, use that. Otherwise,
19685 derive the ascent from the font in use. */
19686 if (prop = Fplist_get (plist, QCascent),
19687 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
19688 ascent = height * NUMVAL (prop) / 100.0;
19689 else if (!NILP (prop)
19690 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
19691 ascent = min (max (0, (int)tem), height);
19692 else
19693 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
19694
19695 if (width > 0 && !it->truncate_lines_p
19696 && it->current_x + width > it->last_visible_x)
19697 width = it->last_visible_x - it->current_x - 1;
19698
19699 if (width > 0 && height > 0 && it->glyph_row)
19700 {
19701 Lisp_Object object = it->stack[it->sp - 1].string;
19702 if (!STRINGP (object))
19703 object = it->w->buffer;
19704 append_stretch_glyph (it, object, width, height, ascent);
19705 }
19706
19707 it->pixel_width = width;
19708 it->ascent = it->phys_ascent = ascent;
19709 it->descent = it->phys_descent = height - it->ascent;
19710 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
19711
19712 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
19713 {
19714 if (face->box_line_width > 0)
19715 {
19716 it->ascent += face->box_line_width;
19717 it->descent += face->box_line_width;
19718 }
19719
19720 if (it->start_of_box_run_p)
19721 it->pixel_width += abs (face->box_line_width);
19722 if (it->end_of_box_run_p)
19723 it->pixel_width += abs (face->box_line_width);
19724 }
19725
19726 take_vertical_position_into_account (it);
19727 }
19728
19729 /* Get line-height and line-spacing property at point.
19730 If line-height has format (HEIGHT TOTAL), return TOTAL
19731 in TOTAL_HEIGHT. */
19732
19733 static Lisp_Object
19734 get_line_height_property (it, prop)
19735 struct it *it;
19736 Lisp_Object prop;
19737 {
19738 Lisp_Object position;
19739
19740 if (STRINGP (it->object))
19741 position = make_number (IT_STRING_CHARPOS (*it));
19742 else if (BUFFERP (it->object))
19743 position = make_number (IT_CHARPOS (*it));
19744 else
19745 return Qnil;
19746
19747 return Fget_char_property (position, prop, it->object);
19748 }
19749
19750 /* Calculate line-height and line-spacing properties.
19751 An integer value specifies explicit pixel value.
19752 A float value specifies relative value to current face height.
19753 A cons (float . face-name) specifies relative value to
19754 height of specified face font.
19755
19756 Returns height in pixels, or nil. */
19757
19758
19759 static Lisp_Object
19760 calc_line_height_property (it, val, font, boff, override)
19761 struct it *it;
19762 Lisp_Object val;
19763 XFontStruct *font;
19764 int boff, override;
19765 {
19766 Lisp_Object face_name = Qnil;
19767 int ascent, descent, height;
19768
19769 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
19770 return val;
19771
19772 if (CONSP (val))
19773 {
19774 face_name = XCAR (val);
19775 val = XCDR (val);
19776 if (!NUMBERP (val))
19777 val = make_number (1);
19778 if (NILP (face_name))
19779 {
19780 height = it->ascent + it->descent;
19781 goto scale;
19782 }
19783 }
19784
19785 if (NILP (face_name))
19786 {
19787 font = FRAME_FONT (it->f);
19788 boff = FRAME_BASELINE_OFFSET (it->f);
19789 }
19790 else if (EQ (face_name, Qt))
19791 {
19792 override = 0;
19793 }
19794 else
19795 {
19796 int face_id;
19797 struct face *face;
19798 struct font_info *font_info;
19799
19800 face_id = lookup_named_face (it->f, face_name, ' ', 0);
19801 if (face_id < 0)
19802 return make_number (-1);
19803
19804 face = FACE_FROM_ID (it->f, face_id);
19805 font = face->font;
19806 if (font == NULL)
19807 return make_number (-1);
19808
19809 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19810 boff = font_info->baseline_offset;
19811 if (font_info->vertical_centering)
19812 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19813 }
19814
19815 ascent = FONT_BASE (font) + boff;
19816 descent = FONT_DESCENT (font) - boff;
19817
19818 if (override)
19819 {
19820 it->override_ascent = ascent;
19821 it->override_descent = descent;
19822 it->override_boff = boff;
19823 }
19824
19825 height = ascent + descent;
19826
19827 scale:
19828 if (FLOATP (val))
19829 height = (int)(XFLOAT_DATA (val) * height);
19830 else if (INTEGERP (val))
19831 height *= XINT (val);
19832
19833 return make_number (height);
19834 }
19835
19836
19837 /* RIF:
19838 Produce glyphs/get display metrics for the display element IT is
19839 loaded with. See the description of struct it in dispextern.h
19840 for an overview of struct it. */
19841
19842 void
19843 x_produce_glyphs (it)
19844 struct it *it;
19845 {
19846 int extra_line_spacing = it->extra_line_spacing;
19847
19848 it->glyph_not_available_p = 0;
19849
19850 if (it->what == IT_CHARACTER)
19851 {
19852 XChar2b char2b;
19853 XFontStruct *font;
19854 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19855 XCharStruct *pcm;
19856 int font_not_found_p;
19857 struct font_info *font_info;
19858 int boff; /* baseline offset */
19859 /* We may change it->multibyte_p upon unibyte<->multibyte
19860 conversion. So, save the current value now and restore it
19861 later.
19862
19863 Note: It seems that we don't have to record multibyte_p in
19864 struct glyph because the character code itself tells if or
19865 not the character is multibyte. Thus, in the future, we must
19866 consider eliminating the field `multibyte_p' in the struct
19867 glyph. */
19868 int saved_multibyte_p = it->multibyte_p;
19869
19870 /* Maybe translate single-byte characters to multibyte, or the
19871 other way. */
19872 it->char_to_display = it->c;
19873 if (!ASCII_BYTE_P (it->c))
19874 {
19875 if (unibyte_display_via_language_environment
19876 && SINGLE_BYTE_CHAR_P (it->c)
19877 && (it->c >= 0240
19878 || !NILP (Vnonascii_translation_table)))
19879 {
19880 it->char_to_display = unibyte_char_to_multibyte (it->c);
19881 it->multibyte_p = 1;
19882 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19883 face = FACE_FROM_ID (it->f, it->face_id);
19884 }
19885 else if (!SINGLE_BYTE_CHAR_P (it->c)
19886 && !it->multibyte_p)
19887 {
19888 it->multibyte_p = 1;
19889 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19890 face = FACE_FROM_ID (it->f, it->face_id);
19891 }
19892 }
19893
19894 /* Get font to use. Encode IT->char_to_display. */
19895 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19896 &char2b, it->multibyte_p, 0);
19897 font = face->font;
19898
19899 /* When no suitable font found, use the default font. */
19900 font_not_found_p = font == NULL;
19901 if (font_not_found_p)
19902 {
19903 font = FRAME_FONT (it->f);
19904 boff = FRAME_BASELINE_OFFSET (it->f);
19905 font_info = NULL;
19906 }
19907 else
19908 {
19909 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19910 boff = font_info->baseline_offset;
19911 if (font_info->vertical_centering)
19912 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19913 }
19914
19915 if (it->char_to_display >= ' '
19916 && (!it->multibyte_p || it->char_to_display < 128))
19917 {
19918 /* Either unibyte or ASCII. */
19919 int stretched_p;
19920
19921 it->nglyphs = 1;
19922
19923 pcm = rif->per_char_metric (font, &char2b,
19924 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
19925
19926 if (it->override_ascent >= 0)
19927 {
19928 it->ascent = it->override_ascent;
19929 it->descent = it->override_descent;
19930 boff = it->override_boff;
19931 }
19932 else
19933 {
19934 it->ascent = FONT_BASE (font) + boff;
19935 it->descent = FONT_DESCENT (font) - boff;
19936 }
19937
19938 if (pcm)
19939 {
19940 it->phys_ascent = pcm->ascent + boff;
19941 it->phys_descent = pcm->descent - boff;
19942 it->pixel_width = pcm->width;
19943 }
19944 else
19945 {
19946 it->glyph_not_available_p = 1;
19947 it->phys_ascent = it->ascent;
19948 it->phys_descent = it->descent;
19949 it->pixel_width = FONT_WIDTH (font);
19950 }
19951
19952 if (it->constrain_row_ascent_descent_p)
19953 {
19954 if (it->descent > it->max_descent)
19955 {
19956 it->ascent += it->descent - it->max_descent;
19957 it->descent = it->max_descent;
19958 }
19959 if (it->ascent > it->max_ascent)
19960 {
19961 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19962 it->ascent = it->max_ascent;
19963 }
19964 it->phys_ascent = min (it->phys_ascent, it->ascent);
19965 it->phys_descent = min (it->phys_descent, it->descent);
19966 extra_line_spacing = 0;
19967 }
19968
19969 /* If this is a space inside a region of text with
19970 `space-width' property, change its width. */
19971 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
19972 if (stretched_p)
19973 it->pixel_width *= XFLOATINT (it->space_width);
19974
19975 /* If face has a box, add the box thickness to the character
19976 height. If character has a box line to the left and/or
19977 right, add the box line width to the character's width. */
19978 if (face->box != FACE_NO_BOX)
19979 {
19980 int thick = face->box_line_width;
19981
19982 if (thick > 0)
19983 {
19984 it->ascent += thick;
19985 it->descent += thick;
19986 }
19987 else
19988 thick = -thick;
19989
19990 if (it->start_of_box_run_p)
19991 it->pixel_width += thick;
19992 if (it->end_of_box_run_p)
19993 it->pixel_width += thick;
19994 }
19995
19996 /* If face has an overline, add the height of the overline
19997 (1 pixel) and a 1 pixel margin to the character height. */
19998 if (face->overline_p)
19999 it->ascent += 2;
20000
20001 if (it->constrain_row_ascent_descent_p)
20002 {
20003 if (it->ascent > it->max_ascent)
20004 it->ascent = it->max_ascent;
20005 if (it->descent > it->max_descent)
20006 it->descent = it->max_descent;
20007 }
20008
20009 take_vertical_position_into_account (it);
20010
20011 /* If we have to actually produce glyphs, do it. */
20012 if (it->glyph_row)
20013 {
20014 if (stretched_p)
20015 {
20016 /* Translate a space with a `space-width' property
20017 into a stretch glyph. */
20018 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
20019 / FONT_HEIGHT (font));
20020 append_stretch_glyph (it, it->object, it->pixel_width,
20021 it->ascent + it->descent, ascent);
20022 }
20023 else
20024 append_glyph (it);
20025
20026 /* If characters with lbearing or rbearing are displayed
20027 in this line, record that fact in a flag of the
20028 glyph row. This is used to optimize X output code. */
20029 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
20030 it->glyph_row->contains_overlapping_glyphs_p = 1;
20031 }
20032 }
20033 else if (it->char_to_display == '\n')
20034 {
20035 /* A newline has no width but we need the height of the line.
20036 But if previous part of the line set a height, don't
20037 increase that height */
20038
20039 Lisp_Object height;
20040 Lisp_Object total_height = Qnil;
20041
20042 it->override_ascent = -1;
20043 it->pixel_width = 0;
20044 it->nglyphs = 0;
20045
20046 height = get_line_height_property(it, Qline_height);
20047 /* Split (line-height total-height) list */
20048 if (CONSP (height)
20049 && CONSP (XCDR (height))
20050 && NILP (XCDR (XCDR (height))))
20051 {
20052 total_height = XCAR (XCDR (height));
20053 height = XCAR (height);
20054 }
20055 height = calc_line_height_property(it, height, font, boff, 1);
20056
20057 if (it->override_ascent >= 0)
20058 {
20059 it->ascent = it->override_ascent;
20060 it->descent = it->override_descent;
20061 boff = it->override_boff;
20062 }
20063 else
20064 {
20065 it->ascent = FONT_BASE (font) + boff;
20066 it->descent = FONT_DESCENT (font) - boff;
20067 }
20068
20069 if (EQ (height, Qt))
20070 {
20071 if (it->descent > it->max_descent)
20072 {
20073 it->ascent += it->descent - it->max_descent;
20074 it->descent = it->max_descent;
20075 }
20076 if (it->ascent > it->max_ascent)
20077 {
20078 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20079 it->ascent = it->max_ascent;
20080 }
20081 it->phys_ascent = min (it->phys_ascent, it->ascent);
20082 it->phys_descent = min (it->phys_descent, it->descent);
20083 it->constrain_row_ascent_descent_p = 1;
20084 extra_line_spacing = 0;
20085 }
20086 else
20087 {
20088 Lisp_Object spacing;
20089
20090 it->phys_ascent = it->ascent;
20091 it->phys_descent = it->descent;
20092
20093 if ((it->max_ascent > 0 || it->max_descent > 0)
20094 && face->box != FACE_NO_BOX
20095 && face->box_line_width > 0)
20096 {
20097 it->ascent += face->box_line_width;
20098 it->descent += face->box_line_width;
20099 }
20100 if (!NILP (height)
20101 && XINT (height) > it->ascent + it->descent)
20102 it->ascent = XINT (height) - it->descent;
20103
20104 if (!NILP (total_height))
20105 spacing = calc_line_height_property(it, total_height, font, boff, 0);
20106 else
20107 {
20108 spacing = get_line_height_property(it, Qline_spacing);
20109 spacing = calc_line_height_property(it, spacing, font, boff, 0);
20110 }
20111 if (INTEGERP (spacing))
20112 {
20113 extra_line_spacing = XINT (spacing);
20114 if (!NILP (total_height))
20115 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20116 }
20117 }
20118 }
20119 else if (it->char_to_display == '\t')
20120 {
20121 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
20122 int x = it->current_x + it->continuation_lines_width;
20123 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
20124
20125 /* If the distance from the current position to the next tab
20126 stop is less than a space character width, use the
20127 tab stop after that. */
20128 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
20129 next_tab_x += tab_width;
20130
20131 it->pixel_width = next_tab_x - x;
20132 it->nglyphs = 1;
20133 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
20134 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
20135
20136 if (it->glyph_row)
20137 {
20138 append_stretch_glyph (it, it->object, it->pixel_width,
20139 it->ascent + it->descent, it->ascent);
20140 }
20141 }
20142 else
20143 {
20144 /* A multi-byte character. Assume that the display width of the
20145 character is the width of the character multiplied by the
20146 width of the font. */
20147
20148 /* If we found a font, this font should give us the right
20149 metrics. If we didn't find a font, use the frame's
20150 default font and calculate the width of the character
20151 from the charset width; this is what old redisplay code
20152 did. */
20153
20154 pcm = rif->per_char_metric (font, &char2b,
20155 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
20156
20157 if (font_not_found_p || !pcm)
20158 {
20159 int charset = CHAR_CHARSET (it->char_to_display);
20160
20161 it->glyph_not_available_p = 1;
20162 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
20163 * CHARSET_WIDTH (charset));
20164 it->phys_ascent = FONT_BASE (font) + boff;
20165 it->phys_descent = FONT_DESCENT (font) - boff;
20166 }
20167 else
20168 {
20169 it->pixel_width = pcm->width;
20170 it->phys_ascent = pcm->ascent + boff;
20171 it->phys_descent = pcm->descent - boff;
20172 if (it->glyph_row
20173 && (pcm->lbearing < 0
20174 || pcm->rbearing > pcm->width))
20175 it->glyph_row->contains_overlapping_glyphs_p = 1;
20176 }
20177 it->nglyphs = 1;
20178 it->ascent = FONT_BASE (font) + boff;
20179 it->descent = FONT_DESCENT (font) - boff;
20180 if (face->box != FACE_NO_BOX)
20181 {
20182 int thick = face->box_line_width;
20183
20184 if (thick > 0)
20185 {
20186 it->ascent += thick;
20187 it->descent += thick;
20188 }
20189 else
20190 thick = - thick;
20191
20192 if (it->start_of_box_run_p)
20193 it->pixel_width += thick;
20194 if (it->end_of_box_run_p)
20195 it->pixel_width += thick;
20196 }
20197
20198 /* If face has an overline, add the height of the overline
20199 (1 pixel) and a 1 pixel margin to the character height. */
20200 if (face->overline_p)
20201 it->ascent += 2;
20202
20203 take_vertical_position_into_account (it);
20204
20205 if (it->glyph_row)
20206 append_glyph (it);
20207 }
20208 it->multibyte_p = saved_multibyte_p;
20209 }
20210 else if (it->what == IT_COMPOSITION)
20211 {
20212 /* Note: A composition is represented as one glyph in the
20213 glyph matrix. There are no padding glyphs. */
20214 XChar2b char2b;
20215 XFontStruct *font;
20216 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20217 XCharStruct *pcm;
20218 int font_not_found_p;
20219 struct font_info *font_info;
20220 int boff; /* baseline offset */
20221 struct composition *cmp = composition_table[it->cmp_id];
20222
20223 /* Maybe translate single-byte characters to multibyte. */
20224 it->char_to_display = it->c;
20225 if (unibyte_display_via_language_environment
20226 && SINGLE_BYTE_CHAR_P (it->c)
20227 && (it->c >= 0240
20228 || (it->c >= 0200
20229 && !NILP (Vnonascii_translation_table))))
20230 {
20231 it->char_to_display = unibyte_char_to_multibyte (it->c);
20232 }
20233
20234 /* Get face and font to use. Encode IT->char_to_display. */
20235 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20236 face = FACE_FROM_ID (it->f, it->face_id);
20237 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20238 &char2b, it->multibyte_p, 0);
20239 font = face->font;
20240
20241 /* When no suitable font found, use the default font. */
20242 font_not_found_p = font == NULL;
20243 if (font_not_found_p)
20244 {
20245 font = FRAME_FONT (it->f);
20246 boff = FRAME_BASELINE_OFFSET (it->f);
20247 font_info = NULL;
20248 }
20249 else
20250 {
20251 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20252 boff = font_info->baseline_offset;
20253 if (font_info->vertical_centering)
20254 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20255 }
20256
20257 /* There are no padding glyphs, so there is only one glyph to
20258 produce for the composition. Important is that pixel_width,
20259 ascent and descent are the values of what is drawn by
20260 draw_glyphs (i.e. the values of the overall glyphs composed). */
20261 it->nglyphs = 1;
20262
20263 /* If we have not yet calculated pixel size data of glyphs of
20264 the composition for the current face font, calculate them
20265 now. Theoretically, we have to check all fonts for the
20266 glyphs, but that requires much time and memory space. So,
20267 here we check only the font of the first glyph. This leads
20268 to incorrect display very rarely, and C-l (recenter) can
20269 correct the display anyway. */
20270 if (cmp->font != (void *) font)
20271 {
20272 /* Ascent and descent of the font of the first character of
20273 this composition (adjusted by baseline offset). Ascent
20274 and descent of overall glyphs should not be less than
20275 them respectively. */
20276 int font_ascent = FONT_BASE (font) + boff;
20277 int font_descent = FONT_DESCENT (font) - boff;
20278 /* Bounding box of the overall glyphs. */
20279 int leftmost, rightmost, lowest, highest;
20280 int i, width, ascent, descent;
20281
20282 cmp->font = (void *) font;
20283
20284 /* Initialize the bounding box. */
20285 if (font_info
20286 && (pcm = rif->per_char_metric (font, &char2b,
20287 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
20288 {
20289 width = pcm->width;
20290 ascent = pcm->ascent;
20291 descent = pcm->descent;
20292 }
20293 else
20294 {
20295 width = FONT_WIDTH (font);
20296 ascent = FONT_BASE (font);
20297 descent = FONT_DESCENT (font);
20298 }
20299
20300 rightmost = width;
20301 lowest = - descent + boff;
20302 highest = ascent + boff;
20303 leftmost = 0;
20304
20305 if (font_info
20306 && font_info->default_ascent
20307 && CHAR_TABLE_P (Vuse_default_ascent)
20308 && !NILP (Faref (Vuse_default_ascent,
20309 make_number (it->char_to_display))))
20310 highest = font_info->default_ascent + boff;
20311
20312 /* Draw the first glyph at the normal position. It may be
20313 shifted to right later if some other glyphs are drawn at
20314 the left. */
20315 cmp->offsets[0] = 0;
20316 cmp->offsets[1] = boff;
20317
20318 /* Set cmp->offsets for the remaining glyphs. */
20319 for (i = 1; i < cmp->glyph_len; i++)
20320 {
20321 int left, right, btm, top;
20322 int ch = COMPOSITION_GLYPH (cmp, i);
20323 int face_id = FACE_FOR_CHAR (it->f, face, ch);
20324
20325 face = FACE_FROM_ID (it->f, face_id);
20326 get_char_face_and_encoding (it->f, ch, face->id,
20327 &char2b, it->multibyte_p, 0);
20328 font = face->font;
20329 if (font == NULL)
20330 {
20331 font = FRAME_FONT (it->f);
20332 boff = FRAME_BASELINE_OFFSET (it->f);
20333 font_info = NULL;
20334 }
20335 else
20336 {
20337 font_info
20338 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20339 boff = font_info->baseline_offset;
20340 if (font_info->vertical_centering)
20341 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20342 }
20343
20344 if (font_info
20345 && (pcm = rif->per_char_metric (font, &char2b,
20346 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
20347 {
20348 width = pcm->width;
20349 ascent = pcm->ascent;
20350 descent = pcm->descent;
20351 }
20352 else
20353 {
20354 width = FONT_WIDTH (font);
20355 ascent = 1;
20356 descent = 0;
20357 }
20358
20359 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
20360 {
20361 /* Relative composition with or without
20362 alternate chars. */
20363 left = (leftmost + rightmost - width) / 2;
20364 btm = - descent + boff;
20365 if (font_info && font_info->relative_compose
20366 && (! CHAR_TABLE_P (Vignore_relative_composition)
20367 || NILP (Faref (Vignore_relative_composition,
20368 make_number (ch)))))
20369 {
20370
20371 if (- descent >= font_info->relative_compose)
20372 /* One extra pixel between two glyphs. */
20373 btm = highest + 1;
20374 else if (ascent <= 0)
20375 /* One extra pixel between two glyphs. */
20376 btm = lowest - 1 - ascent - descent;
20377 }
20378 }
20379 else
20380 {
20381 /* A composition rule is specified by an integer
20382 value that encodes global and new reference
20383 points (GREF and NREF). GREF and NREF are
20384 specified by numbers as below:
20385
20386 0---1---2 -- ascent
20387 | |
20388 | |
20389 | |
20390 9--10--11 -- center
20391 | |
20392 ---3---4---5--- baseline
20393 | |
20394 6---7---8 -- descent
20395 */
20396 int rule = COMPOSITION_RULE (cmp, i);
20397 int gref, nref, grefx, grefy, nrefx, nrefy;
20398
20399 COMPOSITION_DECODE_RULE (rule, gref, nref);
20400 grefx = gref % 3, nrefx = nref % 3;
20401 grefy = gref / 3, nrefy = nref / 3;
20402
20403 left = (leftmost
20404 + grefx * (rightmost - leftmost) / 2
20405 - nrefx * width / 2);
20406 btm = ((grefy == 0 ? highest
20407 : grefy == 1 ? 0
20408 : grefy == 2 ? lowest
20409 : (highest + lowest) / 2)
20410 - (nrefy == 0 ? ascent + descent
20411 : nrefy == 1 ? descent - boff
20412 : nrefy == 2 ? 0
20413 : (ascent + descent) / 2));
20414 }
20415
20416 cmp->offsets[i * 2] = left;
20417 cmp->offsets[i * 2 + 1] = btm + descent;
20418
20419 /* Update the bounding box of the overall glyphs. */
20420 right = left + width;
20421 top = btm + descent + ascent;
20422 if (left < leftmost)
20423 leftmost = left;
20424 if (right > rightmost)
20425 rightmost = right;
20426 if (top > highest)
20427 highest = top;
20428 if (btm < lowest)
20429 lowest = btm;
20430 }
20431
20432 /* If there are glyphs whose x-offsets are negative,
20433 shift all glyphs to the right and make all x-offsets
20434 non-negative. */
20435 if (leftmost < 0)
20436 {
20437 for (i = 0; i < cmp->glyph_len; i++)
20438 cmp->offsets[i * 2] -= leftmost;
20439 rightmost -= leftmost;
20440 }
20441
20442 cmp->pixel_width = rightmost;
20443 cmp->ascent = highest;
20444 cmp->descent = - lowest;
20445 if (cmp->ascent < font_ascent)
20446 cmp->ascent = font_ascent;
20447 if (cmp->descent < font_descent)
20448 cmp->descent = font_descent;
20449 }
20450
20451 it->pixel_width = cmp->pixel_width;
20452 it->ascent = it->phys_ascent = cmp->ascent;
20453 it->descent = it->phys_descent = cmp->descent;
20454
20455 if (face->box != FACE_NO_BOX)
20456 {
20457 int thick = face->box_line_width;
20458
20459 if (thick > 0)
20460 {
20461 it->ascent += thick;
20462 it->descent += thick;
20463 }
20464 else
20465 thick = - thick;
20466
20467 if (it->start_of_box_run_p)
20468 it->pixel_width += thick;
20469 if (it->end_of_box_run_p)
20470 it->pixel_width += thick;
20471 }
20472
20473 /* If face has an overline, add the height of the overline
20474 (1 pixel) and a 1 pixel margin to the character height. */
20475 if (face->overline_p)
20476 it->ascent += 2;
20477
20478 take_vertical_position_into_account (it);
20479
20480 if (it->glyph_row)
20481 append_composite_glyph (it);
20482 }
20483 else if (it->what == IT_IMAGE)
20484 produce_image_glyph (it);
20485 else if (it->what == IT_STRETCH)
20486 produce_stretch_glyph (it);
20487
20488 /* Accumulate dimensions. Note: can't assume that it->descent > 0
20489 because this isn't true for images with `:ascent 100'. */
20490 xassert (it->ascent >= 0 && it->descent >= 0);
20491 if (it->area == TEXT_AREA)
20492 it->current_x += it->pixel_width;
20493
20494 if (extra_line_spacing > 0)
20495 {
20496 it->descent += extra_line_spacing;
20497 if (extra_line_spacing > it->max_extra_line_spacing)
20498 it->max_extra_line_spacing = extra_line_spacing;
20499 }
20500
20501 it->max_ascent = max (it->max_ascent, it->ascent);
20502 it->max_descent = max (it->max_descent, it->descent);
20503 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
20504 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
20505 }
20506
20507 /* EXPORT for RIF:
20508 Output LEN glyphs starting at START at the nominal cursor position.
20509 Advance the nominal cursor over the text. The global variable
20510 updated_window contains the window being updated, updated_row is
20511 the glyph row being updated, and updated_area is the area of that
20512 row being updated. */
20513
20514 void
20515 x_write_glyphs (start, len)
20516 struct glyph *start;
20517 int len;
20518 {
20519 int x, hpos;
20520
20521 xassert (updated_window && updated_row);
20522 BLOCK_INPUT;
20523
20524 /* Write glyphs. */
20525
20526 hpos = start - updated_row->glyphs[updated_area];
20527 x = draw_glyphs (updated_window, output_cursor.x,
20528 updated_row, updated_area,
20529 hpos, hpos + len,
20530 DRAW_NORMAL_TEXT, 0);
20531
20532 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
20533 if (updated_area == TEXT_AREA
20534 && updated_window->phys_cursor_on_p
20535 && updated_window->phys_cursor.vpos == output_cursor.vpos
20536 && updated_window->phys_cursor.hpos >= hpos
20537 && updated_window->phys_cursor.hpos < hpos + len)
20538 updated_window->phys_cursor_on_p = 0;
20539
20540 UNBLOCK_INPUT;
20541
20542 /* Advance the output cursor. */
20543 output_cursor.hpos += len;
20544 output_cursor.x = x;
20545 }
20546
20547
20548 /* EXPORT for RIF:
20549 Insert LEN glyphs from START at the nominal cursor position. */
20550
20551 void
20552 x_insert_glyphs (start, len)
20553 struct glyph *start;
20554 int len;
20555 {
20556 struct frame *f;
20557 struct window *w;
20558 int line_height, shift_by_width, shifted_region_width;
20559 struct glyph_row *row;
20560 struct glyph *glyph;
20561 int frame_x, frame_y, hpos;
20562
20563 xassert (updated_window && updated_row);
20564 BLOCK_INPUT;
20565 w = updated_window;
20566 f = XFRAME (WINDOW_FRAME (w));
20567
20568 /* Get the height of the line we are in. */
20569 row = updated_row;
20570 line_height = row->height;
20571
20572 /* Get the width of the glyphs to insert. */
20573 shift_by_width = 0;
20574 for (glyph = start; glyph < start + len; ++glyph)
20575 shift_by_width += glyph->pixel_width;
20576
20577 /* Get the width of the region to shift right. */
20578 shifted_region_width = (window_box_width (w, updated_area)
20579 - output_cursor.x
20580 - shift_by_width);
20581
20582 /* Shift right. */
20583 frame_x = window_box_left (w, updated_area) + output_cursor.x;
20584 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
20585
20586 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
20587 line_height, shift_by_width);
20588
20589 /* Write the glyphs. */
20590 hpos = start - row->glyphs[updated_area];
20591 draw_glyphs (w, output_cursor.x, row, updated_area,
20592 hpos, hpos + len,
20593 DRAW_NORMAL_TEXT, 0);
20594
20595 /* Advance the output cursor. */
20596 output_cursor.hpos += len;
20597 output_cursor.x += shift_by_width;
20598 UNBLOCK_INPUT;
20599 }
20600
20601
20602 /* EXPORT for RIF:
20603 Erase the current text line from the nominal cursor position
20604 (inclusive) to pixel column TO_X (exclusive). The idea is that
20605 everything from TO_X onward is already erased.
20606
20607 TO_X is a pixel position relative to updated_area of
20608 updated_window. TO_X == -1 means clear to the end of this area. */
20609
20610 void
20611 x_clear_end_of_line (to_x)
20612 int to_x;
20613 {
20614 struct frame *f;
20615 struct window *w = updated_window;
20616 int max_x, min_y, max_y;
20617 int from_x, from_y, to_y;
20618
20619 xassert (updated_window && updated_row);
20620 f = XFRAME (w->frame);
20621
20622 if (updated_row->full_width_p)
20623 max_x = WINDOW_TOTAL_WIDTH (w);
20624 else
20625 max_x = window_box_width (w, updated_area);
20626 max_y = window_text_bottom_y (w);
20627
20628 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
20629 of window. For TO_X > 0, truncate to end of drawing area. */
20630 if (to_x == 0)
20631 return;
20632 else if (to_x < 0)
20633 to_x = max_x;
20634 else
20635 to_x = min (to_x, max_x);
20636
20637 to_y = min (max_y, output_cursor.y + updated_row->height);
20638
20639 /* Notice if the cursor will be cleared by this operation. */
20640 if (!updated_row->full_width_p)
20641 notice_overwritten_cursor (w, updated_area,
20642 output_cursor.x, -1,
20643 updated_row->y,
20644 MATRIX_ROW_BOTTOM_Y (updated_row));
20645
20646 from_x = output_cursor.x;
20647
20648 /* Translate to frame coordinates. */
20649 if (updated_row->full_width_p)
20650 {
20651 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
20652 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
20653 }
20654 else
20655 {
20656 int area_left = window_box_left (w, updated_area);
20657 from_x += area_left;
20658 to_x += area_left;
20659 }
20660
20661 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
20662 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
20663 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
20664
20665 /* Prevent inadvertently clearing to end of the X window. */
20666 if (to_x > from_x && to_y > from_y)
20667 {
20668 BLOCK_INPUT;
20669 rif->clear_frame_area (f, from_x, from_y,
20670 to_x - from_x, to_y - from_y);
20671 UNBLOCK_INPUT;
20672 }
20673 }
20674
20675 #endif /* HAVE_WINDOW_SYSTEM */
20676
20677
20678 \f
20679 /***********************************************************************
20680 Cursor types
20681 ***********************************************************************/
20682
20683 /* Value is the internal representation of the specified cursor type
20684 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
20685 of the bar cursor. */
20686
20687 static enum text_cursor_kinds
20688 get_specified_cursor_type (arg, width)
20689 Lisp_Object arg;
20690 int *width;
20691 {
20692 enum text_cursor_kinds type;
20693
20694 if (NILP (arg))
20695 return NO_CURSOR;
20696
20697 if (EQ (arg, Qbox))
20698 return FILLED_BOX_CURSOR;
20699
20700 if (EQ (arg, Qhollow))
20701 return HOLLOW_BOX_CURSOR;
20702
20703 if (EQ (arg, Qbar))
20704 {
20705 *width = 2;
20706 return BAR_CURSOR;
20707 }
20708
20709 if (CONSP (arg)
20710 && EQ (XCAR (arg), Qbar)
20711 && INTEGERP (XCDR (arg))
20712 && XINT (XCDR (arg)) >= 0)
20713 {
20714 *width = XINT (XCDR (arg));
20715 return BAR_CURSOR;
20716 }
20717
20718 if (EQ (arg, Qhbar))
20719 {
20720 *width = 2;
20721 return HBAR_CURSOR;
20722 }
20723
20724 if (CONSP (arg)
20725 && EQ (XCAR (arg), Qhbar)
20726 && INTEGERP (XCDR (arg))
20727 && XINT (XCDR (arg)) >= 0)
20728 {
20729 *width = XINT (XCDR (arg));
20730 return HBAR_CURSOR;
20731 }
20732
20733 /* Treat anything unknown as "hollow box cursor".
20734 It was bad to signal an error; people have trouble fixing
20735 .Xdefaults with Emacs, when it has something bad in it. */
20736 type = HOLLOW_BOX_CURSOR;
20737
20738 return type;
20739 }
20740
20741 /* Set the default cursor types for specified frame. */
20742 void
20743 set_frame_cursor_types (f, arg)
20744 struct frame *f;
20745 Lisp_Object arg;
20746 {
20747 int width;
20748 Lisp_Object tem;
20749
20750 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
20751 FRAME_CURSOR_WIDTH (f) = width;
20752
20753 /* By default, set up the blink-off state depending on the on-state. */
20754
20755 tem = Fassoc (arg, Vblink_cursor_alist);
20756 if (!NILP (tem))
20757 {
20758 FRAME_BLINK_OFF_CURSOR (f)
20759 = get_specified_cursor_type (XCDR (tem), &width);
20760 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
20761 }
20762 else
20763 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
20764 }
20765
20766
20767 /* Return the cursor we want to be displayed in window W. Return
20768 width of bar/hbar cursor through WIDTH arg. Return with
20769 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
20770 (i.e. if the `system caret' should track this cursor).
20771
20772 In a mini-buffer window, we want the cursor only to appear if we
20773 are reading input from this window. For the selected window, we
20774 want the cursor type given by the frame parameter or buffer local
20775 setting of cursor-type. If explicitly marked off, draw no cursor.
20776 In all other cases, we want a hollow box cursor. */
20777
20778 static enum text_cursor_kinds
20779 get_window_cursor_type (w, glyph, width, active_cursor)
20780 struct window *w;
20781 struct glyph *glyph;
20782 int *width;
20783 int *active_cursor;
20784 {
20785 struct frame *f = XFRAME (w->frame);
20786 struct buffer *b = XBUFFER (w->buffer);
20787 int cursor_type = DEFAULT_CURSOR;
20788 Lisp_Object alt_cursor;
20789 int non_selected = 0;
20790
20791 *active_cursor = 1;
20792
20793 /* Echo area */
20794 if (cursor_in_echo_area
20795 && FRAME_HAS_MINIBUF_P (f)
20796 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
20797 {
20798 if (w == XWINDOW (echo_area_window))
20799 {
20800 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
20801 {
20802 *width = FRAME_CURSOR_WIDTH (f);
20803 return FRAME_DESIRED_CURSOR (f);
20804 }
20805 else
20806 return get_specified_cursor_type (b->cursor_type, width);
20807 }
20808
20809 *active_cursor = 0;
20810 non_selected = 1;
20811 }
20812
20813 /* Nonselected window or nonselected frame. */
20814 else if (w != XWINDOW (f->selected_window)
20815 #ifdef HAVE_WINDOW_SYSTEM
20816 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
20817 #endif
20818 )
20819 {
20820 *active_cursor = 0;
20821
20822 if (MINI_WINDOW_P (w) && minibuf_level == 0)
20823 return NO_CURSOR;
20824
20825 non_selected = 1;
20826 }
20827
20828 /* Never display a cursor in a window in which cursor-type is nil. */
20829 if (NILP (b->cursor_type))
20830 return NO_CURSOR;
20831
20832 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
20833 if (non_selected)
20834 {
20835 alt_cursor = b->cursor_in_non_selected_windows;
20836 return get_specified_cursor_type (alt_cursor, width);
20837 }
20838
20839 /* Get the normal cursor type for this window. */
20840 if (EQ (b->cursor_type, Qt))
20841 {
20842 cursor_type = FRAME_DESIRED_CURSOR (f);
20843 *width = FRAME_CURSOR_WIDTH (f);
20844 }
20845 else
20846 cursor_type = get_specified_cursor_type (b->cursor_type, width);
20847
20848 /* Use normal cursor if not blinked off. */
20849 if (!w->cursor_off_p)
20850 {
20851 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
20852 if (cursor_type == FILLED_BOX_CURSOR)
20853 cursor_type = HOLLOW_BOX_CURSOR;
20854 }
20855 return cursor_type;
20856 }
20857
20858 /* Cursor is blinked off, so determine how to "toggle" it. */
20859
20860 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
20861 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
20862 return get_specified_cursor_type (XCDR (alt_cursor), width);
20863
20864 /* Then see if frame has specified a specific blink off cursor type. */
20865 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
20866 {
20867 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
20868 return FRAME_BLINK_OFF_CURSOR (f);
20869 }
20870
20871 #if 0
20872 /* Some people liked having a permanently visible blinking cursor,
20873 while others had very strong opinions against it. So it was
20874 decided to remove it. KFS 2003-09-03 */
20875
20876 /* Finally perform built-in cursor blinking:
20877 filled box <-> hollow box
20878 wide [h]bar <-> narrow [h]bar
20879 narrow [h]bar <-> no cursor
20880 other type <-> no cursor */
20881
20882 if (cursor_type == FILLED_BOX_CURSOR)
20883 return HOLLOW_BOX_CURSOR;
20884
20885 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
20886 {
20887 *width = 1;
20888 return cursor_type;
20889 }
20890 #endif
20891
20892 return NO_CURSOR;
20893 }
20894
20895
20896 #ifdef HAVE_WINDOW_SYSTEM
20897
20898 /* Notice when the text cursor of window W has been completely
20899 overwritten by a drawing operation that outputs glyphs in AREA
20900 starting at X0 and ending at X1 in the line starting at Y0 and
20901 ending at Y1. X coordinates are area-relative. X1 < 0 means all
20902 the rest of the line after X0 has been written. Y coordinates
20903 are window-relative. */
20904
20905 static void
20906 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
20907 struct window *w;
20908 enum glyph_row_area area;
20909 int x0, y0, x1, y1;
20910 {
20911 int cx0, cx1, cy0, cy1;
20912 struct glyph_row *row;
20913
20914 if (!w->phys_cursor_on_p)
20915 return;
20916 if (area != TEXT_AREA)
20917 return;
20918
20919 if (w->phys_cursor.vpos < 0
20920 || w->phys_cursor.vpos >= w->current_matrix->nrows
20921 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
20922 !(row->enabled_p && row->displays_text_p)))
20923 return;
20924
20925 if (row->cursor_in_fringe_p)
20926 {
20927 row->cursor_in_fringe_p = 0;
20928 draw_fringe_bitmap (w, row, 0);
20929 w->phys_cursor_on_p = 0;
20930 return;
20931 }
20932
20933 cx0 = w->phys_cursor.x;
20934 cx1 = cx0 + w->phys_cursor_width;
20935 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
20936 return;
20937
20938 /* The cursor image will be completely removed from the
20939 screen if the output area intersects the cursor area in
20940 y-direction. When we draw in [y0 y1[, and some part of
20941 the cursor is at y < y0, that part must have been drawn
20942 before. When scrolling, the cursor is erased before
20943 actually scrolling, so we don't come here. When not
20944 scrolling, the rows above the old cursor row must have
20945 changed, and in this case these rows must have written
20946 over the cursor image.
20947
20948 Likewise if part of the cursor is below y1, with the
20949 exception of the cursor being in the first blank row at
20950 the buffer and window end because update_text_area
20951 doesn't draw that row. (Except when it does, but
20952 that's handled in update_text_area.) */
20953
20954 cy0 = w->phys_cursor.y;
20955 cy1 = cy0 + w->phys_cursor_height;
20956 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
20957 return;
20958
20959 w->phys_cursor_on_p = 0;
20960 }
20961
20962 #endif /* HAVE_WINDOW_SYSTEM */
20963
20964 \f
20965 /************************************************************************
20966 Mouse Face
20967 ************************************************************************/
20968
20969 #ifdef HAVE_WINDOW_SYSTEM
20970
20971 /* EXPORT for RIF:
20972 Fix the display of area AREA of overlapping row ROW in window W
20973 with respect to the overlapping part OVERLAPS. */
20974
20975 void
20976 x_fix_overlapping_area (w, row, area, overlaps)
20977 struct window *w;
20978 struct glyph_row *row;
20979 enum glyph_row_area area;
20980 int overlaps;
20981 {
20982 int i, x;
20983
20984 BLOCK_INPUT;
20985
20986 x = 0;
20987 for (i = 0; i < row->used[area];)
20988 {
20989 if (row->glyphs[area][i].overlaps_vertically_p)
20990 {
20991 int start = i, start_x = x;
20992
20993 do
20994 {
20995 x += row->glyphs[area][i].pixel_width;
20996 ++i;
20997 }
20998 while (i < row->used[area]
20999 && row->glyphs[area][i].overlaps_vertically_p);
21000
21001 draw_glyphs (w, start_x, row, area,
21002 start, i,
21003 DRAW_NORMAL_TEXT, overlaps);
21004 }
21005 else
21006 {
21007 x += row->glyphs[area][i].pixel_width;
21008 ++i;
21009 }
21010 }
21011
21012 UNBLOCK_INPUT;
21013 }
21014
21015
21016 /* EXPORT:
21017 Draw the cursor glyph of window W in glyph row ROW. See the
21018 comment of draw_glyphs for the meaning of HL. */
21019
21020 void
21021 draw_phys_cursor_glyph (w, row, hl)
21022 struct window *w;
21023 struct glyph_row *row;
21024 enum draw_glyphs_face hl;
21025 {
21026 /* If cursor hpos is out of bounds, don't draw garbage. This can
21027 happen in mini-buffer windows when switching between echo area
21028 glyphs and mini-buffer. */
21029 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
21030 {
21031 int on_p = w->phys_cursor_on_p;
21032 int x1;
21033 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
21034 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
21035 hl, 0);
21036 w->phys_cursor_on_p = on_p;
21037
21038 if (hl == DRAW_CURSOR)
21039 w->phys_cursor_width = x1 - w->phys_cursor.x;
21040 /* When we erase the cursor, and ROW is overlapped by other
21041 rows, make sure that these overlapping parts of other rows
21042 are redrawn. */
21043 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
21044 {
21045 w->phys_cursor_width = x1 - w->phys_cursor.x;
21046
21047 if (row > w->current_matrix->rows
21048 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
21049 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
21050 OVERLAPS_ERASED_CURSOR);
21051
21052 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
21053 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
21054 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
21055 OVERLAPS_ERASED_CURSOR);
21056 }
21057 }
21058 }
21059
21060
21061 /* EXPORT:
21062 Erase the image of a cursor of window W from the screen. */
21063
21064 void
21065 erase_phys_cursor (w)
21066 struct window *w;
21067 {
21068 struct frame *f = XFRAME (w->frame);
21069 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21070 int hpos = w->phys_cursor.hpos;
21071 int vpos = w->phys_cursor.vpos;
21072 int mouse_face_here_p = 0;
21073 struct glyph_matrix *active_glyphs = w->current_matrix;
21074 struct glyph_row *cursor_row;
21075 struct glyph *cursor_glyph;
21076 enum draw_glyphs_face hl;
21077
21078 /* No cursor displayed or row invalidated => nothing to do on the
21079 screen. */
21080 if (w->phys_cursor_type == NO_CURSOR)
21081 goto mark_cursor_off;
21082
21083 /* VPOS >= active_glyphs->nrows means that window has been resized.
21084 Don't bother to erase the cursor. */
21085 if (vpos >= active_glyphs->nrows)
21086 goto mark_cursor_off;
21087
21088 /* If row containing cursor is marked invalid, there is nothing we
21089 can do. */
21090 cursor_row = MATRIX_ROW (active_glyphs, vpos);
21091 if (!cursor_row->enabled_p)
21092 goto mark_cursor_off;
21093
21094 /* If line spacing is > 0, old cursor may only be partially visible in
21095 window after split-window. So adjust visible height. */
21096 cursor_row->visible_height = min (cursor_row->visible_height,
21097 window_text_bottom_y (w) - cursor_row->y);
21098
21099 /* If row is completely invisible, don't attempt to delete a cursor which
21100 isn't there. This can happen if cursor is at top of a window, and
21101 we switch to a buffer with a header line in that window. */
21102 if (cursor_row->visible_height <= 0)
21103 goto mark_cursor_off;
21104
21105 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
21106 if (cursor_row->cursor_in_fringe_p)
21107 {
21108 cursor_row->cursor_in_fringe_p = 0;
21109 draw_fringe_bitmap (w, cursor_row, 0);
21110 goto mark_cursor_off;
21111 }
21112
21113 /* This can happen when the new row is shorter than the old one.
21114 In this case, either draw_glyphs or clear_end_of_line
21115 should have cleared the cursor. Note that we wouldn't be
21116 able to erase the cursor in this case because we don't have a
21117 cursor glyph at hand. */
21118 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
21119 goto mark_cursor_off;
21120
21121 /* If the cursor is in the mouse face area, redisplay that when
21122 we clear the cursor. */
21123 if (! NILP (dpyinfo->mouse_face_window)
21124 && w == XWINDOW (dpyinfo->mouse_face_window)
21125 && (vpos > dpyinfo->mouse_face_beg_row
21126 || (vpos == dpyinfo->mouse_face_beg_row
21127 && hpos >= dpyinfo->mouse_face_beg_col))
21128 && (vpos < dpyinfo->mouse_face_end_row
21129 || (vpos == dpyinfo->mouse_face_end_row
21130 && hpos < dpyinfo->mouse_face_end_col))
21131 /* Don't redraw the cursor's spot in mouse face if it is at the
21132 end of a line (on a newline). The cursor appears there, but
21133 mouse highlighting does not. */
21134 && cursor_row->used[TEXT_AREA] > hpos)
21135 mouse_face_here_p = 1;
21136
21137 /* Maybe clear the display under the cursor. */
21138 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
21139 {
21140 int x, y;
21141 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
21142 int width;
21143
21144 cursor_glyph = get_phys_cursor_glyph (w);
21145 if (cursor_glyph == NULL)
21146 goto mark_cursor_off;
21147
21148 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
21149 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
21150 width = min (cursor_glyph->pixel_width,
21151 window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
21152
21153 rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
21154 }
21155
21156 /* Erase the cursor by redrawing the character underneath it. */
21157 if (mouse_face_here_p)
21158 hl = DRAW_MOUSE_FACE;
21159 else
21160 hl = DRAW_NORMAL_TEXT;
21161 draw_phys_cursor_glyph (w, cursor_row, hl);
21162
21163 mark_cursor_off:
21164 w->phys_cursor_on_p = 0;
21165 w->phys_cursor_type = NO_CURSOR;
21166 }
21167
21168
21169 /* EXPORT:
21170 Display or clear cursor of window W. If ON is zero, clear the
21171 cursor. If it is non-zero, display the cursor. If ON is nonzero,
21172 where to put the cursor is specified by HPOS, VPOS, X and Y. */
21173
21174 void
21175 display_and_set_cursor (w, on, hpos, vpos, x, y)
21176 struct window *w;
21177 int on, hpos, vpos, x, y;
21178 {
21179 struct frame *f = XFRAME (w->frame);
21180 int new_cursor_type;
21181 int new_cursor_width;
21182 int active_cursor;
21183 struct glyph_row *glyph_row;
21184 struct glyph *glyph;
21185
21186 /* This is pointless on invisible frames, and dangerous on garbaged
21187 windows and frames; in the latter case, the frame or window may
21188 be in the midst of changing its size, and x and y may be off the
21189 window. */
21190 if (! FRAME_VISIBLE_P (f)
21191 || FRAME_GARBAGED_P (f)
21192 || vpos >= w->current_matrix->nrows
21193 || hpos >= w->current_matrix->matrix_w)
21194 return;
21195
21196 /* If cursor is off and we want it off, return quickly. */
21197 if (!on && !w->phys_cursor_on_p)
21198 return;
21199
21200 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
21201 /* If cursor row is not enabled, we don't really know where to
21202 display the cursor. */
21203 if (!glyph_row->enabled_p)
21204 {
21205 w->phys_cursor_on_p = 0;
21206 return;
21207 }
21208
21209 glyph = NULL;
21210 if (!glyph_row->exact_window_width_line_p
21211 || hpos < glyph_row->used[TEXT_AREA])
21212 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
21213
21214 xassert (interrupt_input_blocked);
21215
21216 /* Set new_cursor_type to the cursor we want to be displayed. */
21217 new_cursor_type = get_window_cursor_type (w, glyph,
21218 &new_cursor_width, &active_cursor);
21219
21220 /* If cursor is currently being shown and we don't want it to be or
21221 it is in the wrong place, or the cursor type is not what we want,
21222 erase it. */
21223 if (w->phys_cursor_on_p
21224 && (!on
21225 || w->phys_cursor.x != x
21226 || w->phys_cursor.y != y
21227 || new_cursor_type != w->phys_cursor_type
21228 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
21229 && new_cursor_width != w->phys_cursor_width)))
21230 erase_phys_cursor (w);
21231
21232 /* Don't check phys_cursor_on_p here because that flag is only set
21233 to zero in some cases where we know that the cursor has been
21234 completely erased, to avoid the extra work of erasing the cursor
21235 twice. In other words, phys_cursor_on_p can be 1 and the cursor
21236 still not be visible, or it has only been partly erased. */
21237 if (on)
21238 {
21239 w->phys_cursor_ascent = glyph_row->ascent;
21240 w->phys_cursor_height = glyph_row->height;
21241
21242 /* Set phys_cursor_.* before x_draw_.* is called because some
21243 of them may need the information. */
21244 w->phys_cursor.x = x;
21245 w->phys_cursor.y = glyph_row->y;
21246 w->phys_cursor.hpos = hpos;
21247 w->phys_cursor.vpos = vpos;
21248 }
21249
21250 rif->draw_window_cursor (w, glyph_row, x, y,
21251 new_cursor_type, new_cursor_width,
21252 on, active_cursor);
21253 }
21254
21255
21256 /* Switch the display of W's cursor on or off, according to the value
21257 of ON. */
21258
21259 static void
21260 update_window_cursor (w, on)
21261 struct window *w;
21262 int on;
21263 {
21264 /* Don't update cursor in windows whose frame is in the process
21265 of being deleted. */
21266 if (w->current_matrix)
21267 {
21268 BLOCK_INPUT;
21269 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
21270 w->phys_cursor.x, w->phys_cursor.y);
21271 UNBLOCK_INPUT;
21272 }
21273 }
21274
21275
21276 /* Call update_window_cursor with parameter ON_P on all leaf windows
21277 in the window tree rooted at W. */
21278
21279 static void
21280 update_cursor_in_window_tree (w, on_p)
21281 struct window *w;
21282 int on_p;
21283 {
21284 while (w)
21285 {
21286 if (!NILP (w->hchild))
21287 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
21288 else if (!NILP (w->vchild))
21289 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
21290 else
21291 update_window_cursor (w, on_p);
21292
21293 w = NILP (w->next) ? 0 : XWINDOW (w->next);
21294 }
21295 }
21296
21297
21298 /* EXPORT:
21299 Display the cursor on window W, or clear it, according to ON_P.
21300 Don't change the cursor's position. */
21301
21302 void
21303 x_update_cursor (f, on_p)
21304 struct frame *f;
21305 int on_p;
21306 {
21307 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
21308 }
21309
21310
21311 /* EXPORT:
21312 Clear the cursor of window W to background color, and mark the
21313 cursor as not shown. This is used when the text where the cursor
21314 is is about to be rewritten. */
21315
21316 void
21317 x_clear_cursor (w)
21318 struct window *w;
21319 {
21320 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
21321 update_window_cursor (w, 0);
21322 }
21323
21324
21325 /* EXPORT:
21326 Display the active region described by mouse_face_* according to DRAW. */
21327
21328 void
21329 show_mouse_face (dpyinfo, draw)
21330 Display_Info *dpyinfo;
21331 enum draw_glyphs_face draw;
21332 {
21333 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
21334 struct frame *f = XFRAME (WINDOW_FRAME (w));
21335
21336 if (/* If window is in the process of being destroyed, don't bother
21337 to do anything. */
21338 w->current_matrix != NULL
21339 /* Don't update mouse highlight if hidden */
21340 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
21341 /* Recognize when we are called to operate on rows that don't exist
21342 anymore. This can happen when a window is split. */
21343 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
21344 {
21345 int phys_cursor_on_p = w->phys_cursor_on_p;
21346 struct glyph_row *row, *first, *last;
21347
21348 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
21349 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
21350
21351 for (row = first; row <= last && row->enabled_p; ++row)
21352 {
21353 int start_hpos, end_hpos, start_x;
21354
21355 /* For all but the first row, the highlight starts at column 0. */
21356 if (row == first)
21357 {
21358 start_hpos = dpyinfo->mouse_face_beg_col;
21359 start_x = dpyinfo->mouse_face_beg_x;
21360 }
21361 else
21362 {
21363 start_hpos = 0;
21364 start_x = 0;
21365 }
21366
21367 if (row == last)
21368 end_hpos = dpyinfo->mouse_face_end_col;
21369 else
21370 {
21371 end_hpos = row->used[TEXT_AREA];
21372 if (draw == DRAW_NORMAL_TEXT)
21373 row->fill_line_p = 1; /* Clear to end of line */
21374 }
21375
21376 if (end_hpos > start_hpos)
21377 {
21378 draw_glyphs (w, start_x, row, TEXT_AREA,
21379 start_hpos, end_hpos,
21380 draw, 0);
21381
21382 row->mouse_face_p
21383 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
21384 }
21385 }
21386
21387 /* When we've written over the cursor, arrange for it to
21388 be displayed again. */
21389 if (phys_cursor_on_p && !w->phys_cursor_on_p)
21390 {
21391 BLOCK_INPUT;
21392 display_and_set_cursor (w, 1,
21393 w->phys_cursor.hpos, w->phys_cursor.vpos,
21394 w->phys_cursor.x, w->phys_cursor.y);
21395 UNBLOCK_INPUT;
21396 }
21397 }
21398
21399 /* Change the mouse cursor. */
21400 if (draw == DRAW_NORMAL_TEXT)
21401 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
21402 else if (draw == DRAW_MOUSE_FACE)
21403 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
21404 else
21405 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
21406 }
21407
21408 /* EXPORT:
21409 Clear out the mouse-highlighted active region.
21410 Redraw it un-highlighted first. Value is non-zero if mouse
21411 face was actually drawn unhighlighted. */
21412
21413 int
21414 clear_mouse_face (dpyinfo)
21415 Display_Info *dpyinfo;
21416 {
21417 int cleared = 0;
21418
21419 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
21420 {
21421 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
21422 cleared = 1;
21423 }
21424
21425 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21426 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21427 dpyinfo->mouse_face_window = Qnil;
21428 dpyinfo->mouse_face_overlay = Qnil;
21429 return cleared;
21430 }
21431
21432
21433 /* EXPORT:
21434 Non-zero if physical cursor of window W is within mouse face. */
21435
21436 int
21437 cursor_in_mouse_face_p (w)
21438 struct window *w;
21439 {
21440 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21441 int in_mouse_face = 0;
21442
21443 if (WINDOWP (dpyinfo->mouse_face_window)
21444 && XWINDOW (dpyinfo->mouse_face_window) == w)
21445 {
21446 int hpos = w->phys_cursor.hpos;
21447 int vpos = w->phys_cursor.vpos;
21448
21449 if (vpos >= dpyinfo->mouse_face_beg_row
21450 && vpos <= dpyinfo->mouse_face_end_row
21451 && (vpos > dpyinfo->mouse_face_beg_row
21452 || hpos >= dpyinfo->mouse_face_beg_col)
21453 && (vpos < dpyinfo->mouse_face_end_row
21454 || hpos < dpyinfo->mouse_face_end_col
21455 || dpyinfo->mouse_face_past_end))
21456 in_mouse_face = 1;
21457 }
21458
21459 return in_mouse_face;
21460 }
21461
21462
21463
21464 \f
21465 /* Find the glyph matrix position of buffer position CHARPOS in window
21466 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
21467 current glyphs must be up to date. If CHARPOS is above window
21468 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
21469 of last line in W. In the row containing CHARPOS, stop before glyphs
21470 having STOP as object. */
21471
21472 #if 1 /* This is a version of fast_find_position that's more correct
21473 in the presence of hscrolling, for example. I didn't install
21474 it right away because the problem fixed is minor, it failed
21475 in 20.x as well, and I think it's too risky to install
21476 so near the release of 21.1. 2001-09-25 gerd. */
21477
21478 static int
21479 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
21480 struct window *w;
21481 int charpos;
21482 int *hpos, *vpos, *x, *y;
21483 Lisp_Object stop;
21484 {
21485 struct glyph_row *row, *first;
21486 struct glyph *glyph, *end;
21487 int past_end = 0;
21488
21489 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
21490 if (charpos < MATRIX_ROW_START_CHARPOS (first))
21491 {
21492 *x = first->x;
21493 *y = first->y;
21494 *hpos = 0;
21495 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
21496 return 1;
21497 }
21498
21499 row = row_containing_pos (w, charpos, first, NULL, 0);
21500 if (row == NULL)
21501 {
21502 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
21503 past_end = 1;
21504 }
21505
21506 /* If whole rows or last part of a row came from a display overlay,
21507 row_containing_pos will skip over such rows because their end pos
21508 equals the start pos of the overlay or interval.
21509
21510 Move back if we have a STOP object and previous row's
21511 end glyph came from STOP. */
21512 if (!NILP (stop))
21513 {
21514 struct glyph_row *prev;
21515 while ((prev = row - 1, prev >= first)
21516 && MATRIX_ROW_END_CHARPOS (prev) == charpos
21517 && prev->used[TEXT_AREA] > 0)
21518 {
21519 struct glyph *beg = prev->glyphs[TEXT_AREA];
21520 glyph = beg + prev->used[TEXT_AREA];
21521 while (--glyph >= beg
21522 && INTEGERP (glyph->object));
21523 if (glyph < beg
21524 || !EQ (stop, glyph->object))
21525 break;
21526 row = prev;
21527 }
21528 }
21529
21530 *x = row->x;
21531 *y = row->y;
21532 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
21533
21534 glyph = row->glyphs[TEXT_AREA];
21535 end = glyph + row->used[TEXT_AREA];
21536
21537 /* Skip over glyphs not having an object at the start of the row.
21538 These are special glyphs like truncation marks on terminal
21539 frames. */
21540 if (row->displays_text_p)
21541 while (glyph < end
21542 && INTEGERP (glyph->object)
21543 && !EQ (stop, glyph->object)
21544 && glyph->charpos < 0)
21545 {
21546 *x += glyph->pixel_width;
21547 ++glyph;
21548 }
21549
21550 while (glyph < end
21551 && !INTEGERP (glyph->object)
21552 && !EQ (stop, glyph->object)
21553 && (!BUFFERP (glyph->object)
21554 || glyph->charpos < charpos))
21555 {
21556 *x += glyph->pixel_width;
21557 ++glyph;
21558 }
21559
21560 *hpos = glyph - row->glyphs[TEXT_AREA];
21561 return !past_end;
21562 }
21563
21564 #else /* not 1 */
21565
21566 static int
21567 fast_find_position (w, pos, hpos, vpos, x, y, stop)
21568 struct window *w;
21569 int pos;
21570 int *hpos, *vpos, *x, *y;
21571 Lisp_Object stop;
21572 {
21573 int i;
21574 int lastcol;
21575 int maybe_next_line_p = 0;
21576 int line_start_position;
21577 int yb = window_text_bottom_y (w);
21578 struct glyph_row *row, *best_row;
21579 int row_vpos, best_row_vpos;
21580 int current_x;
21581
21582 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
21583 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
21584
21585 while (row->y < yb)
21586 {
21587 if (row->used[TEXT_AREA])
21588 line_start_position = row->glyphs[TEXT_AREA]->charpos;
21589 else
21590 line_start_position = 0;
21591
21592 if (line_start_position > pos)
21593 break;
21594 /* If the position sought is the end of the buffer,
21595 don't include the blank lines at the bottom of the window. */
21596 else if (line_start_position == pos
21597 && pos == BUF_ZV (XBUFFER (w->buffer)))
21598 {
21599 maybe_next_line_p = 1;
21600 break;
21601 }
21602 else if (line_start_position > 0)
21603 {
21604 best_row = row;
21605 best_row_vpos = row_vpos;
21606 }
21607
21608 if (row->y + row->height >= yb)
21609 break;
21610
21611 ++row;
21612 ++row_vpos;
21613 }
21614
21615 /* Find the right column within BEST_ROW. */
21616 lastcol = 0;
21617 current_x = best_row->x;
21618 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
21619 {
21620 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
21621 int charpos = glyph->charpos;
21622
21623 if (BUFFERP (glyph->object))
21624 {
21625 if (charpos == pos)
21626 {
21627 *hpos = i;
21628 *vpos = best_row_vpos;
21629 *x = current_x;
21630 *y = best_row->y;
21631 return 1;
21632 }
21633 else if (charpos > pos)
21634 break;
21635 }
21636 else if (EQ (glyph->object, stop))
21637 break;
21638
21639 if (charpos > 0)
21640 lastcol = i;
21641 current_x += glyph->pixel_width;
21642 }
21643
21644 /* If we're looking for the end of the buffer,
21645 and we didn't find it in the line we scanned,
21646 use the start of the following line. */
21647 if (maybe_next_line_p)
21648 {
21649 ++best_row;
21650 ++best_row_vpos;
21651 lastcol = 0;
21652 current_x = best_row->x;
21653 }
21654
21655 *vpos = best_row_vpos;
21656 *hpos = lastcol + 1;
21657 *x = current_x;
21658 *y = best_row->y;
21659 return 0;
21660 }
21661
21662 #endif /* not 1 */
21663
21664
21665 /* Find the position of the glyph for position POS in OBJECT in
21666 window W's current matrix, and return in *X, *Y the pixel
21667 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
21668
21669 RIGHT_P non-zero means return the position of the right edge of the
21670 glyph, RIGHT_P zero means return the left edge position.
21671
21672 If no glyph for POS exists in the matrix, return the position of
21673 the glyph with the next smaller position that is in the matrix, if
21674 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
21675 exists in the matrix, return the position of the glyph with the
21676 next larger position in OBJECT.
21677
21678 Value is non-zero if a glyph was found. */
21679
21680 static int
21681 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
21682 struct window *w;
21683 int pos;
21684 Lisp_Object object;
21685 int *hpos, *vpos, *x, *y;
21686 int right_p;
21687 {
21688 int yb = window_text_bottom_y (w);
21689 struct glyph_row *r;
21690 struct glyph *best_glyph = NULL;
21691 struct glyph_row *best_row = NULL;
21692 int best_x = 0;
21693
21694 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
21695 r->enabled_p && r->y < yb;
21696 ++r)
21697 {
21698 struct glyph *g = r->glyphs[TEXT_AREA];
21699 struct glyph *e = g + r->used[TEXT_AREA];
21700 int gx;
21701
21702 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
21703 if (EQ (g->object, object))
21704 {
21705 if (g->charpos == pos)
21706 {
21707 best_glyph = g;
21708 best_x = gx;
21709 best_row = r;
21710 goto found;
21711 }
21712 else if (best_glyph == NULL
21713 || ((abs (g->charpos - pos)
21714 < abs (best_glyph->charpos - pos))
21715 && (right_p
21716 ? g->charpos < pos
21717 : g->charpos > pos)))
21718 {
21719 best_glyph = g;
21720 best_x = gx;
21721 best_row = r;
21722 }
21723 }
21724 }
21725
21726 found:
21727
21728 if (best_glyph)
21729 {
21730 *x = best_x;
21731 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
21732
21733 if (right_p)
21734 {
21735 *x += best_glyph->pixel_width;
21736 ++*hpos;
21737 }
21738
21739 *y = best_row->y;
21740 *vpos = best_row - w->current_matrix->rows;
21741 }
21742
21743 return best_glyph != NULL;
21744 }
21745
21746
21747 /* See if position X, Y is within a hot-spot of an image. */
21748
21749 static int
21750 on_hot_spot_p (hot_spot, x, y)
21751 Lisp_Object hot_spot;
21752 int x, y;
21753 {
21754 if (!CONSP (hot_spot))
21755 return 0;
21756
21757 if (EQ (XCAR (hot_spot), Qrect))
21758 {
21759 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
21760 Lisp_Object rect = XCDR (hot_spot);
21761 Lisp_Object tem;
21762 if (!CONSP (rect))
21763 return 0;
21764 if (!CONSP (XCAR (rect)))
21765 return 0;
21766 if (!CONSP (XCDR (rect)))
21767 return 0;
21768 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
21769 return 0;
21770 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
21771 return 0;
21772 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
21773 return 0;
21774 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
21775 return 0;
21776 return 1;
21777 }
21778 else if (EQ (XCAR (hot_spot), Qcircle))
21779 {
21780 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
21781 Lisp_Object circ = XCDR (hot_spot);
21782 Lisp_Object lr, lx0, ly0;
21783 if (CONSP (circ)
21784 && CONSP (XCAR (circ))
21785 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
21786 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
21787 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
21788 {
21789 double r = XFLOATINT (lr);
21790 double dx = XINT (lx0) - x;
21791 double dy = XINT (ly0) - y;
21792 return (dx * dx + dy * dy <= r * r);
21793 }
21794 }
21795 else if (EQ (XCAR (hot_spot), Qpoly))
21796 {
21797 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
21798 if (VECTORP (XCDR (hot_spot)))
21799 {
21800 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
21801 Lisp_Object *poly = v->contents;
21802 int n = v->size;
21803 int i;
21804 int inside = 0;
21805 Lisp_Object lx, ly;
21806 int x0, y0;
21807
21808 /* Need an even number of coordinates, and at least 3 edges. */
21809 if (n < 6 || n & 1)
21810 return 0;
21811
21812 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
21813 If count is odd, we are inside polygon. Pixels on edges
21814 may or may not be included depending on actual geometry of the
21815 polygon. */
21816 if ((lx = poly[n-2], !INTEGERP (lx))
21817 || (ly = poly[n-1], !INTEGERP (lx)))
21818 return 0;
21819 x0 = XINT (lx), y0 = XINT (ly);
21820 for (i = 0; i < n; i += 2)
21821 {
21822 int x1 = x0, y1 = y0;
21823 if ((lx = poly[i], !INTEGERP (lx))
21824 || (ly = poly[i+1], !INTEGERP (ly)))
21825 return 0;
21826 x0 = XINT (lx), y0 = XINT (ly);
21827
21828 /* Does this segment cross the X line? */
21829 if (x0 >= x)
21830 {
21831 if (x1 >= x)
21832 continue;
21833 }
21834 else if (x1 < x)
21835 continue;
21836 if (y > y0 && y > y1)
21837 continue;
21838 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
21839 inside = !inside;
21840 }
21841 return inside;
21842 }
21843 }
21844 /* If we don't understand the format, pretend we're not in the hot-spot. */
21845 return 0;
21846 }
21847
21848 Lisp_Object
21849 find_hot_spot (map, x, y)
21850 Lisp_Object map;
21851 int x, y;
21852 {
21853 while (CONSP (map))
21854 {
21855 if (CONSP (XCAR (map))
21856 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
21857 return XCAR (map);
21858 map = XCDR (map);
21859 }
21860
21861 return Qnil;
21862 }
21863
21864 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
21865 3, 3, 0,
21866 doc: /* Lookup in image map MAP coordinates X and Y.
21867 An image map is an alist where each element has the format (AREA ID PLIST).
21868 An AREA is specified as either a rectangle, a circle, or a polygon:
21869 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
21870 pixel coordinates of the upper left and bottom right corners.
21871 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
21872 and the radius of the circle; r may be a float or integer.
21873 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
21874 vector describes one corner in the polygon.
21875 Returns the alist element for the first matching AREA in MAP. */)
21876 (map, x, y)
21877 Lisp_Object map;
21878 Lisp_Object x, y;
21879 {
21880 if (NILP (map))
21881 return Qnil;
21882
21883 CHECK_NUMBER (x);
21884 CHECK_NUMBER (y);
21885
21886 return find_hot_spot (map, XINT (x), XINT (y));
21887 }
21888
21889
21890 /* Display frame CURSOR, optionally using shape defined by POINTER. */
21891 static void
21892 define_frame_cursor1 (f, cursor, pointer)
21893 struct frame *f;
21894 Cursor cursor;
21895 Lisp_Object pointer;
21896 {
21897 /* Do not change cursor shape while dragging mouse. */
21898 if (!NILP (do_mouse_tracking))
21899 return;
21900
21901 if (!NILP (pointer))
21902 {
21903 if (EQ (pointer, Qarrow))
21904 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21905 else if (EQ (pointer, Qhand))
21906 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
21907 else if (EQ (pointer, Qtext))
21908 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21909 else if (EQ (pointer, intern ("hdrag")))
21910 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21911 #ifdef HAVE_X_WINDOWS
21912 else if (EQ (pointer, intern ("vdrag")))
21913 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
21914 #endif
21915 else if (EQ (pointer, intern ("hourglass")))
21916 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
21917 else if (EQ (pointer, Qmodeline))
21918 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
21919 else
21920 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21921 }
21922
21923 if (cursor != No_Cursor)
21924 rif->define_frame_cursor (f, cursor);
21925 }
21926
21927 /* Take proper action when mouse has moved to the mode or header line
21928 or marginal area AREA of window W, x-position X and y-position Y.
21929 X is relative to the start of the text display area of W, so the
21930 width of bitmap areas and scroll bars must be subtracted to get a
21931 position relative to the start of the mode line. */
21932
21933 static void
21934 note_mode_line_or_margin_highlight (window, x, y, area)
21935 Lisp_Object window;
21936 int x, y;
21937 enum window_part area;
21938 {
21939 struct window *w = XWINDOW (window);
21940 struct frame *f = XFRAME (w->frame);
21941 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21942 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21943 Lisp_Object pointer = Qnil;
21944 int charpos, dx, dy, width, height;
21945 Lisp_Object string, object = Qnil;
21946 Lisp_Object pos, help;
21947
21948 Lisp_Object mouse_face;
21949 int original_x_pixel = x;
21950 struct glyph * glyph = NULL;
21951 struct glyph_row *row;
21952
21953 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
21954 {
21955 int x0;
21956 struct glyph *end;
21957
21958 string = mode_line_string (w, area, &x, &y, &charpos,
21959 &object, &dx, &dy, &width, &height);
21960
21961 row = (area == ON_MODE_LINE
21962 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
21963 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
21964
21965 /* Find glyph */
21966 if (row->mode_line_p && row->enabled_p)
21967 {
21968 glyph = row->glyphs[TEXT_AREA];
21969 end = glyph + row->used[TEXT_AREA];
21970
21971 for (x0 = original_x_pixel;
21972 glyph < end && x0 >= glyph->pixel_width;
21973 ++glyph)
21974 x0 -= glyph->pixel_width;
21975
21976 if (glyph >= end)
21977 glyph = NULL;
21978 }
21979 }
21980 else
21981 {
21982 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
21983 string = marginal_area_string (w, area, &x, &y, &charpos,
21984 &object, &dx, &dy, &width, &height);
21985 }
21986
21987 help = Qnil;
21988
21989 if (IMAGEP (object))
21990 {
21991 Lisp_Object image_map, hotspot;
21992 if ((image_map = Fplist_get (XCDR (object), QCmap),
21993 !NILP (image_map))
21994 && (hotspot = find_hot_spot (image_map, dx, dy),
21995 CONSP (hotspot))
21996 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21997 {
21998 Lisp_Object area_id, plist;
21999
22000 area_id = XCAR (hotspot);
22001 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22002 If so, we could look for mouse-enter, mouse-leave
22003 properties in PLIST (and do something...). */
22004 hotspot = XCDR (hotspot);
22005 if (CONSP (hotspot)
22006 && (plist = XCAR (hotspot), CONSP (plist)))
22007 {
22008 pointer = Fplist_get (plist, Qpointer);
22009 if (NILP (pointer))
22010 pointer = Qhand;
22011 help = Fplist_get (plist, Qhelp_echo);
22012 if (!NILP (help))
22013 {
22014 help_echo_string = help;
22015 /* Is this correct? ++kfs */
22016 XSETWINDOW (help_echo_window, w);
22017 help_echo_object = w->buffer;
22018 help_echo_pos = charpos;
22019 }
22020 }
22021 }
22022 if (NILP (pointer))
22023 pointer = Fplist_get (XCDR (object), QCpointer);
22024 }
22025
22026 if (STRINGP (string))
22027 {
22028 pos = make_number (charpos);
22029 /* If we're on a string with `help-echo' text property, arrange
22030 for the help to be displayed. This is done by setting the
22031 global variable help_echo_string to the help string. */
22032 if (NILP (help))
22033 {
22034 help = Fget_text_property (pos, Qhelp_echo, string);
22035 if (!NILP (help))
22036 {
22037 help_echo_string = help;
22038 XSETWINDOW (help_echo_window, w);
22039 help_echo_object = string;
22040 help_echo_pos = charpos;
22041 }
22042 }
22043
22044 if (NILP (pointer))
22045 pointer = Fget_text_property (pos, Qpointer, string);
22046
22047 /* Change the mouse pointer according to what is under X/Y. */
22048 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
22049 {
22050 Lisp_Object map;
22051 map = Fget_text_property (pos, Qlocal_map, string);
22052 if (!KEYMAPP (map))
22053 map = Fget_text_property (pos, Qkeymap, string);
22054 if (!KEYMAPP (map))
22055 cursor = dpyinfo->vertical_scroll_bar_cursor;
22056 }
22057
22058 /* Change the mouse face according to what is under X/Y. */
22059 mouse_face = Fget_text_property (pos, Qmouse_face, string);
22060 if (!NILP (mouse_face)
22061 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22062 && glyph)
22063 {
22064 Lisp_Object b, e;
22065
22066 struct glyph * tmp_glyph;
22067
22068 int gpos;
22069 int gseq_length;
22070 int total_pixel_width;
22071 int ignore;
22072
22073 int vpos, hpos;
22074
22075 b = Fprevious_single_property_change (make_number (charpos + 1),
22076 Qmouse_face, string, Qnil);
22077 if (NILP (b))
22078 b = make_number (0);
22079
22080 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
22081 if (NILP (e))
22082 e = make_number (SCHARS (string));
22083
22084 /* Calculate the position(glyph position: GPOS) of GLYPH in
22085 displayed string. GPOS is different from CHARPOS.
22086
22087 CHARPOS is the position of glyph in internal string
22088 object. A mode line string format has structures which
22089 is converted to a flatten by emacs lisp interpreter.
22090 The internal string is an element of the structures.
22091 The displayed string is the flatten string. */
22092 for (tmp_glyph = glyph - 1, gpos = 0;
22093 tmp_glyph->charpos >= XINT (b);
22094 tmp_glyph--, gpos++)
22095 {
22096 if (!EQ (tmp_glyph->object, glyph->object))
22097 break;
22098 }
22099
22100 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
22101 displayed string holding GLYPH.
22102
22103 GSEQ_LENGTH is different from SCHARS (STRING).
22104 SCHARS (STRING) returns the length of the internal string. */
22105 for (tmp_glyph = glyph, gseq_length = gpos;
22106 tmp_glyph->charpos < XINT (e);
22107 tmp_glyph++, gseq_length++)
22108 {
22109 if (!EQ (tmp_glyph->object, glyph->object))
22110 break;
22111 }
22112
22113 total_pixel_width = 0;
22114 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
22115 total_pixel_width += tmp_glyph->pixel_width;
22116
22117 /* Pre calculation of re-rendering position */
22118 vpos = (x - gpos);
22119 hpos = (area == ON_MODE_LINE
22120 ? (w->current_matrix)->nrows - 1
22121 : 0);
22122
22123 /* If the re-rendering position is included in the last
22124 re-rendering area, we should do nothing. */
22125 if ( EQ (window, dpyinfo->mouse_face_window)
22126 && dpyinfo->mouse_face_beg_col <= vpos
22127 && vpos < dpyinfo->mouse_face_end_col
22128 && dpyinfo->mouse_face_beg_row == hpos )
22129 return;
22130
22131 if (clear_mouse_face (dpyinfo))
22132 cursor = No_Cursor;
22133
22134 dpyinfo->mouse_face_beg_col = vpos;
22135 dpyinfo->mouse_face_beg_row = hpos;
22136
22137 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
22138 dpyinfo->mouse_face_beg_y = 0;
22139
22140 dpyinfo->mouse_face_end_col = vpos + gseq_length;
22141 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
22142
22143 dpyinfo->mouse_face_end_x = 0;
22144 dpyinfo->mouse_face_end_y = 0;
22145
22146 dpyinfo->mouse_face_past_end = 0;
22147 dpyinfo->mouse_face_window = window;
22148
22149 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
22150 charpos,
22151 0, 0, 0, &ignore,
22152 glyph->face_id, 1);
22153 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22154
22155 if (NILP (pointer))
22156 pointer = Qhand;
22157 }
22158 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22159 clear_mouse_face (dpyinfo);
22160 }
22161 define_frame_cursor1 (f, cursor, pointer);
22162 }
22163
22164
22165 /* EXPORT:
22166 Take proper action when the mouse has moved to position X, Y on
22167 frame F as regards highlighting characters that have mouse-face
22168 properties. Also de-highlighting chars where the mouse was before.
22169 X and Y can be negative or out of range. */
22170
22171 void
22172 note_mouse_highlight (f, x, y)
22173 struct frame *f;
22174 int x, y;
22175 {
22176 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22177 enum window_part part;
22178 Lisp_Object window;
22179 struct window *w;
22180 Cursor cursor = No_Cursor;
22181 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
22182 struct buffer *b;
22183
22184 /* When a menu is active, don't highlight because this looks odd. */
22185 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
22186 if (popup_activated ())
22187 return;
22188 #endif
22189
22190 if (NILP (Vmouse_highlight)
22191 || !f->glyphs_initialized_p)
22192 return;
22193
22194 dpyinfo->mouse_face_mouse_x = x;
22195 dpyinfo->mouse_face_mouse_y = y;
22196 dpyinfo->mouse_face_mouse_frame = f;
22197
22198 if (dpyinfo->mouse_face_defer)
22199 return;
22200
22201 if (gc_in_progress)
22202 {
22203 dpyinfo->mouse_face_deferred_gc = 1;
22204 return;
22205 }
22206
22207 /* Which window is that in? */
22208 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
22209
22210 /* If we were displaying active text in another window, clear that.
22211 Also clear if we move out of text area in same window. */
22212 if (! EQ (window, dpyinfo->mouse_face_window)
22213 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
22214 && !NILP (dpyinfo->mouse_face_window)))
22215 clear_mouse_face (dpyinfo);
22216
22217 /* Not on a window -> return. */
22218 if (!WINDOWP (window))
22219 return;
22220
22221 /* Reset help_echo_string. It will get recomputed below. */
22222 help_echo_string = Qnil;
22223
22224 /* Convert to window-relative pixel coordinates. */
22225 w = XWINDOW (window);
22226 frame_to_window_pixel_xy (w, &x, &y);
22227
22228 /* Handle tool-bar window differently since it doesn't display a
22229 buffer. */
22230 if (EQ (window, f->tool_bar_window))
22231 {
22232 note_tool_bar_highlight (f, x, y);
22233 return;
22234 }
22235
22236 /* Mouse is on the mode, header line or margin? */
22237 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
22238 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
22239 {
22240 note_mode_line_or_margin_highlight (window, x, y, part);
22241 return;
22242 }
22243
22244 if (part == ON_VERTICAL_BORDER)
22245 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22246 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
22247 || part == ON_SCROLL_BAR)
22248 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22249 else
22250 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22251
22252 /* Are we in a window whose display is up to date?
22253 And verify the buffer's text has not changed. */
22254 b = XBUFFER (w->buffer);
22255 if (part == ON_TEXT
22256 && EQ (w->window_end_valid, w->buffer)
22257 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
22258 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
22259 {
22260 int hpos, vpos, pos, i, dx, dy, area;
22261 struct glyph *glyph;
22262 Lisp_Object object;
22263 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
22264 Lisp_Object *overlay_vec = NULL;
22265 int noverlays;
22266 struct buffer *obuf;
22267 int obegv, ozv, same_region;
22268
22269 /* Find the glyph under X/Y. */
22270 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
22271
22272 /* Look for :pointer property on image. */
22273 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
22274 {
22275 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
22276 if (img != NULL && IMAGEP (img->spec))
22277 {
22278 Lisp_Object image_map, hotspot;
22279 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
22280 !NILP (image_map))
22281 && (hotspot = find_hot_spot (image_map,
22282 glyph->slice.x + dx,
22283 glyph->slice.y + dy),
22284 CONSP (hotspot))
22285 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22286 {
22287 Lisp_Object area_id, plist;
22288
22289 area_id = XCAR (hotspot);
22290 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22291 If so, we could look for mouse-enter, mouse-leave
22292 properties in PLIST (and do something...). */
22293 hotspot = XCDR (hotspot);
22294 if (CONSP (hotspot)
22295 && (plist = XCAR (hotspot), CONSP (plist)))
22296 {
22297 pointer = Fplist_get (plist, Qpointer);
22298 if (NILP (pointer))
22299 pointer = Qhand;
22300 help_echo_string = Fplist_get (plist, Qhelp_echo);
22301 if (!NILP (help_echo_string))
22302 {
22303 help_echo_window = window;
22304 help_echo_object = glyph->object;
22305 help_echo_pos = glyph->charpos;
22306 }
22307 }
22308 }
22309 if (NILP (pointer))
22310 pointer = Fplist_get (XCDR (img->spec), QCpointer);
22311 }
22312 }
22313
22314 /* Clear mouse face if X/Y not over text. */
22315 if (glyph == NULL
22316 || area != TEXT_AREA
22317 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
22318 {
22319 if (clear_mouse_face (dpyinfo))
22320 cursor = No_Cursor;
22321 if (NILP (pointer))
22322 {
22323 if (area != TEXT_AREA)
22324 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22325 else
22326 pointer = Vvoid_text_area_pointer;
22327 }
22328 goto set_cursor;
22329 }
22330
22331 pos = glyph->charpos;
22332 object = glyph->object;
22333 if (!STRINGP (object) && !BUFFERP (object))
22334 goto set_cursor;
22335
22336 /* If we get an out-of-range value, return now; avoid an error. */
22337 if (BUFFERP (object) && pos > BUF_Z (b))
22338 goto set_cursor;
22339
22340 /* Make the window's buffer temporarily current for
22341 overlays_at and compute_char_face. */
22342 obuf = current_buffer;
22343 current_buffer = b;
22344 obegv = BEGV;
22345 ozv = ZV;
22346 BEGV = BEG;
22347 ZV = Z;
22348
22349 /* Is this char mouse-active or does it have help-echo? */
22350 position = make_number (pos);
22351
22352 if (BUFFERP (object))
22353 {
22354 /* Put all the overlays we want in a vector in overlay_vec. */
22355 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
22356 /* Sort overlays into increasing priority order. */
22357 noverlays = sort_overlays (overlay_vec, noverlays, w);
22358 }
22359 else
22360 noverlays = 0;
22361
22362 same_region = (EQ (window, dpyinfo->mouse_face_window)
22363 && vpos >= dpyinfo->mouse_face_beg_row
22364 && vpos <= dpyinfo->mouse_face_end_row
22365 && (vpos > dpyinfo->mouse_face_beg_row
22366 || hpos >= dpyinfo->mouse_face_beg_col)
22367 && (vpos < dpyinfo->mouse_face_end_row
22368 || hpos < dpyinfo->mouse_face_end_col
22369 || dpyinfo->mouse_face_past_end));
22370
22371 if (same_region)
22372 cursor = No_Cursor;
22373
22374 /* Check mouse-face highlighting. */
22375 if (! same_region
22376 /* If there exists an overlay with mouse-face overlapping
22377 the one we are currently highlighting, we have to
22378 check if we enter the overlapping overlay, and then
22379 highlight only that. */
22380 || (OVERLAYP (dpyinfo->mouse_face_overlay)
22381 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
22382 {
22383 /* Find the highest priority overlay that has a mouse-face
22384 property. */
22385 overlay = Qnil;
22386 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
22387 {
22388 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
22389 if (!NILP (mouse_face))
22390 overlay = overlay_vec[i];
22391 }
22392
22393 /* If we're actually highlighting the same overlay as
22394 before, there's no need to do that again. */
22395 if (!NILP (overlay)
22396 && EQ (overlay, dpyinfo->mouse_face_overlay))
22397 goto check_help_echo;
22398
22399 dpyinfo->mouse_face_overlay = overlay;
22400
22401 /* Clear the display of the old active region, if any. */
22402 if (clear_mouse_face (dpyinfo))
22403 cursor = No_Cursor;
22404
22405 /* If no overlay applies, get a text property. */
22406 if (NILP (overlay))
22407 mouse_face = Fget_text_property (position, Qmouse_face, object);
22408
22409 /* Handle the overlay case. */
22410 if (!NILP (overlay))
22411 {
22412 /* Find the range of text around this char that
22413 should be active. */
22414 Lisp_Object before, after;
22415 int ignore;
22416
22417 before = Foverlay_start (overlay);
22418 after = Foverlay_end (overlay);
22419 /* Record this as the current active region. */
22420 fast_find_position (w, XFASTINT (before),
22421 &dpyinfo->mouse_face_beg_col,
22422 &dpyinfo->mouse_face_beg_row,
22423 &dpyinfo->mouse_face_beg_x,
22424 &dpyinfo->mouse_face_beg_y, Qnil);
22425
22426 dpyinfo->mouse_face_past_end
22427 = !fast_find_position (w, XFASTINT (after),
22428 &dpyinfo->mouse_face_end_col,
22429 &dpyinfo->mouse_face_end_row,
22430 &dpyinfo->mouse_face_end_x,
22431 &dpyinfo->mouse_face_end_y, Qnil);
22432 dpyinfo->mouse_face_window = window;
22433
22434 dpyinfo->mouse_face_face_id
22435 = face_at_buffer_position (w, pos, 0, 0,
22436 &ignore, pos + 1,
22437 !dpyinfo->mouse_face_hidden);
22438
22439 /* Display it as active. */
22440 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22441 cursor = No_Cursor;
22442 }
22443 /* Handle the text property case. */
22444 else if (!NILP (mouse_face) && BUFFERP (object))
22445 {
22446 /* Find the range of text around this char that
22447 should be active. */
22448 Lisp_Object before, after, beginning, end;
22449 int ignore;
22450
22451 beginning = Fmarker_position (w->start);
22452 end = make_number (BUF_Z (XBUFFER (object))
22453 - XFASTINT (w->window_end_pos));
22454 before
22455 = Fprevious_single_property_change (make_number (pos + 1),
22456 Qmouse_face,
22457 object, beginning);
22458 after
22459 = Fnext_single_property_change (position, Qmouse_face,
22460 object, end);
22461
22462 /* Record this as the current active region. */
22463 fast_find_position (w, XFASTINT (before),
22464 &dpyinfo->mouse_face_beg_col,
22465 &dpyinfo->mouse_face_beg_row,
22466 &dpyinfo->mouse_face_beg_x,
22467 &dpyinfo->mouse_face_beg_y, Qnil);
22468 dpyinfo->mouse_face_past_end
22469 = !fast_find_position (w, XFASTINT (after),
22470 &dpyinfo->mouse_face_end_col,
22471 &dpyinfo->mouse_face_end_row,
22472 &dpyinfo->mouse_face_end_x,
22473 &dpyinfo->mouse_face_end_y, Qnil);
22474 dpyinfo->mouse_face_window = window;
22475
22476 if (BUFFERP (object))
22477 dpyinfo->mouse_face_face_id
22478 = face_at_buffer_position (w, pos, 0, 0,
22479 &ignore, pos + 1,
22480 !dpyinfo->mouse_face_hidden);
22481
22482 /* Display it as active. */
22483 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22484 cursor = No_Cursor;
22485 }
22486 else if (!NILP (mouse_face) && STRINGP (object))
22487 {
22488 Lisp_Object b, e;
22489 int ignore;
22490
22491 b = Fprevious_single_property_change (make_number (pos + 1),
22492 Qmouse_face,
22493 object, Qnil);
22494 e = Fnext_single_property_change (position, Qmouse_face,
22495 object, Qnil);
22496 if (NILP (b))
22497 b = make_number (0);
22498 if (NILP (e))
22499 e = make_number (SCHARS (object) - 1);
22500
22501 fast_find_string_pos (w, XINT (b), object,
22502 &dpyinfo->mouse_face_beg_col,
22503 &dpyinfo->mouse_face_beg_row,
22504 &dpyinfo->mouse_face_beg_x,
22505 &dpyinfo->mouse_face_beg_y, 0);
22506 fast_find_string_pos (w, XINT (e), object,
22507 &dpyinfo->mouse_face_end_col,
22508 &dpyinfo->mouse_face_end_row,
22509 &dpyinfo->mouse_face_end_x,
22510 &dpyinfo->mouse_face_end_y, 1);
22511 dpyinfo->mouse_face_past_end = 0;
22512 dpyinfo->mouse_face_window = window;
22513 dpyinfo->mouse_face_face_id
22514 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
22515 glyph->face_id, 1);
22516 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22517 cursor = No_Cursor;
22518 }
22519 else if (STRINGP (object) && NILP (mouse_face))
22520 {
22521 /* A string which doesn't have mouse-face, but
22522 the text ``under'' it might have. */
22523 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
22524 int start = MATRIX_ROW_START_CHARPOS (r);
22525
22526 pos = string_buffer_position (w, object, start);
22527 if (pos > 0)
22528 mouse_face = get_char_property_and_overlay (make_number (pos),
22529 Qmouse_face,
22530 w->buffer,
22531 &overlay);
22532 if (!NILP (mouse_face) && !NILP (overlay))
22533 {
22534 Lisp_Object before = Foverlay_start (overlay);
22535 Lisp_Object after = Foverlay_end (overlay);
22536 int ignore;
22537
22538 /* Note that we might not be able to find position
22539 BEFORE in the glyph matrix if the overlay is
22540 entirely covered by a `display' property. In
22541 this case, we overshoot. So let's stop in
22542 the glyph matrix before glyphs for OBJECT. */
22543 fast_find_position (w, XFASTINT (before),
22544 &dpyinfo->mouse_face_beg_col,
22545 &dpyinfo->mouse_face_beg_row,
22546 &dpyinfo->mouse_face_beg_x,
22547 &dpyinfo->mouse_face_beg_y,
22548 object);
22549
22550 dpyinfo->mouse_face_past_end
22551 = !fast_find_position (w, XFASTINT (after),
22552 &dpyinfo->mouse_face_end_col,
22553 &dpyinfo->mouse_face_end_row,
22554 &dpyinfo->mouse_face_end_x,
22555 &dpyinfo->mouse_face_end_y,
22556 Qnil);
22557 dpyinfo->mouse_face_window = window;
22558 dpyinfo->mouse_face_face_id
22559 = face_at_buffer_position (w, pos, 0, 0,
22560 &ignore, pos + 1,
22561 !dpyinfo->mouse_face_hidden);
22562
22563 /* Display it as active. */
22564 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22565 cursor = No_Cursor;
22566 }
22567 }
22568 }
22569
22570 check_help_echo:
22571
22572 /* Look for a `help-echo' property. */
22573 if (NILP (help_echo_string)) {
22574 Lisp_Object help, overlay;
22575
22576 /* Check overlays first. */
22577 help = overlay = Qnil;
22578 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
22579 {
22580 overlay = overlay_vec[i];
22581 help = Foverlay_get (overlay, Qhelp_echo);
22582 }
22583
22584 if (!NILP (help))
22585 {
22586 help_echo_string = help;
22587 help_echo_window = window;
22588 help_echo_object = overlay;
22589 help_echo_pos = pos;
22590 }
22591 else
22592 {
22593 Lisp_Object object = glyph->object;
22594 int charpos = glyph->charpos;
22595
22596 /* Try text properties. */
22597 if (STRINGP (object)
22598 && charpos >= 0
22599 && charpos < SCHARS (object))
22600 {
22601 help = Fget_text_property (make_number (charpos),
22602 Qhelp_echo, object);
22603 if (NILP (help))
22604 {
22605 /* If the string itself doesn't specify a help-echo,
22606 see if the buffer text ``under'' it does. */
22607 struct glyph_row *r
22608 = MATRIX_ROW (w->current_matrix, vpos);
22609 int start = MATRIX_ROW_START_CHARPOS (r);
22610 int pos = string_buffer_position (w, object, start);
22611 if (pos > 0)
22612 {
22613 help = Fget_char_property (make_number (pos),
22614 Qhelp_echo, w->buffer);
22615 if (!NILP (help))
22616 {
22617 charpos = pos;
22618 object = w->buffer;
22619 }
22620 }
22621 }
22622 }
22623 else if (BUFFERP (object)
22624 && charpos >= BEGV
22625 && charpos < ZV)
22626 help = Fget_text_property (make_number (charpos), Qhelp_echo,
22627 object);
22628
22629 if (!NILP (help))
22630 {
22631 help_echo_string = help;
22632 help_echo_window = window;
22633 help_echo_object = object;
22634 help_echo_pos = charpos;
22635 }
22636 }
22637 }
22638
22639 /* Look for a `pointer' property. */
22640 if (NILP (pointer))
22641 {
22642 /* Check overlays first. */
22643 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
22644 pointer = Foverlay_get (overlay_vec[i], Qpointer);
22645
22646 if (NILP (pointer))
22647 {
22648 Lisp_Object object = glyph->object;
22649 int charpos = glyph->charpos;
22650
22651 /* Try text properties. */
22652 if (STRINGP (object)
22653 && charpos >= 0
22654 && charpos < SCHARS (object))
22655 {
22656 pointer = Fget_text_property (make_number (charpos),
22657 Qpointer, object);
22658 if (NILP (pointer))
22659 {
22660 /* If the string itself doesn't specify a pointer,
22661 see if the buffer text ``under'' it does. */
22662 struct glyph_row *r
22663 = MATRIX_ROW (w->current_matrix, vpos);
22664 int start = MATRIX_ROW_START_CHARPOS (r);
22665 int pos = string_buffer_position (w, object, start);
22666 if (pos > 0)
22667 pointer = Fget_char_property (make_number (pos),
22668 Qpointer, w->buffer);
22669 }
22670 }
22671 else if (BUFFERP (object)
22672 && charpos >= BEGV
22673 && charpos < ZV)
22674 pointer = Fget_text_property (make_number (charpos),
22675 Qpointer, object);
22676 }
22677 }
22678
22679 BEGV = obegv;
22680 ZV = ozv;
22681 current_buffer = obuf;
22682 }
22683
22684 set_cursor:
22685
22686 define_frame_cursor1 (f, cursor, pointer);
22687 }
22688
22689
22690 /* EXPORT for RIF:
22691 Clear any mouse-face on window W. This function is part of the
22692 redisplay interface, and is called from try_window_id and similar
22693 functions to ensure the mouse-highlight is off. */
22694
22695 void
22696 x_clear_window_mouse_face (w)
22697 struct window *w;
22698 {
22699 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
22700 Lisp_Object window;
22701
22702 BLOCK_INPUT;
22703 XSETWINDOW (window, w);
22704 if (EQ (window, dpyinfo->mouse_face_window))
22705 clear_mouse_face (dpyinfo);
22706 UNBLOCK_INPUT;
22707 }
22708
22709
22710 /* EXPORT:
22711 Just discard the mouse face information for frame F, if any.
22712 This is used when the size of F is changed. */
22713
22714 void
22715 cancel_mouse_face (f)
22716 struct frame *f;
22717 {
22718 Lisp_Object window;
22719 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22720
22721 window = dpyinfo->mouse_face_window;
22722 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
22723 {
22724 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
22725 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
22726 dpyinfo->mouse_face_window = Qnil;
22727 }
22728 }
22729
22730
22731 #endif /* HAVE_WINDOW_SYSTEM */
22732
22733 \f
22734 /***********************************************************************
22735 Exposure Events
22736 ***********************************************************************/
22737
22738 #ifdef HAVE_WINDOW_SYSTEM
22739
22740 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
22741 which intersects rectangle R. R is in window-relative coordinates. */
22742
22743 static void
22744 expose_area (w, row, r, area)
22745 struct window *w;
22746 struct glyph_row *row;
22747 XRectangle *r;
22748 enum glyph_row_area area;
22749 {
22750 struct glyph *first = row->glyphs[area];
22751 struct glyph *end = row->glyphs[area] + row->used[area];
22752 struct glyph *last;
22753 int first_x, start_x, x;
22754
22755 if (area == TEXT_AREA && row->fill_line_p)
22756 /* If row extends face to end of line write the whole line. */
22757 draw_glyphs (w, 0, row, area,
22758 0, row->used[area],
22759 DRAW_NORMAL_TEXT, 0);
22760 else
22761 {
22762 /* Set START_X to the window-relative start position for drawing glyphs of
22763 AREA. The first glyph of the text area can be partially visible.
22764 The first glyphs of other areas cannot. */
22765 start_x = window_box_left_offset (w, area);
22766 x = start_x;
22767 if (area == TEXT_AREA)
22768 x += row->x;
22769
22770 /* Find the first glyph that must be redrawn. */
22771 while (first < end
22772 && x + first->pixel_width < r->x)
22773 {
22774 x += first->pixel_width;
22775 ++first;
22776 }
22777
22778 /* Find the last one. */
22779 last = first;
22780 first_x = x;
22781 while (last < end
22782 && x < r->x + r->width)
22783 {
22784 x += last->pixel_width;
22785 ++last;
22786 }
22787
22788 /* Repaint. */
22789 if (last > first)
22790 draw_glyphs (w, first_x - start_x, row, area,
22791 first - row->glyphs[area], last - row->glyphs[area],
22792 DRAW_NORMAL_TEXT, 0);
22793 }
22794 }
22795
22796
22797 /* Redraw the parts of the glyph row ROW on window W intersecting
22798 rectangle R. R is in window-relative coordinates. Value is
22799 non-zero if mouse-face was overwritten. */
22800
22801 static int
22802 expose_line (w, row, r)
22803 struct window *w;
22804 struct glyph_row *row;
22805 XRectangle *r;
22806 {
22807 xassert (row->enabled_p);
22808
22809 if (row->mode_line_p || w->pseudo_window_p)
22810 draw_glyphs (w, 0, row, TEXT_AREA,
22811 0, row->used[TEXT_AREA],
22812 DRAW_NORMAL_TEXT, 0);
22813 else
22814 {
22815 if (row->used[LEFT_MARGIN_AREA])
22816 expose_area (w, row, r, LEFT_MARGIN_AREA);
22817 if (row->used[TEXT_AREA])
22818 expose_area (w, row, r, TEXT_AREA);
22819 if (row->used[RIGHT_MARGIN_AREA])
22820 expose_area (w, row, r, RIGHT_MARGIN_AREA);
22821 draw_row_fringe_bitmaps (w, row);
22822 }
22823
22824 return row->mouse_face_p;
22825 }
22826
22827
22828 /* Redraw those parts of glyphs rows during expose event handling that
22829 overlap other rows. Redrawing of an exposed line writes over parts
22830 of lines overlapping that exposed line; this function fixes that.
22831
22832 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
22833 row in W's current matrix that is exposed and overlaps other rows.
22834 LAST_OVERLAPPING_ROW is the last such row. */
22835
22836 static void
22837 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
22838 struct window *w;
22839 struct glyph_row *first_overlapping_row;
22840 struct glyph_row *last_overlapping_row;
22841 {
22842 struct glyph_row *row;
22843
22844 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
22845 if (row->overlapping_p)
22846 {
22847 xassert (row->enabled_p && !row->mode_line_p);
22848
22849 if (row->used[LEFT_MARGIN_AREA])
22850 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
22851
22852 if (row->used[TEXT_AREA])
22853 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
22854
22855 if (row->used[RIGHT_MARGIN_AREA])
22856 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
22857 }
22858 }
22859
22860
22861 /* Return non-zero if W's cursor intersects rectangle R. */
22862
22863 static int
22864 phys_cursor_in_rect_p (w, r)
22865 struct window *w;
22866 XRectangle *r;
22867 {
22868 XRectangle cr, result;
22869 struct glyph *cursor_glyph;
22870
22871 cursor_glyph = get_phys_cursor_glyph (w);
22872 if (cursor_glyph)
22873 {
22874 /* r is relative to W's box, but w->phys_cursor.x is relative
22875 to left edge of W's TEXT area. Adjust it. */
22876 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
22877 cr.y = w->phys_cursor.y;
22878 cr.width = cursor_glyph->pixel_width;
22879 cr.height = w->phys_cursor_height;
22880 /* ++KFS: W32 version used W32-specific IntersectRect here, but
22881 I assume the effect is the same -- and this is portable. */
22882 return x_intersect_rectangles (&cr, r, &result);
22883 }
22884 else
22885 return 0;
22886 }
22887
22888
22889 /* EXPORT:
22890 Draw a vertical window border to the right of window W if W doesn't
22891 have vertical scroll bars. */
22892
22893 void
22894 x_draw_vertical_border (w)
22895 struct window *w;
22896 {
22897 /* We could do better, if we knew what type of scroll-bar the adjacent
22898 windows (on either side) have... But we don't :-(
22899 However, I think this works ok. ++KFS 2003-04-25 */
22900
22901 /* Redraw borders between horizontally adjacent windows. Don't
22902 do it for frames with vertical scroll bars because either the
22903 right scroll bar of a window, or the left scroll bar of its
22904 neighbor will suffice as a border. */
22905 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
22906 return;
22907
22908 if (!WINDOW_RIGHTMOST_P (w)
22909 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
22910 {
22911 int x0, x1, y0, y1;
22912
22913 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22914 y1 -= 1;
22915
22916 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
22917 x1 -= 1;
22918
22919 rif->draw_vertical_window_border (w, x1, y0, y1);
22920 }
22921 else if (!WINDOW_LEFTMOST_P (w)
22922 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
22923 {
22924 int x0, x1, y0, y1;
22925
22926 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22927 y1 -= 1;
22928
22929 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
22930 x0 -= 1;
22931
22932 rif->draw_vertical_window_border (w, x0, y0, y1);
22933 }
22934 }
22935
22936
22937 /* Redraw the part of window W intersection rectangle FR. Pixel
22938 coordinates in FR are frame-relative. Call this function with
22939 input blocked. Value is non-zero if the exposure overwrites
22940 mouse-face. */
22941
22942 static int
22943 expose_window (w, fr)
22944 struct window *w;
22945 XRectangle *fr;
22946 {
22947 struct frame *f = XFRAME (w->frame);
22948 XRectangle wr, r;
22949 int mouse_face_overwritten_p = 0;
22950
22951 /* If window is not yet fully initialized, do nothing. This can
22952 happen when toolkit scroll bars are used and a window is split.
22953 Reconfiguring the scroll bar will generate an expose for a newly
22954 created window. */
22955 if (w->current_matrix == NULL)
22956 return 0;
22957
22958 /* When we're currently updating the window, display and current
22959 matrix usually don't agree. Arrange for a thorough display
22960 later. */
22961 if (w == updated_window)
22962 {
22963 SET_FRAME_GARBAGED (f);
22964 return 0;
22965 }
22966
22967 /* Frame-relative pixel rectangle of W. */
22968 wr.x = WINDOW_LEFT_EDGE_X (w);
22969 wr.y = WINDOW_TOP_EDGE_Y (w);
22970 wr.width = WINDOW_TOTAL_WIDTH (w);
22971 wr.height = WINDOW_TOTAL_HEIGHT (w);
22972
22973 if (x_intersect_rectangles (fr, &wr, &r))
22974 {
22975 int yb = window_text_bottom_y (w);
22976 struct glyph_row *row;
22977 int cursor_cleared_p;
22978 struct glyph_row *first_overlapping_row, *last_overlapping_row;
22979
22980 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
22981 r.x, r.y, r.width, r.height));
22982
22983 /* Convert to window coordinates. */
22984 r.x -= WINDOW_LEFT_EDGE_X (w);
22985 r.y -= WINDOW_TOP_EDGE_Y (w);
22986
22987 /* Turn off the cursor. */
22988 if (!w->pseudo_window_p
22989 && phys_cursor_in_rect_p (w, &r))
22990 {
22991 x_clear_cursor (w);
22992 cursor_cleared_p = 1;
22993 }
22994 else
22995 cursor_cleared_p = 0;
22996
22997 /* Update lines intersecting rectangle R. */
22998 first_overlapping_row = last_overlapping_row = NULL;
22999 for (row = w->current_matrix->rows;
23000 row->enabled_p;
23001 ++row)
23002 {
23003 int y0 = row->y;
23004 int y1 = MATRIX_ROW_BOTTOM_Y (row);
23005
23006 if ((y0 >= r.y && y0 < r.y + r.height)
23007 || (y1 > r.y && y1 < r.y + r.height)
23008 || (r.y >= y0 && r.y < y1)
23009 || (r.y + r.height > y0 && r.y + r.height < y1))
23010 {
23011 /* A header line may be overlapping, but there is no need
23012 to fix overlapping areas for them. KFS 2005-02-12 */
23013 if (row->overlapping_p && !row->mode_line_p)
23014 {
23015 if (first_overlapping_row == NULL)
23016 first_overlapping_row = row;
23017 last_overlapping_row = row;
23018 }
23019
23020 if (expose_line (w, row, &r))
23021 mouse_face_overwritten_p = 1;
23022 }
23023
23024 if (y1 >= yb)
23025 break;
23026 }
23027
23028 /* Display the mode line if there is one. */
23029 if (WINDOW_WANTS_MODELINE_P (w)
23030 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
23031 row->enabled_p)
23032 && row->y < r.y + r.height)
23033 {
23034 if (expose_line (w, row, &r))
23035 mouse_face_overwritten_p = 1;
23036 }
23037
23038 if (!w->pseudo_window_p)
23039 {
23040 /* Fix the display of overlapping rows. */
23041 if (first_overlapping_row)
23042 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
23043
23044 /* Draw border between windows. */
23045 x_draw_vertical_border (w);
23046
23047 /* Turn the cursor on again. */
23048 if (cursor_cleared_p)
23049 update_window_cursor (w, 1);
23050 }
23051 }
23052
23053 return mouse_face_overwritten_p;
23054 }
23055
23056
23057
23058 /* Redraw (parts) of all windows in the window tree rooted at W that
23059 intersect R. R contains frame pixel coordinates. Value is
23060 non-zero if the exposure overwrites mouse-face. */
23061
23062 static int
23063 expose_window_tree (w, r)
23064 struct window *w;
23065 XRectangle *r;
23066 {
23067 struct frame *f = XFRAME (w->frame);
23068 int mouse_face_overwritten_p = 0;
23069
23070 while (w && !FRAME_GARBAGED_P (f))
23071 {
23072 if (!NILP (w->hchild))
23073 mouse_face_overwritten_p
23074 |= expose_window_tree (XWINDOW (w->hchild), r);
23075 else if (!NILP (w->vchild))
23076 mouse_face_overwritten_p
23077 |= expose_window_tree (XWINDOW (w->vchild), r);
23078 else
23079 mouse_face_overwritten_p |= expose_window (w, r);
23080
23081 w = NILP (w->next) ? NULL : XWINDOW (w->next);
23082 }
23083
23084 return mouse_face_overwritten_p;
23085 }
23086
23087
23088 /* EXPORT:
23089 Redisplay an exposed area of frame F. X and Y are the upper-left
23090 corner of the exposed rectangle. W and H are width and height of
23091 the exposed area. All are pixel values. W or H zero means redraw
23092 the entire frame. */
23093
23094 void
23095 expose_frame (f, x, y, w, h)
23096 struct frame *f;
23097 int x, y, w, h;
23098 {
23099 XRectangle r;
23100 int mouse_face_overwritten_p = 0;
23101
23102 TRACE ((stderr, "expose_frame "));
23103
23104 /* No need to redraw if frame will be redrawn soon. */
23105 if (FRAME_GARBAGED_P (f))
23106 {
23107 TRACE ((stderr, " garbaged\n"));
23108 return;
23109 }
23110
23111 /* If basic faces haven't been realized yet, there is no point in
23112 trying to redraw anything. This can happen when we get an expose
23113 event while Emacs is starting, e.g. by moving another window. */
23114 if (FRAME_FACE_CACHE (f) == NULL
23115 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
23116 {
23117 TRACE ((stderr, " no faces\n"));
23118 return;
23119 }
23120
23121 if (w == 0 || h == 0)
23122 {
23123 r.x = r.y = 0;
23124 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
23125 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
23126 }
23127 else
23128 {
23129 r.x = x;
23130 r.y = y;
23131 r.width = w;
23132 r.height = h;
23133 }
23134
23135 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
23136 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
23137
23138 if (WINDOWP (f->tool_bar_window))
23139 mouse_face_overwritten_p
23140 |= expose_window (XWINDOW (f->tool_bar_window), &r);
23141
23142 #ifdef HAVE_X_WINDOWS
23143 #ifndef MSDOS
23144 #ifndef USE_X_TOOLKIT
23145 if (WINDOWP (f->menu_bar_window))
23146 mouse_face_overwritten_p
23147 |= expose_window (XWINDOW (f->menu_bar_window), &r);
23148 #endif /* not USE_X_TOOLKIT */
23149 #endif
23150 #endif
23151
23152 /* Some window managers support a focus-follows-mouse style with
23153 delayed raising of frames. Imagine a partially obscured frame,
23154 and moving the mouse into partially obscured mouse-face on that
23155 frame. The visible part of the mouse-face will be highlighted,
23156 then the WM raises the obscured frame. With at least one WM, KDE
23157 2.1, Emacs is not getting any event for the raising of the frame
23158 (even tried with SubstructureRedirectMask), only Expose events.
23159 These expose events will draw text normally, i.e. not
23160 highlighted. Which means we must redo the highlight here.
23161 Subsume it under ``we love X''. --gerd 2001-08-15 */
23162 /* Included in Windows version because Windows most likely does not
23163 do the right thing if any third party tool offers
23164 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
23165 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
23166 {
23167 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23168 if (f == dpyinfo->mouse_face_mouse_frame)
23169 {
23170 int x = dpyinfo->mouse_face_mouse_x;
23171 int y = dpyinfo->mouse_face_mouse_y;
23172 clear_mouse_face (dpyinfo);
23173 note_mouse_highlight (f, x, y);
23174 }
23175 }
23176 }
23177
23178
23179 /* EXPORT:
23180 Determine the intersection of two rectangles R1 and R2. Return
23181 the intersection in *RESULT. Value is non-zero if RESULT is not
23182 empty. */
23183
23184 int
23185 x_intersect_rectangles (r1, r2, result)
23186 XRectangle *r1, *r2, *result;
23187 {
23188 XRectangle *left, *right;
23189 XRectangle *upper, *lower;
23190 int intersection_p = 0;
23191
23192 /* Rearrange so that R1 is the left-most rectangle. */
23193 if (r1->x < r2->x)
23194 left = r1, right = r2;
23195 else
23196 left = r2, right = r1;
23197
23198 /* X0 of the intersection is right.x0, if this is inside R1,
23199 otherwise there is no intersection. */
23200 if (right->x <= left->x + left->width)
23201 {
23202 result->x = right->x;
23203
23204 /* The right end of the intersection is the minimum of the
23205 the right ends of left and right. */
23206 result->width = (min (left->x + left->width, right->x + right->width)
23207 - result->x);
23208
23209 /* Same game for Y. */
23210 if (r1->y < r2->y)
23211 upper = r1, lower = r2;
23212 else
23213 upper = r2, lower = r1;
23214
23215 /* The upper end of the intersection is lower.y0, if this is inside
23216 of upper. Otherwise, there is no intersection. */
23217 if (lower->y <= upper->y + upper->height)
23218 {
23219 result->y = lower->y;
23220
23221 /* The lower end of the intersection is the minimum of the lower
23222 ends of upper and lower. */
23223 result->height = (min (lower->y + lower->height,
23224 upper->y + upper->height)
23225 - result->y);
23226 intersection_p = 1;
23227 }
23228 }
23229
23230 return intersection_p;
23231 }
23232
23233 #endif /* HAVE_WINDOW_SYSTEM */
23234
23235 \f
23236 /***********************************************************************
23237 Initialization
23238 ***********************************************************************/
23239
23240 void
23241 syms_of_xdisp ()
23242 {
23243 Vwith_echo_area_save_vector = Qnil;
23244 staticpro (&Vwith_echo_area_save_vector);
23245
23246 Vmessage_stack = Qnil;
23247 staticpro (&Vmessage_stack);
23248
23249 Qinhibit_redisplay = intern ("inhibit-redisplay");
23250 staticpro (&Qinhibit_redisplay);
23251
23252 message_dolog_marker1 = Fmake_marker ();
23253 staticpro (&message_dolog_marker1);
23254 message_dolog_marker2 = Fmake_marker ();
23255 staticpro (&message_dolog_marker2);
23256 message_dolog_marker3 = Fmake_marker ();
23257 staticpro (&message_dolog_marker3);
23258
23259 #if GLYPH_DEBUG
23260 defsubr (&Sdump_frame_glyph_matrix);
23261 defsubr (&Sdump_glyph_matrix);
23262 defsubr (&Sdump_glyph_row);
23263 defsubr (&Sdump_tool_bar_row);
23264 defsubr (&Strace_redisplay);
23265 defsubr (&Strace_to_stderr);
23266 #endif
23267 #ifdef HAVE_WINDOW_SYSTEM
23268 defsubr (&Stool_bar_lines_needed);
23269 defsubr (&Slookup_image_map);
23270 #endif
23271 defsubr (&Sformat_mode_line);
23272
23273 staticpro (&Qmenu_bar_update_hook);
23274 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
23275
23276 staticpro (&Qoverriding_terminal_local_map);
23277 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
23278
23279 staticpro (&Qoverriding_local_map);
23280 Qoverriding_local_map = intern ("overriding-local-map");
23281
23282 staticpro (&Qwindow_scroll_functions);
23283 Qwindow_scroll_functions = intern ("window-scroll-functions");
23284
23285 staticpro (&Qredisplay_end_trigger_functions);
23286 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
23287
23288 staticpro (&Qinhibit_point_motion_hooks);
23289 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
23290
23291 QCdata = intern (":data");
23292 staticpro (&QCdata);
23293 Qdisplay = intern ("display");
23294 staticpro (&Qdisplay);
23295 Qspace_width = intern ("space-width");
23296 staticpro (&Qspace_width);
23297 Qraise = intern ("raise");
23298 staticpro (&Qraise);
23299 Qslice = intern ("slice");
23300 staticpro (&Qslice);
23301 Qspace = intern ("space");
23302 staticpro (&Qspace);
23303 Qmargin = intern ("margin");
23304 staticpro (&Qmargin);
23305 Qpointer = intern ("pointer");
23306 staticpro (&Qpointer);
23307 Qleft_margin = intern ("left-margin");
23308 staticpro (&Qleft_margin);
23309 Qright_margin = intern ("right-margin");
23310 staticpro (&Qright_margin);
23311 Qcenter = intern ("center");
23312 staticpro (&Qcenter);
23313 Qline_height = intern ("line-height");
23314 staticpro (&Qline_height);
23315 QCalign_to = intern (":align-to");
23316 staticpro (&QCalign_to);
23317 QCrelative_width = intern (":relative-width");
23318 staticpro (&QCrelative_width);
23319 QCrelative_height = intern (":relative-height");
23320 staticpro (&QCrelative_height);
23321 QCeval = intern (":eval");
23322 staticpro (&QCeval);
23323 QCpropertize = intern (":propertize");
23324 staticpro (&QCpropertize);
23325 QCfile = intern (":file");
23326 staticpro (&QCfile);
23327 Qfontified = intern ("fontified");
23328 staticpro (&Qfontified);
23329 Qfontification_functions = intern ("fontification-functions");
23330 staticpro (&Qfontification_functions);
23331 Qtrailing_whitespace = intern ("trailing-whitespace");
23332 staticpro (&Qtrailing_whitespace);
23333 Qescape_glyph = intern ("escape-glyph");
23334 staticpro (&Qescape_glyph);
23335 Qnobreak_space = intern ("nobreak-space");
23336 staticpro (&Qnobreak_space);
23337 Qimage = intern ("image");
23338 staticpro (&Qimage);
23339 QCmap = intern (":map");
23340 staticpro (&QCmap);
23341 QCpointer = intern (":pointer");
23342 staticpro (&QCpointer);
23343 Qrect = intern ("rect");
23344 staticpro (&Qrect);
23345 Qcircle = intern ("circle");
23346 staticpro (&Qcircle);
23347 Qpoly = intern ("poly");
23348 staticpro (&Qpoly);
23349 Qmessage_truncate_lines = intern ("message-truncate-lines");
23350 staticpro (&Qmessage_truncate_lines);
23351 Qgrow_only = intern ("grow-only");
23352 staticpro (&Qgrow_only);
23353 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
23354 staticpro (&Qinhibit_menubar_update);
23355 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
23356 staticpro (&Qinhibit_eval_during_redisplay);
23357 Qposition = intern ("position");
23358 staticpro (&Qposition);
23359 Qbuffer_position = intern ("buffer-position");
23360 staticpro (&Qbuffer_position);
23361 Qobject = intern ("object");
23362 staticpro (&Qobject);
23363 Qbar = intern ("bar");
23364 staticpro (&Qbar);
23365 Qhbar = intern ("hbar");
23366 staticpro (&Qhbar);
23367 Qbox = intern ("box");
23368 staticpro (&Qbox);
23369 Qhollow = intern ("hollow");
23370 staticpro (&Qhollow);
23371 Qhand = intern ("hand");
23372 staticpro (&Qhand);
23373 Qarrow = intern ("arrow");
23374 staticpro (&Qarrow);
23375 Qtext = intern ("text");
23376 staticpro (&Qtext);
23377 Qrisky_local_variable = intern ("risky-local-variable");
23378 staticpro (&Qrisky_local_variable);
23379 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
23380 staticpro (&Qinhibit_free_realized_faces);
23381
23382 list_of_error = Fcons (Fcons (intern ("error"),
23383 Fcons (intern ("void-variable"), Qnil)),
23384 Qnil);
23385 staticpro (&list_of_error);
23386
23387 Qlast_arrow_position = intern ("last-arrow-position");
23388 staticpro (&Qlast_arrow_position);
23389 Qlast_arrow_string = intern ("last-arrow-string");
23390 staticpro (&Qlast_arrow_string);
23391
23392 Qoverlay_arrow_string = intern ("overlay-arrow-string");
23393 staticpro (&Qoverlay_arrow_string);
23394 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
23395 staticpro (&Qoverlay_arrow_bitmap);
23396
23397 echo_buffer[0] = echo_buffer[1] = Qnil;
23398 staticpro (&echo_buffer[0]);
23399 staticpro (&echo_buffer[1]);
23400
23401 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
23402 staticpro (&echo_area_buffer[0]);
23403 staticpro (&echo_area_buffer[1]);
23404
23405 Vmessages_buffer_name = build_string ("*Messages*");
23406 staticpro (&Vmessages_buffer_name);
23407
23408 mode_line_proptrans_alist = Qnil;
23409 staticpro (&mode_line_proptrans_alist);
23410 mode_line_string_list = Qnil;
23411 staticpro (&mode_line_string_list);
23412 mode_line_string_face = Qnil;
23413 staticpro (&mode_line_string_face);
23414 mode_line_string_face_prop = Qnil;
23415 staticpro (&mode_line_string_face_prop);
23416 Vmode_line_unwind_vector = Qnil;
23417 staticpro (&Vmode_line_unwind_vector);
23418
23419 help_echo_string = Qnil;
23420 staticpro (&help_echo_string);
23421 help_echo_object = Qnil;
23422 staticpro (&help_echo_object);
23423 help_echo_window = Qnil;
23424 staticpro (&help_echo_window);
23425 previous_help_echo_string = Qnil;
23426 staticpro (&previous_help_echo_string);
23427 help_echo_pos = -1;
23428
23429 #ifdef HAVE_WINDOW_SYSTEM
23430 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
23431 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
23432 For example, if a block cursor is over a tab, it will be drawn as
23433 wide as that tab on the display. */);
23434 x_stretch_cursor_p = 0;
23435 #endif
23436
23437 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
23438 doc: /* *Non-nil means highlight trailing whitespace.
23439 The face used for trailing whitespace is `trailing-whitespace'. */);
23440 Vshow_trailing_whitespace = Qnil;
23441
23442 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
23443 doc: /* *Control highlighting of nobreak space and soft hyphen.
23444 A value of t means highlight the character itself (for nobreak space,
23445 use face `nobreak-space').
23446 A value of nil means no highlighting.
23447 Other values mean display the escape glyph followed by an ordinary
23448 space or ordinary hyphen. */);
23449 Vnobreak_char_display = Qt;
23450
23451 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
23452 doc: /* *The pointer shape to show in void text areas.
23453 A value of nil means to show the text pointer. Other options are `arrow',
23454 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
23455 Vvoid_text_area_pointer = Qarrow;
23456
23457 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
23458 doc: /* Non-nil means don't actually do any redisplay.
23459 This is used for internal purposes. */);
23460 Vinhibit_redisplay = Qnil;
23461
23462 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
23463 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
23464 Vglobal_mode_string = Qnil;
23465
23466 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
23467 doc: /* Marker for where to display an arrow on top of the buffer text.
23468 This must be the beginning of a line in order to work.
23469 See also `overlay-arrow-string'. */);
23470 Voverlay_arrow_position = Qnil;
23471
23472 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
23473 doc: /* String to display as an arrow in non-window frames.
23474 See also `overlay-arrow-position'. */);
23475 Voverlay_arrow_string = build_string ("=>");
23476
23477 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
23478 doc: /* List of variables (symbols) which hold markers for overlay arrows.
23479 The symbols on this list are examined during redisplay to determine
23480 where to display overlay arrows. */);
23481 Voverlay_arrow_variable_list
23482 = Fcons (intern ("overlay-arrow-position"), Qnil);
23483
23484 DEFVAR_INT ("scroll-step", &scroll_step,
23485 doc: /* *The number of lines to try scrolling a window by when point moves out.
23486 If that fails to bring point back on frame, point is centered instead.
23487 If this is zero, point is always centered after it moves off frame.
23488 If you want scrolling to always be a line at a time, you should set
23489 `scroll-conservatively' to a large value rather than set this to 1. */);
23490
23491 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
23492 doc: /* *Scroll up to this many lines, to bring point back on screen.
23493 A value of zero means to scroll the text to center point vertically
23494 in the window. */);
23495 scroll_conservatively = 0;
23496
23497 DEFVAR_INT ("scroll-margin", &scroll_margin,
23498 doc: /* *Number of lines of margin at the top and bottom of a window.
23499 Recenter the window whenever point gets within this many lines
23500 of the top or bottom of the window. */);
23501 scroll_margin = 0;
23502
23503 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
23504 doc: /* Pixels per inch value for non-window system displays.
23505 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
23506 Vdisplay_pixels_per_inch = make_float (72.0);
23507
23508 #if GLYPH_DEBUG
23509 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
23510 #endif
23511
23512 DEFVAR_BOOL ("truncate-partial-width-windows",
23513 &truncate_partial_width_windows,
23514 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
23515 truncate_partial_width_windows = 1;
23516
23517 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
23518 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
23519 Any other value means to use the appropriate face, `mode-line',
23520 `header-line', or `menu' respectively. */);
23521 mode_line_inverse_video = 1;
23522
23523 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
23524 doc: /* *Maximum buffer size for which line number should be displayed.
23525 If the buffer is bigger than this, the line number does not appear
23526 in the mode line. A value of nil means no limit. */);
23527 Vline_number_display_limit = Qnil;
23528
23529 DEFVAR_INT ("line-number-display-limit-width",
23530 &line_number_display_limit_width,
23531 doc: /* *Maximum line width (in characters) for line number display.
23532 If the average length of the lines near point is bigger than this, then the
23533 line number may be omitted from the mode line. */);
23534 line_number_display_limit_width = 200;
23535
23536 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
23537 doc: /* *Non-nil means highlight region even in nonselected windows. */);
23538 highlight_nonselected_windows = 0;
23539
23540 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
23541 doc: /* Non-nil if more than one frame is visible on this display.
23542 Minibuffer-only frames don't count, but iconified frames do.
23543 This variable is not guaranteed to be accurate except while processing
23544 `frame-title-format' and `icon-title-format'. */);
23545
23546 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
23547 doc: /* Template for displaying the title bar of visible frames.
23548 \(Assuming the window manager supports this feature.)
23549 This variable has the same structure as `mode-line-format' (which see),
23550 and is used only on frames for which no explicit name has been set
23551 \(see `modify-frame-parameters'). */);
23552
23553 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
23554 doc: /* Template for displaying the title bar of an iconified frame.
23555 \(Assuming the window manager supports this feature.)
23556 This variable has the same structure as `mode-line-format' (which see),
23557 and is used only on frames for which no explicit name has been set
23558 \(see `modify-frame-parameters'). */);
23559 Vicon_title_format
23560 = Vframe_title_format
23561 = Fcons (intern ("multiple-frames"),
23562 Fcons (build_string ("%b"),
23563 Fcons (Fcons (empty_string,
23564 Fcons (intern ("invocation-name"),
23565 Fcons (build_string ("@"),
23566 Fcons (intern ("system-name"),
23567 Qnil)))),
23568 Qnil)));
23569
23570 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
23571 doc: /* Maximum number of lines to keep in the message log buffer.
23572 If nil, disable message logging. If t, log messages but don't truncate
23573 the buffer when it becomes large. */);
23574 Vmessage_log_max = make_number (50);
23575
23576 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
23577 doc: /* Functions called before redisplay, if window sizes have changed.
23578 The value should be a list of functions that take one argument.
23579 Just before redisplay, for each frame, if any of its windows have changed
23580 size since the last redisplay, or have been split or deleted,
23581 all the functions in the list are called, with the frame as argument. */);
23582 Vwindow_size_change_functions = Qnil;
23583
23584 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
23585 doc: /* List of functions to call before redisplaying a window with scrolling.
23586 Each function is called with two arguments, the window
23587 and its new display-start position. Note that the value of `window-end'
23588 is not valid when these functions are called. */);
23589 Vwindow_scroll_functions = Qnil;
23590
23591 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
23592 doc: /* Functions called when redisplay of a window reaches the end trigger.
23593 Each function is called with two arguments, the window and the end trigger value.
23594 See `set-window-redisplay-end-trigger'. */);
23595 Vredisplay_end_trigger_functions = Qnil;
23596
23597 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
23598 doc: /* *Non-nil means autoselect window with mouse pointer. */);
23599 mouse_autoselect_window = 0;
23600
23601 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
23602 doc: /* *Non-nil means automatically resize tool-bars.
23603 This increases a tool-bar's height if not all tool-bar items are visible.
23604 It decreases a tool-bar's height when it would display blank lines
23605 otherwise. */);
23606 auto_resize_tool_bars_p = 1;
23607
23608 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
23609 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
23610 auto_raise_tool_bar_buttons_p = 1;
23611
23612 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
23613 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
23614 make_cursor_line_fully_visible_p = 1;
23615
23616 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
23617 doc: /* *Margin around tool-bar buttons in pixels.
23618 If an integer, use that for both horizontal and vertical margins.
23619 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
23620 HORZ specifying the horizontal margin, and VERT specifying the
23621 vertical margin. */);
23622 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
23623
23624 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
23625 doc: /* *Relief thickness of tool-bar buttons. */);
23626 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
23627
23628 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
23629 doc: /* List of functions to call to fontify regions of text.
23630 Each function is called with one argument POS. Functions must
23631 fontify a region starting at POS in the current buffer, and give
23632 fontified regions the property `fontified'. */);
23633 Vfontification_functions = Qnil;
23634 Fmake_variable_buffer_local (Qfontification_functions);
23635
23636 DEFVAR_BOOL ("unibyte-display-via-language-environment",
23637 &unibyte_display_via_language_environment,
23638 doc: /* *Non-nil means display unibyte text according to language environment.
23639 Specifically this means that unibyte non-ASCII characters
23640 are displayed by converting them to the equivalent multibyte characters
23641 according to the current language environment. As a result, they are
23642 displayed according to the current fontset. */);
23643 unibyte_display_via_language_environment = 0;
23644
23645 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
23646 doc: /* *Maximum height for resizing mini-windows.
23647 If a float, it specifies a fraction of the mini-window frame's height.
23648 If an integer, it specifies a number of lines. */);
23649 Vmax_mini_window_height = make_float (0.25);
23650
23651 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
23652 doc: /* *How to resize mini-windows.
23653 A value of nil means don't automatically resize mini-windows.
23654 A value of t means resize them to fit the text displayed in them.
23655 A value of `grow-only', the default, means let mini-windows grow
23656 only, until their display becomes empty, at which point the windows
23657 go back to their normal size. */);
23658 Vresize_mini_windows = Qgrow_only;
23659
23660 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
23661 doc: /* Alist specifying how to blink the cursor off.
23662 Each element has the form (ON-STATE . OFF-STATE). Whenever the
23663 `cursor-type' frame-parameter or variable equals ON-STATE,
23664 comparing using `equal', Emacs uses OFF-STATE to specify
23665 how to blink it off. ON-STATE and OFF-STATE are values for
23666 the `cursor-type' frame parameter.
23667
23668 If a frame's ON-STATE has no entry in this list,
23669 the frame's other specifications determine how to blink the cursor off. */);
23670 Vblink_cursor_alist = Qnil;
23671
23672 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
23673 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
23674 automatic_hscrolling_p = 1;
23675
23676 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
23677 doc: /* *How many columns away from the window edge point is allowed to get
23678 before automatic hscrolling will horizontally scroll the window. */);
23679 hscroll_margin = 5;
23680
23681 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
23682 doc: /* *How many columns to scroll the window when point gets too close to the edge.
23683 When point is less than `automatic-hscroll-margin' columns from the window
23684 edge, automatic hscrolling will scroll the window by the amount of columns
23685 determined by this variable. If its value is a positive integer, scroll that
23686 many columns. If it's a positive floating-point number, it specifies the
23687 fraction of the window's width to scroll. If it's nil or zero, point will be
23688 centered horizontally after the scroll. Any other value, including negative
23689 numbers, are treated as if the value were zero.
23690
23691 Automatic hscrolling always moves point outside the scroll margin, so if
23692 point was more than scroll step columns inside the margin, the window will
23693 scroll more than the value given by the scroll step.
23694
23695 Note that the lower bound for automatic hscrolling specified by `scroll-left'
23696 and `scroll-right' overrides this variable's effect. */);
23697 Vhscroll_step = make_number (0);
23698
23699 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
23700 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
23701 Bind this around calls to `message' to let it take effect. */);
23702 message_truncate_lines = 0;
23703
23704 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
23705 doc: /* Normal hook run to update the menu bar definitions.
23706 Redisplay runs this hook before it redisplays the menu bar.
23707 This is used to update submenus such as Buffers,
23708 whose contents depend on various data. */);
23709 Vmenu_bar_update_hook = Qnil;
23710
23711 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
23712 doc: /* Non-nil means don't update menu bars. Internal use only. */);
23713 inhibit_menubar_update = 0;
23714
23715 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
23716 doc: /* Non-nil means don't eval Lisp during redisplay. */);
23717 inhibit_eval_during_redisplay = 0;
23718
23719 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
23720 doc: /* Non-nil means don't free realized faces. Internal use only. */);
23721 inhibit_free_realized_faces = 0;
23722
23723 #if GLYPH_DEBUG
23724 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
23725 doc: /* Inhibit try_window_id display optimization. */);
23726 inhibit_try_window_id = 0;
23727
23728 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
23729 doc: /* Inhibit try_window_reusing display optimization. */);
23730 inhibit_try_window_reusing = 0;
23731
23732 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
23733 doc: /* Inhibit try_cursor_movement display optimization. */);
23734 inhibit_try_cursor_movement = 0;
23735 #endif /* GLYPH_DEBUG */
23736 }
23737
23738
23739 /* Initialize this module when Emacs starts. */
23740
23741 void
23742 init_xdisp ()
23743 {
23744 Lisp_Object root_window;
23745 struct window *mini_w;
23746
23747 current_header_line_height = current_mode_line_height = -1;
23748
23749 CHARPOS (this_line_start_pos) = 0;
23750
23751 mini_w = XWINDOW (minibuf_window);
23752 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
23753
23754 if (!noninteractive)
23755 {
23756 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
23757 int i;
23758
23759 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
23760 set_window_height (root_window,
23761 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
23762 0);
23763 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
23764 set_window_height (minibuf_window, 1, 0);
23765
23766 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
23767 mini_w->total_cols = make_number (FRAME_COLS (f));
23768
23769 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
23770 scratch_glyph_row.glyphs[TEXT_AREA + 1]
23771 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
23772
23773 /* The default ellipsis glyphs `...'. */
23774 for (i = 0; i < 3; ++i)
23775 default_invis_vector[i] = make_number ('.');
23776 }
23777
23778 {
23779 /* Allocate the buffer for frame titles.
23780 Also used for `format-mode-line'. */
23781 int size = 100;
23782 mode_line_noprop_buf = (char *) xmalloc (size);
23783 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
23784 mode_line_noprop_ptr = mode_line_noprop_buf;
23785 mode_line_target = MODE_LINE_DISPLAY;
23786 }
23787
23788 help_echo_showing_p = 0;
23789 }
23790
23791
23792 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
23793 (do not change this comment) */