]> code.delx.au - gnu-emacs/blob - src/xdisp.c
(pos_visible_p): CHARPOS < 0 means return info for
[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-nil means automatically select any window when the mouse
260 cursor moves into it. */
261 Lisp_Object Vmouse_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 below tool bar in pixels. 0 or nil means no margin.
273 If value is `internal-border-width' or `border-width',
274 the corresponding frame parameter is used. */
275
276 Lisp_Object Vtool_bar_border;
277
278 /* Margin around tool bar buttons in pixels. */
279
280 Lisp_Object Vtool_bar_button_margin;
281
282 /* Thickness of shadow to draw around tool bar buttons. */
283
284 EMACS_INT tool_bar_button_relief;
285
286 /* Non-zero means automatically resize tool-bars so that all tool-bar
287 items are visible, and no blank lines remain. */
288
289 int auto_resize_tool_bars_p;
290
291 /* Non-zero means draw block and hollow cursor as wide as the glyph
292 under it. For example, if a block cursor is over a tab, it will be
293 drawn as wide as that tab on the display. */
294
295 int x_stretch_cursor_p;
296
297 /* Non-nil means don't actually do any redisplay. */
298
299 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
300
301 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
302
303 int inhibit_eval_during_redisplay;
304
305 /* Names of text properties relevant for redisplay. */
306
307 Lisp_Object Qdisplay;
308 extern Lisp_Object Qface, Qinvisible, Qwidth;
309
310 /* Symbols used in text property values. */
311
312 Lisp_Object Vdisplay_pixels_per_inch;
313 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
314 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
315 Lisp_Object Qslice;
316 Lisp_Object Qcenter;
317 Lisp_Object Qmargin, Qpointer;
318 Lisp_Object Qline_height;
319 extern Lisp_Object Qheight;
320 extern Lisp_Object QCwidth, QCheight, QCascent;
321 extern Lisp_Object Qscroll_bar;
322 extern Lisp_Object Qcursor;
323
324 /* Non-nil means highlight trailing whitespace. */
325
326 Lisp_Object Vshow_trailing_whitespace;
327
328 /* Non-nil means escape non-break space and hyphens. */
329
330 Lisp_Object Vnobreak_char_display;
331
332 #ifdef HAVE_WINDOW_SYSTEM
333 extern Lisp_Object Voverflow_newline_into_fringe;
334
335 /* Test if overflow newline into fringe. Called with iterator IT
336 at or past right window margin, and with IT->current_x set. */
337
338 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
339 (!NILP (Voverflow_newline_into_fringe) \
340 && FRAME_WINDOW_P (it->f) \
341 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
342 && it->current_x == it->last_visible_x)
343
344 #endif /* HAVE_WINDOW_SYSTEM */
345
346 /* Non-nil means show the text cursor in void text areas
347 i.e. in blank areas after eol and eob. This used to be
348 the default in 21.3. */
349
350 Lisp_Object Vvoid_text_area_pointer;
351
352 /* Name of the face used to highlight trailing whitespace. */
353
354 Lisp_Object Qtrailing_whitespace;
355
356 /* Name and number of the face used to highlight escape glyphs. */
357
358 Lisp_Object Qescape_glyph;
359
360 /* Name and number of the face used to highlight non-breaking spaces. */
361
362 Lisp_Object Qnobreak_space;
363
364 /* The symbol `image' which is the car of the lists used to represent
365 images in Lisp. */
366
367 Lisp_Object Qimage;
368
369 /* The image map types. */
370 Lisp_Object QCmap, QCpointer;
371 Lisp_Object Qrect, Qcircle, Qpoly;
372
373 /* Non-zero means print newline to stdout before next mini-buffer
374 message. */
375
376 int noninteractive_need_newline;
377
378 /* Non-zero means print newline to message log before next message. */
379
380 static int message_log_need_newline;
381
382 /* Three markers that message_dolog uses.
383 It could allocate them itself, but that causes trouble
384 in handling memory-full errors. */
385 static Lisp_Object message_dolog_marker1;
386 static Lisp_Object message_dolog_marker2;
387 static Lisp_Object message_dolog_marker3;
388 \f
389 /* The buffer position of the first character appearing entirely or
390 partially on the line of the selected window which contains the
391 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
392 redisplay optimization in redisplay_internal. */
393
394 static struct text_pos this_line_start_pos;
395
396 /* Number of characters past the end of the line above, including the
397 terminating newline. */
398
399 static struct text_pos this_line_end_pos;
400
401 /* The vertical positions and the height of this line. */
402
403 static int this_line_vpos;
404 static int this_line_y;
405 static int this_line_pixel_height;
406
407 /* X position at which this display line starts. Usually zero;
408 negative if first character is partially visible. */
409
410 static int this_line_start_x;
411
412 /* Buffer that this_line_.* variables are referring to. */
413
414 static struct buffer *this_line_buffer;
415
416 /* Nonzero means truncate lines in all windows less wide than the
417 frame. */
418
419 int truncate_partial_width_windows;
420
421 /* A flag to control how to display unibyte 8-bit character. */
422
423 int unibyte_display_via_language_environment;
424
425 /* Nonzero means we have more than one non-mini-buffer-only frame.
426 Not guaranteed to be accurate except while parsing
427 frame-title-format. */
428
429 int multiple_frames;
430
431 Lisp_Object Vglobal_mode_string;
432
433
434 /* List of variables (symbols) which hold markers for overlay arrows.
435 The symbols on this list are examined during redisplay to determine
436 where to display overlay arrows. */
437
438 Lisp_Object Voverlay_arrow_variable_list;
439
440 /* Marker for where to display an arrow on top of the buffer text. */
441
442 Lisp_Object Voverlay_arrow_position;
443
444 /* String to display for the arrow. Only used on terminal frames. */
445
446 Lisp_Object Voverlay_arrow_string;
447
448 /* Values of those variables at last redisplay are stored as
449 properties on `overlay-arrow-position' symbol. However, if
450 Voverlay_arrow_position is a marker, last-arrow-position is its
451 numerical position. */
452
453 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
454
455 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
456 properties on a symbol in overlay-arrow-variable-list. */
457
458 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
459
460 /* Like mode-line-format, but for the title bar on a visible frame. */
461
462 Lisp_Object Vframe_title_format;
463
464 /* Like mode-line-format, but for the title bar on an iconified frame. */
465
466 Lisp_Object Vicon_title_format;
467
468 /* List of functions to call when a window's size changes. These
469 functions get one arg, a frame on which one or more windows' sizes
470 have changed. */
471
472 static Lisp_Object Vwindow_size_change_functions;
473
474 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
475
476 /* Nonzero if an overlay arrow has been displayed in this window. */
477
478 static int overlay_arrow_seen;
479
480 /* Nonzero means highlight the region even in nonselected windows. */
481
482 int highlight_nonselected_windows;
483
484 /* If cursor motion alone moves point off frame, try scrolling this
485 many lines up or down if that will bring it back. */
486
487 static EMACS_INT scroll_step;
488
489 /* Nonzero means scroll just far enough to bring point back on the
490 screen, when appropriate. */
491
492 static EMACS_INT scroll_conservatively;
493
494 /* Recenter the window whenever point gets within this many lines of
495 the top or bottom of the window. This value is translated into a
496 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
497 that there is really a fixed pixel height scroll margin. */
498
499 EMACS_INT scroll_margin;
500
501 /* Number of windows showing the buffer of the selected window (or
502 another buffer with the same base buffer). keyboard.c refers to
503 this. */
504
505 int buffer_shared;
506
507 /* Vector containing glyphs for an ellipsis `...'. */
508
509 static Lisp_Object default_invis_vector[3];
510
511 /* Zero means display the mode-line/header-line/menu-bar in the default face
512 (this slightly odd definition is for compatibility with previous versions
513 of emacs), non-zero means display them using their respective faces.
514
515 This variable is deprecated. */
516
517 int mode_line_inverse_video;
518
519 /* Prompt to display in front of the mini-buffer contents. */
520
521 Lisp_Object minibuf_prompt;
522
523 /* Width of current mini-buffer prompt. Only set after display_line
524 of the line that contains the prompt. */
525
526 int minibuf_prompt_width;
527
528 /* This is the window where the echo area message was displayed. It
529 is always a mini-buffer window, but it may not be the same window
530 currently active as a mini-buffer. */
531
532 Lisp_Object echo_area_window;
533
534 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
535 pushes the current message and the value of
536 message_enable_multibyte on the stack, the function restore_message
537 pops the stack and displays MESSAGE again. */
538
539 Lisp_Object Vmessage_stack;
540
541 /* Nonzero means multibyte characters were enabled when the echo area
542 message was specified. */
543
544 int message_enable_multibyte;
545
546 /* Nonzero if we should redraw the mode lines on the next redisplay. */
547
548 int update_mode_lines;
549
550 /* Nonzero if window sizes or contents have changed since last
551 redisplay that finished. */
552
553 int windows_or_buffers_changed;
554
555 /* Nonzero means a frame's cursor type has been changed. */
556
557 int cursor_type_changed;
558
559 /* Nonzero after display_mode_line if %l was used and it displayed a
560 line number. */
561
562 int line_number_displayed;
563
564 /* Maximum buffer size for which to display line numbers. */
565
566 Lisp_Object Vline_number_display_limit;
567
568 /* Line width to consider when repositioning for line number display. */
569
570 static EMACS_INT line_number_display_limit_width;
571
572 /* Number of lines to keep in the message log buffer. t means
573 infinite. nil means don't log at all. */
574
575 Lisp_Object Vmessage_log_max;
576
577 /* The name of the *Messages* buffer, a string. */
578
579 static Lisp_Object Vmessages_buffer_name;
580
581 /* Index 0 is the buffer that holds the current (desired) echo area message,
582 or nil if none is desired right now.
583
584 Index 1 is the buffer that holds the previously displayed echo area message,
585 or nil to indicate no message. This is normally what's on the screen now.
586
587 These two can point to the same buffer. That happens when the last
588 message output by the user (or made by echoing) has been displayed. */
589
590 Lisp_Object echo_area_buffer[2];
591
592 /* Permanent pointers to the two buffers that are used for echo area
593 purposes. Once the two buffers are made, and their pointers are
594 placed here, these two slots remain unchanged unless those buffers
595 need to be created afresh. */
596
597 static Lisp_Object echo_buffer[2];
598
599 /* A vector saved used in with_area_buffer to reduce consing. */
600
601 static Lisp_Object Vwith_echo_area_save_vector;
602
603 /* Non-zero means display_echo_area should display the last echo area
604 message again. Set by redisplay_preserve_echo_area. */
605
606 static int display_last_displayed_message_p;
607
608 /* Nonzero if echo area is being used by print; zero if being used by
609 message. */
610
611 int message_buf_print;
612
613 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
614
615 Lisp_Object Qinhibit_menubar_update;
616 int inhibit_menubar_update;
617
618 /* When evaluating expressions from menu bar items (enable conditions,
619 for instance), this is the frame they are being processed for. */
620
621 Lisp_Object Vmenu_updating_frame;
622
623 /* Maximum height for resizing mini-windows. Either a float
624 specifying a fraction of the available height, or an integer
625 specifying a number of lines. */
626
627 Lisp_Object Vmax_mini_window_height;
628
629 /* Non-zero means messages should be displayed with truncated
630 lines instead of being continued. */
631
632 int message_truncate_lines;
633 Lisp_Object Qmessage_truncate_lines;
634
635 /* Set to 1 in clear_message to make redisplay_internal aware
636 of an emptied echo area. */
637
638 static int message_cleared_p;
639
640 /* How to blink the default frame cursor off. */
641 Lisp_Object Vblink_cursor_alist;
642
643 /* A scratch glyph row with contents used for generating truncation
644 glyphs. Also used in direct_output_for_insert. */
645
646 #define MAX_SCRATCH_GLYPHS 100
647 struct glyph_row scratch_glyph_row;
648 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
649
650 /* Ascent and height of the last line processed by move_it_to. */
651
652 static int last_max_ascent, last_height;
653
654 /* Non-zero if there's a help-echo in the echo area. */
655
656 int help_echo_showing_p;
657
658 /* If >= 0, computed, exact values of mode-line and header-line height
659 to use in the macros CURRENT_MODE_LINE_HEIGHT and
660 CURRENT_HEADER_LINE_HEIGHT. */
661
662 int current_mode_line_height, current_header_line_height;
663
664 /* The maximum distance to look ahead for text properties. Values
665 that are too small let us call compute_char_face and similar
666 functions too often which is expensive. Values that are too large
667 let us call compute_char_face and alike too often because we
668 might not be interested in text properties that far away. */
669
670 #define TEXT_PROP_DISTANCE_LIMIT 100
671
672 #if GLYPH_DEBUG
673
674 /* Variables to turn off display optimizations from Lisp. */
675
676 int inhibit_try_window_id, inhibit_try_window_reusing;
677 int inhibit_try_cursor_movement;
678
679 /* Non-zero means print traces of redisplay if compiled with
680 GLYPH_DEBUG != 0. */
681
682 int trace_redisplay_p;
683
684 #endif /* GLYPH_DEBUG */
685
686 #ifdef DEBUG_TRACE_MOVE
687 /* Non-zero means trace with TRACE_MOVE to stderr. */
688 int trace_move;
689
690 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
691 #else
692 #define TRACE_MOVE(x) (void) 0
693 #endif
694
695 /* Non-zero means automatically scroll windows horizontally to make
696 point visible. */
697
698 int automatic_hscrolling_p;
699
700 /* How close to the margin can point get before the window is scrolled
701 horizontally. */
702 EMACS_INT hscroll_margin;
703
704 /* How much to scroll horizontally when point is inside the above margin. */
705 Lisp_Object Vhscroll_step;
706
707 /* The variable `resize-mini-windows'. If nil, don't resize
708 mini-windows. If t, always resize them to fit the text they
709 display. If `grow-only', let mini-windows grow only until they
710 become empty. */
711
712 Lisp_Object Vresize_mini_windows;
713
714 /* Buffer being redisplayed -- for redisplay_window_error. */
715
716 struct buffer *displayed_buffer;
717
718 /* Space between overline and text. */
719
720 EMACS_INT overline_margin;
721
722 /* Value returned from text property handlers (see below). */
723
724 enum prop_handled
725 {
726 HANDLED_NORMALLY,
727 HANDLED_RECOMPUTE_PROPS,
728 HANDLED_OVERLAY_STRING_CONSUMED,
729 HANDLED_RETURN
730 };
731
732 /* A description of text properties that redisplay is interested
733 in. */
734
735 struct props
736 {
737 /* The name of the property. */
738 Lisp_Object *name;
739
740 /* A unique index for the property. */
741 enum prop_idx idx;
742
743 /* A handler function called to set up iterator IT from the property
744 at IT's current position. Value is used to steer handle_stop. */
745 enum prop_handled (*handler) P_ ((struct it *it));
746 };
747
748 static enum prop_handled handle_face_prop P_ ((struct it *));
749 static enum prop_handled handle_invisible_prop P_ ((struct it *));
750 static enum prop_handled handle_display_prop P_ ((struct it *));
751 static enum prop_handled handle_composition_prop P_ ((struct it *));
752 static enum prop_handled handle_overlay_change P_ ((struct it *));
753 static enum prop_handled handle_fontified_prop P_ ((struct it *));
754
755 /* Properties handled by iterators. */
756
757 static struct props it_props[] =
758 {
759 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
760 /* Handle `face' before `display' because some sub-properties of
761 `display' need to know the face. */
762 {&Qface, FACE_PROP_IDX, handle_face_prop},
763 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
764 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
765 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
766 {NULL, 0, NULL}
767 };
768
769 /* Value is the position described by X. If X is a marker, value is
770 the marker_position of X. Otherwise, value is X. */
771
772 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
773
774 /* Enumeration returned by some move_it_.* functions internally. */
775
776 enum move_it_result
777 {
778 /* Not used. Undefined value. */
779 MOVE_UNDEFINED,
780
781 /* Move ended at the requested buffer position or ZV. */
782 MOVE_POS_MATCH_OR_ZV,
783
784 /* Move ended at the requested X pixel position. */
785 MOVE_X_REACHED,
786
787 /* Move within a line ended at the end of a line that must be
788 continued. */
789 MOVE_LINE_CONTINUED,
790
791 /* Move within a line ended at the end of a line that would
792 be displayed truncated. */
793 MOVE_LINE_TRUNCATED,
794
795 /* Move within a line ended at a line end. */
796 MOVE_NEWLINE_OR_CR
797 };
798
799 /* This counter is used to clear the face cache every once in a while
800 in redisplay_internal. It is incremented for each redisplay.
801 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
802 cleared. */
803
804 #define CLEAR_FACE_CACHE_COUNT 500
805 static int clear_face_cache_count;
806
807 /* Similarly for the image cache. */
808
809 #ifdef HAVE_WINDOW_SYSTEM
810 #define CLEAR_IMAGE_CACHE_COUNT 101
811 static int clear_image_cache_count;
812 #endif
813
814 /* Record the previous terminal frame we displayed. */
815
816 static struct frame *previous_terminal_frame;
817
818 /* Non-zero while redisplay_internal is in progress. */
819
820 int redisplaying_p;
821
822 /* Non-zero means don't free realized faces. Bound while freeing
823 realized faces is dangerous because glyph matrices might still
824 reference them. */
825
826 int inhibit_free_realized_faces;
827 Lisp_Object Qinhibit_free_realized_faces;
828
829 /* If a string, XTread_socket generates an event to display that string.
830 (The display is done in read_char.) */
831
832 Lisp_Object help_echo_string;
833 Lisp_Object help_echo_window;
834 Lisp_Object help_echo_object;
835 int help_echo_pos;
836
837 /* Temporary variable for XTread_socket. */
838
839 Lisp_Object previous_help_echo_string;
840
841 /* Null glyph slice */
842
843 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
844
845 \f
846 /* Function prototypes. */
847
848 static void setup_for_ellipsis P_ ((struct it *, int));
849 static void mark_window_display_accurate_1 P_ ((struct window *, int));
850 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
851 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
852 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
853 static int redisplay_mode_lines P_ ((Lisp_Object, int));
854 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
855
856 #if 0
857 static int invisible_text_between_p P_ ((struct it *, int, int));
858 #endif
859
860 static void pint2str P_ ((char *, int, int));
861 static void pint2hrstr P_ ((char *, int, int));
862 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
863 struct text_pos));
864 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
865 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
866 static void store_mode_line_noprop_char P_ ((char));
867 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
868 static void x_consider_frame_title P_ ((Lisp_Object));
869 static void handle_stop P_ ((struct it *));
870 static int tool_bar_lines_needed P_ ((struct frame *, int *));
871 static int single_display_spec_intangible_p P_ ((Lisp_Object));
872 static void ensure_echo_area_buffers P_ ((void));
873 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
874 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
875 static int with_echo_area_buffer P_ ((struct window *, int,
876 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
877 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
878 static void clear_garbaged_frames P_ ((void));
879 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
880 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
881 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
882 static int display_echo_area P_ ((struct window *));
883 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
884 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
885 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
886 static int string_char_and_length P_ ((const unsigned char *, int, int *));
887 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
888 struct text_pos));
889 static int compute_window_start_on_continuation_line P_ ((struct window *));
890 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
891 static void insert_left_trunc_glyphs P_ ((struct it *));
892 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
893 Lisp_Object));
894 static void extend_face_to_end_of_line P_ ((struct it *));
895 static int append_space_for_newline P_ ((struct it *, int));
896 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
897 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
898 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
899 static int trailing_whitespace_p P_ ((int));
900 static int message_log_check_duplicate P_ ((int, int, int, int));
901 static void push_it P_ ((struct it *));
902 static void pop_it P_ ((struct it *));
903 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
904 static void select_frame_for_redisplay P_ ((Lisp_Object));
905 static void redisplay_internal P_ ((int));
906 static int echo_area_display P_ ((int));
907 static void redisplay_windows P_ ((Lisp_Object));
908 static void redisplay_window P_ ((Lisp_Object, int));
909 static Lisp_Object redisplay_window_error ();
910 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
911 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
912 static int update_menu_bar P_ ((struct frame *, int, int));
913 static int try_window_reusing_current_matrix P_ ((struct window *));
914 static int try_window_id P_ ((struct window *));
915 static int display_line P_ ((struct it *));
916 static int display_mode_lines P_ ((struct window *));
917 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
918 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
919 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
920 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
921 static void display_menu_bar P_ ((struct window *));
922 static int display_count_lines P_ ((int, int, int, int, int *));
923 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
924 int, int, struct it *, int, int, int, int));
925 static void compute_line_metrics P_ ((struct it *));
926 static void run_redisplay_end_trigger_hook P_ ((struct it *));
927 static int get_overlay_strings P_ ((struct it *, int));
928 static int get_overlay_strings_1 P_ ((struct it *, int, int));
929 static void next_overlay_string P_ ((struct it *));
930 static void reseat P_ ((struct it *, struct text_pos, int));
931 static void reseat_1 P_ ((struct it *, struct text_pos, int));
932 static void back_to_previous_visible_line_start P_ ((struct it *));
933 void reseat_at_previous_visible_line_start P_ ((struct it *));
934 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
935 static int next_element_from_ellipsis P_ ((struct it *));
936 static int next_element_from_display_vector P_ ((struct it *));
937 static int next_element_from_string P_ ((struct it *));
938 static int next_element_from_c_string P_ ((struct it *));
939 static int next_element_from_buffer P_ ((struct it *));
940 static int next_element_from_composition P_ ((struct it *));
941 static int next_element_from_image P_ ((struct it *));
942 static int next_element_from_stretch P_ ((struct it *));
943 static void load_overlay_strings P_ ((struct it *, int));
944 static int init_from_display_pos P_ ((struct it *, struct window *,
945 struct display_pos *));
946 static void reseat_to_string P_ ((struct it *, unsigned char *,
947 Lisp_Object, int, int, int, int));
948 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
949 int, int, int));
950 void move_it_vertically_backward P_ ((struct it *, int));
951 static void init_to_row_start P_ ((struct it *, struct window *,
952 struct glyph_row *));
953 static int init_to_row_end P_ ((struct it *, struct window *,
954 struct glyph_row *));
955 static void back_to_previous_line_start P_ ((struct it *));
956 static int forward_to_next_line_start P_ ((struct it *, int *));
957 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
958 Lisp_Object, int));
959 static struct text_pos string_pos P_ ((int, Lisp_Object));
960 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
961 static int number_of_chars P_ ((unsigned char *, int));
962 static void compute_stop_pos P_ ((struct it *));
963 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
964 Lisp_Object));
965 static int face_before_or_after_it_pos P_ ((struct it *, int));
966 static int next_overlay_change P_ ((int));
967 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
968 Lisp_Object, struct text_pos *,
969 int));
970 static int underlying_face_id P_ ((struct it *));
971 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
972 struct window *));
973
974 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
975 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
976
977 #ifdef HAVE_WINDOW_SYSTEM
978
979 static void update_tool_bar P_ ((struct frame *, int));
980 static void build_desired_tool_bar_string P_ ((struct frame *f));
981 static int redisplay_tool_bar P_ ((struct frame *));
982 static void display_tool_bar_line P_ ((struct it *, int));
983 static void notice_overwritten_cursor P_ ((struct window *,
984 enum glyph_row_area,
985 int, int, int, int));
986
987
988
989 #endif /* HAVE_WINDOW_SYSTEM */
990
991 \f
992 /***********************************************************************
993 Window display dimensions
994 ***********************************************************************/
995
996 /* Return the bottom boundary y-position for text lines in window W.
997 This is the first y position at which a line cannot start.
998 It is relative to the top of the window.
999
1000 This is the height of W minus the height of a mode line, if any. */
1001
1002 INLINE int
1003 window_text_bottom_y (w)
1004 struct window *w;
1005 {
1006 int height = WINDOW_TOTAL_HEIGHT (w);
1007
1008 if (WINDOW_WANTS_MODELINE_P (w))
1009 height -= CURRENT_MODE_LINE_HEIGHT (w);
1010 return height;
1011 }
1012
1013 /* Return the pixel width of display area AREA of window W. AREA < 0
1014 means return the total width of W, not including fringes to
1015 the left and right of the window. */
1016
1017 INLINE int
1018 window_box_width (w, area)
1019 struct window *w;
1020 int area;
1021 {
1022 int cols = XFASTINT (w->total_cols);
1023 int pixels = 0;
1024
1025 if (!w->pseudo_window_p)
1026 {
1027 cols -= WINDOW_SCROLL_BAR_COLS (w);
1028
1029 if (area == TEXT_AREA)
1030 {
1031 if (INTEGERP (w->left_margin_cols))
1032 cols -= XFASTINT (w->left_margin_cols);
1033 if (INTEGERP (w->right_margin_cols))
1034 cols -= XFASTINT (w->right_margin_cols);
1035 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1036 }
1037 else if (area == LEFT_MARGIN_AREA)
1038 {
1039 cols = (INTEGERP (w->left_margin_cols)
1040 ? XFASTINT (w->left_margin_cols) : 0);
1041 pixels = 0;
1042 }
1043 else if (area == RIGHT_MARGIN_AREA)
1044 {
1045 cols = (INTEGERP (w->right_margin_cols)
1046 ? XFASTINT (w->right_margin_cols) : 0);
1047 pixels = 0;
1048 }
1049 }
1050
1051 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1052 }
1053
1054
1055 /* Return the pixel height of the display area of window W, not
1056 including mode lines of W, if any. */
1057
1058 INLINE int
1059 window_box_height (w)
1060 struct window *w;
1061 {
1062 struct frame *f = XFRAME (w->frame);
1063 int height = WINDOW_TOTAL_HEIGHT (w);
1064
1065 xassert (height >= 0);
1066
1067 /* Note: the code below that determines the mode-line/header-line
1068 height is essentially the same as that contained in the macro
1069 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1070 the appropriate glyph row has its `mode_line_p' flag set,
1071 and if it doesn't, uses estimate_mode_line_height instead. */
1072
1073 if (WINDOW_WANTS_MODELINE_P (w))
1074 {
1075 struct glyph_row *ml_row
1076 = (w->current_matrix && w->current_matrix->rows
1077 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1078 : 0);
1079 if (ml_row && ml_row->mode_line_p)
1080 height -= ml_row->height;
1081 else
1082 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1083 }
1084
1085 if (WINDOW_WANTS_HEADER_LINE_P (w))
1086 {
1087 struct glyph_row *hl_row
1088 = (w->current_matrix && w->current_matrix->rows
1089 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1090 : 0);
1091 if (hl_row && hl_row->mode_line_p)
1092 height -= hl_row->height;
1093 else
1094 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1095 }
1096
1097 /* With a very small font and a mode-line that's taller than
1098 default, we might end up with a negative height. */
1099 return max (0, height);
1100 }
1101
1102 /* Return the window-relative coordinate of the left edge of display
1103 area AREA of window W. AREA < 0 means return the left edge of the
1104 whole window, to the right of the left fringe of W. */
1105
1106 INLINE int
1107 window_box_left_offset (w, area)
1108 struct window *w;
1109 int area;
1110 {
1111 int x;
1112
1113 if (w->pseudo_window_p)
1114 return 0;
1115
1116 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1117
1118 if (area == TEXT_AREA)
1119 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1120 + window_box_width (w, LEFT_MARGIN_AREA));
1121 else if (area == RIGHT_MARGIN_AREA)
1122 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1123 + window_box_width (w, LEFT_MARGIN_AREA)
1124 + window_box_width (w, TEXT_AREA)
1125 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1126 ? 0
1127 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1128 else if (area == LEFT_MARGIN_AREA
1129 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1130 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1131
1132 return x;
1133 }
1134
1135
1136 /* Return the window-relative coordinate of the right edge of display
1137 area AREA of window W. AREA < 0 means return the left edge of the
1138 whole window, to the left of the right fringe of W. */
1139
1140 INLINE int
1141 window_box_right_offset (w, area)
1142 struct window *w;
1143 int area;
1144 {
1145 return window_box_left_offset (w, area) + window_box_width (w, area);
1146 }
1147
1148 /* Return the frame-relative coordinate of the left edge of display
1149 area AREA of window W. AREA < 0 means return the left edge of the
1150 whole window, to the right of the left fringe of W. */
1151
1152 INLINE int
1153 window_box_left (w, area)
1154 struct window *w;
1155 int area;
1156 {
1157 struct frame *f = XFRAME (w->frame);
1158 int x;
1159
1160 if (w->pseudo_window_p)
1161 return FRAME_INTERNAL_BORDER_WIDTH (f);
1162
1163 x = (WINDOW_LEFT_EDGE_X (w)
1164 + window_box_left_offset (w, area));
1165
1166 return x;
1167 }
1168
1169
1170 /* Return the frame-relative coordinate of the right edge of display
1171 area AREA of window W. AREA < 0 means return the left edge of the
1172 whole window, to the left of the right fringe of W. */
1173
1174 INLINE int
1175 window_box_right (w, area)
1176 struct window *w;
1177 int area;
1178 {
1179 return window_box_left (w, area) + window_box_width (w, area);
1180 }
1181
1182 /* Get the bounding box of the display area AREA of window W, without
1183 mode lines, in frame-relative coordinates. AREA < 0 means the
1184 whole window, not including the left and right fringes of
1185 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1186 coordinates of the upper-left corner of the box. Return in
1187 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1188
1189 INLINE void
1190 window_box (w, area, box_x, box_y, box_width, box_height)
1191 struct window *w;
1192 int area;
1193 int *box_x, *box_y, *box_width, *box_height;
1194 {
1195 if (box_width)
1196 *box_width = window_box_width (w, area);
1197 if (box_height)
1198 *box_height = window_box_height (w);
1199 if (box_x)
1200 *box_x = window_box_left (w, area);
1201 if (box_y)
1202 {
1203 *box_y = WINDOW_TOP_EDGE_Y (w);
1204 if (WINDOW_WANTS_HEADER_LINE_P (w))
1205 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1206 }
1207 }
1208
1209
1210 /* Get the bounding box of the display area AREA of window W, without
1211 mode lines. AREA < 0 means the whole window, not including the
1212 left and right fringe of the window. Return in *TOP_LEFT_X
1213 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1214 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1215 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1216 box. */
1217
1218 INLINE void
1219 window_box_edges (w, area, top_left_x, top_left_y,
1220 bottom_right_x, bottom_right_y)
1221 struct window *w;
1222 int area;
1223 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1224 {
1225 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1226 bottom_right_y);
1227 *bottom_right_x += *top_left_x;
1228 *bottom_right_y += *top_left_y;
1229 }
1230
1231
1232 \f
1233 /***********************************************************************
1234 Utilities
1235 ***********************************************************************/
1236
1237 /* Return the bottom y-position of the line the iterator IT is in.
1238 This can modify IT's settings. */
1239
1240 int
1241 line_bottom_y (it)
1242 struct it *it;
1243 {
1244 int line_height = it->max_ascent + it->max_descent;
1245 int line_top_y = it->current_y;
1246
1247 if (line_height == 0)
1248 {
1249 if (last_height)
1250 line_height = last_height;
1251 else if (IT_CHARPOS (*it) < ZV)
1252 {
1253 move_it_by_lines (it, 1, 1);
1254 line_height = (it->max_ascent || it->max_descent
1255 ? it->max_ascent + it->max_descent
1256 : last_height);
1257 }
1258 else
1259 {
1260 struct glyph_row *row = it->glyph_row;
1261
1262 /* Use the default character height. */
1263 it->glyph_row = NULL;
1264 it->what = IT_CHARACTER;
1265 it->c = ' ';
1266 it->len = 1;
1267 PRODUCE_GLYPHS (it);
1268 line_height = it->ascent + it->descent;
1269 it->glyph_row = row;
1270 }
1271 }
1272
1273 return line_top_y + line_height;
1274 }
1275
1276
1277 /* Return 1 if position CHARPOS is visible in window W.
1278 CHARPOS < 0 means return info about WINDOW_END position.
1279 If visible, set *X and *Y to pixel coordinates of top left corner.
1280 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1281 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1282
1283 int
1284 pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
1285 struct window *w;
1286 int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
1287 {
1288 struct it it;
1289 struct text_pos top;
1290 int visible_p = 0;
1291 struct buffer *old_buffer = NULL;
1292
1293 if (noninteractive)
1294 return visible_p;
1295
1296 if (XBUFFER (w->buffer) != current_buffer)
1297 {
1298 old_buffer = current_buffer;
1299 set_buffer_internal_1 (XBUFFER (w->buffer));
1300 }
1301
1302 SET_TEXT_POS_FROM_MARKER (top, w->start);
1303
1304 /* Compute exact mode line heights. */
1305 if (WINDOW_WANTS_MODELINE_P (w))
1306 current_mode_line_height
1307 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1308 current_buffer->mode_line_format);
1309
1310 if (WINDOW_WANTS_HEADER_LINE_P (w))
1311 current_header_line_height
1312 = display_mode_line (w, HEADER_LINE_FACE_ID,
1313 current_buffer->header_line_format);
1314
1315 start_display (&it, w, top);
1316 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1317 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1318
1319 /* Note that we may overshoot because of invisible text. */
1320 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1321 {
1322 int top_x = it.current_x;
1323 int top_y = it.current_y;
1324 int bottom_y = (last_height = 0, line_bottom_y (&it));
1325 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1326
1327 if (top_y < window_top_y)
1328 visible_p = bottom_y > window_top_y;
1329 else if (top_y < it.last_visible_y)
1330 visible_p = 1;
1331 if (visible_p)
1332 {
1333 *x = top_x;
1334 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1335 *rtop = max (0, window_top_y - top_y);
1336 *rbot = max (0, bottom_y - it.last_visible_y);
1337 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1338 - max (top_y, window_top_y)));
1339 *vpos = it.vpos;
1340 }
1341 }
1342 else
1343 {
1344 struct it it2;
1345
1346 it2 = it;
1347 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1348 move_it_by_lines (&it, 1, 0);
1349 if (charpos < IT_CHARPOS (it))
1350 {
1351 visible_p = 1;
1352 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1353 *x = it2.current_x;
1354 *y = it2.current_y + it2.max_ascent - it2.ascent;
1355 *rtop = max (0, -it2.current_y);
1356 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1357 - it.last_visible_y));
1358 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1359 it.last_visible_y)
1360 - max (it2.current_y,
1361 WINDOW_HEADER_LINE_HEIGHT (w))));
1362 *vpos = it2.vpos;
1363 }
1364 }
1365
1366 if (old_buffer)
1367 set_buffer_internal_1 (old_buffer);
1368
1369 current_header_line_height = current_mode_line_height = -1;
1370
1371 if (visible_p && XFASTINT (w->hscroll) > 0)
1372 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1373
1374 #if 0
1375 /* Debugging code. */
1376 if (visible_p)
1377 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1378 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1379 else
1380 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1381 #endif
1382
1383 return visible_p;
1384 }
1385
1386
1387 /* Return the next character from STR which is MAXLEN bytes long.
1388 Return in *LEN the length of the character. This is like
1389 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1390 we find one, we return a `?', but with the length of the invalid
1391 character. */
1392
1393 static INLINE int
1394 string_char_and_length (str, maxlen, len)
1395 const unsigned char *str;
1396 int maxlen, *len;
1397 {
1398 int c;
1399
1400 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1401 if (!CHAR_VALID_P (c, 1))
1402 /* We may not change the length here because other places in Emacs
1403 don't use this function, i.e. they silently accept invalid
1404 characters. */
1405 c = '?';
1406
1407 return c;
1408 }
1409
1410
1411
1412 /* Given a position POS containing a valid character and byte position
1413 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1414
1415 static struct text_pos
1416 string_pos_nchars_ahead (pos, string, nchars)
1417 struct text_pos pos;
1418 Lisp_Object string;
1419 int nchars;
1420 {
1421 xassert (STRINGP (string) && nchars >= 0);
1422
1423 if (STRING_MULTIBYTE (string))
1424 {
1425 int rest = SBYTES (string) - BYTEPOS (pos);
1426 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1427 int len;
1428
1429 while (nchars--)
1430 {
1431 string_char_and_length (p, rest, &len);
1432 p += len, rest -= len;
1433 xassert (rest >= 0);
1434 CHARPOS (pos) += 1;
1435 BYTEPOS (pos) += len;
1436 }
1437 }
1438 else
1439 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1440
1441 return pos;
1442 }
1443
1444
1445 /* Value is the text position, i.e. character and byte position,
1446 for character position CHARPOS in STRING. */
1447
1448 static INLINE struct text_pos
1449 string_pos (charpos, string)
1450 int charpos;
1451 Lisp_Object string;
1452 {
1453 struct text_pos pos;
1454 xassert (STRINGP (string));
1455 xassert (charpos >= 0);
1456 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1457 return pos;
1458 }
1459
1460
1461 /* Value is a text position, i.e. character and byte position, for
1462 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1463 means recognize multibyte characters. */
1464
1465 static struct text_pos
1466 c_string_pos (charpos, s, multibyte_p)
1467 int charpos;
1468 unsigned char *s;
1469 int multibyte_p;
1470 {
1471 struct text_pos pos;
1472
1473 xassert (s != NULL);
1474 xassert (charpos >= 0);
1475
1476 if (multibyte_p)
1477 {
1478 int rest = strlen (s), len;
1479
1480 SET_TEXT_POS (pos, 0, 0);
1481 while (charpos--)
1482 {
1483 string_char_and_length (s, rest, &len);
1484 s += len, rest -= len;
1485 xassert (rest >= 0);
1486 CHARPOS (pos) += 1;
1487 BYTEPOS (pos) += len;
1488 }
1489 }
1490 else
1491 SET_TEXT_POS (pos, charpos, charpos);
1492
1493 return pos;
1494 }
1495
1496
1497 /* Value is the number of characters in C string S. MULTIBYTE_P
1498 non-zero means recognize multibyte characters. */
1499
1500 static int
1501 number_of_chars (s, multibyte_p)
1502 unsigned char *s;
1503 int multibyte_p;
1504 {
1505 int nchars;
1506
1507 if (multibyte_p)
1508 {
1509 int rest = strlen (s), len;
1510 unsigned char *p = (unsigned char *) s;
1511
1512 for (nchars = 0; rest > 0; ++nchars)
1513 {
1514 string_char_and_length (p, rest, &len);
1515 rest -= len, p += len;
1516 }
1517 }
1518 else
1519 nchars = strlen (s);
1520
1521 return nchars;
1522 }
1523
1524
1525 /* Compute byte position NEWPOS->bytepos corresponding to
1526 NEWPOS->charpos. POS is a known position in string STRING.
1527 NEWPOS->charpos must be >= POS.charpos. */
1528
1529 static void
1530 compute_string_pos (newpos, pos, string)
1531 struct text_pos *newpos, pos;
1532 Lisp_Object string;
1533 {
1534 xassert (STRINGP (string));
1535 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1536
1537 if (STRING_MULTIBYTE (string))
1538 *newpos = string_pos_nchars_ahead (pos, string,
1539 CHARPOS (*newpos) - CHARPOS (pos));
1540 else
1541 BYTEPOS (*newpos) = CHARPOS (*newpos);
1542 }
1543
1544 /* EXPORT:
1545 Return an estimation of the pixel height of mode or top lines on
1546 frame F. FACE_ID specifies what line's height to estimate. */
1547
1548 int
1549 estimate_mode_line_height (f, face_id)
1550 struct frame *f;
1551 enum face_id face_id;
1552 {
1553 #ifdef HAVE_WINDOW_SYSTEM
1554 if (FRAME_WINDOW_P (f))
1555 {
1556 int height = FONT_HEIGHT (FRAME_FONT (f));
1557
1558 /* This function is called so early when Emacs starts that the face
1559 cache and mode line face are not yet initialized. */
1560 if (FRAME_FACE_CACHE (f))
1561 {
1562 struct face *face = FACE_FROM_ID (f, face_id);
1563 if (face)
1564 {
1565 if (face->font)
1566 height = FONT_HEIGHT (face->font);
1567 if (face->box_line_width > 0)
1568 height += 2 * face->box_line_width;
1569 }
1570 }
1571
1572 return height;
1573 }
1574 #endif
1575
1576 return 1;
1577 }
1578
1579 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1580 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1581 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1582 not force the value into range. */
1583
1584 void
1585 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1586 FRAME_PTR f;
1587 register int pix_x, pix_y;
1588 int *x, *y;
1589 NativeRectangle *bounds;
1590 int noclip;
1591 {
1592
1593 #ifdef HAVE_WINDOW_SYSTEM
1594 if (FRAME_WINDOW_P (f))
1595 {
1596 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1597 even for negative values. */
1598 if (pix_x < 0)
1599 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1600 if (pix_y < 0)
1601 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1602
1603 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1604 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1605
1606 if (bounds)
1607 STORE_NATIVE_RECT (*bounds,
1608 FRAME_COL_TO_PIXEL_X (f, pix_x),
1609 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1610 FRAME_COLUMN_WIDTH (f) - 1,
1611 FRAME_LINE_HEIGHT (f) - 1);
1612
1613 if (!noclip)
1614 {
1615 if (pix_x < 0)
1616 pix_x = 0;
1617 else if (pix_x > FRAME_TOTAL_COLS (f))
1618 pix_x = FRAME_TOTAL_COLS (f);
1619
1620 if (pix_y < 0)
1621 pix_y = 0;
1622 else if (pix_y > FRAME_LINES (f))
1623 pix_y = FRAME_LINES (f);
1624 }
1625 }
1626 #endif
1627
1628 *x = pix_x;
1629 *y = pix_y;
1630 }
1631
1632
1633 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1634 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1635 can't tell the positions because W's display is not up to date,
1636 return 0. */
1637
1638 int
1639 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1640 struct window *w;
1641 int hpos, vpos;
1642 int *frame_x, *frame_y;
1643 {
1644 #ifdef HAVE_WINDOW_SYSTEM
1645 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1646 {
1647 int success_p;
1648
1649 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1650 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1651
1652 if (display_completed)
1653 {
1654 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1655 struct glyph *glyph = row->glyphs[TEXT_AREA];
1656 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1657
1658 hpos = row->x;
1659 vpos = row->y;
1660 while (glyph < end)
1661 {
1662 hpos += glyph->pixel_width;
1663 ++glyph;
1664 }
1665
1666 /* If first glyph is partially visible, its first visible position is still 0. */
1667 if (hpos < 0)
1668 hpos = 0;
1669
1670 success_p = 1;
1671 }
1672 else
1673 {
1674 hpos = vpos = 0;
1675 success_p = 0;
1676 }
1677
1678 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1679 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1680 return success_p;
1681 }
1682 #endif
1683
1684 *frame_x = hpos;
1685 *frame_y = vpos;
1686 return 1;
1687 }
1688
1689
1690 #ifdef HAVE_WINDOW_SYSTEM
1691
1692 /* Find the glyph under window-relative coordinates X/Y in window W.
1693 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1694 strings. Return in *HPOS and *VPOS the row and column number of
1695 the glyph found. Return in *AREA the glyph area containing X.
1696 Value is a pointer to the glyph found or null if X/Y is not on
1697 text, or we can't tell because W's current matrix is not up to
1698 date. */
1699
1700 static struct glyph *
1701 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1702 struct window *w;
1703 int x, y;
1704 int *hpos, *vpos, *dx, *dy, *area;
1705 {
1706 struct glyph *glyph, *end;
1707 struct glyph_row *row = NULL;
1708 int x0, i;
1709
1710 /* Find row containing Y. Give up if some row is not enabled. */
1711 for (i = 0; i < w->current_matrix->nrows; ++i)
1712 {
1713 row = MATRIX_ROW (w->current_matrix, i);
1714 if (!row->enabled_p)
1715 return NULL;
1716 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1717 break;
1718 }
1719
1720 *vpos = i;
1721 *hpos = 0;
1722
1723 /* Give up if Y is not in the window. */
1724 if (i == w->current_matrix->nrows)
1725 return NULL;
1726
1727 /* Get the glyph area containing X. */
1728 if (w->pseudo_window_p)
1729 {
1730 *area = TEXT_AREA;
1731 x0 = 0;
1732 }
1733 else
1734 {
1735 if (x < window_box_left_offset (w, TEXT_AREA))
1736 {
1737 *area = LEFT_MARGIN_AREA;
1738 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1739 }
1740 else if (x < window_box_right_offset (w, TEXT_AREA))
1741 {
1742 *area = TEXT_AREA;
1743 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1744 }
1745 else
1746 {
1747 *area = RIGHT_MARGIN_AREA;
1748 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1749 }
1750 }
1751
1752 /* Find glyph containing X. */
1753 glyph = row->glyphs[*area];
1754 end = glyph + row->used[*area];
1755 x -= x0;
1756 while (glyph < end && x >= glyph->pixel_width)
1757 {
1758 x -= glyph->pixel_width;
1759 ++glyph;
1760 }
1761
1762 if (glyph == end)
1763 return NULL;
1764
1765 if (dx)
1766 {
1767 *dx = x;
1768 *dy = y - (row->y + row->ascent - glyph->ascent);
1769 }
1770
1771 *hpos = glyph - row->glyphs[*area];
1772 return glyph;
1773 }
1774
1775
1776 /* EXPORT:
1777 Convert frame-relative x/y to coordinates relative to window W.
1778 Takes pseudo-windows into account. */
1779
1780 void
1781 frame_to_window_pixel_xy (w, x, y)
1782 struct window *w;
1783 int *x, *y;
1784 {
1785 if (w->pseudo_window_p)
1786 {
1787 /* A pseudo-window is always full-width, and starts at the
1788 left edge of the frame, plus a frame border. */
1789 struct frame *f = XFRAME (w->frame);
1790 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1791 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1792 }
1793 else
1794 {
1795 *x -= WINDOW_LEFT_EDGE_X (w);
1796 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1797 }
1798 }
1799
1800 /* EXPORT:
1801 Return in RECTS[] at most N clipping rectangles for glyph string S.
1802 Return the number of stored rectangles. */
1803
1804 int
1805 get_glyph_string_clip_rects (s, rects, n)
1806 struct glyph_string *s;
1807 NativeRectangle *rects;
1808 int n;
1809 {
1810 XRectangle r;
1811
1812 if (n <= 0)
1813 return 0;
1814
1815 if (s->row->full_width_p)
1816 {
1817 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1818 r.x = WINDOW_LEFT_EDGE_X (s->w);
1819 r.width = WINDOW_TOTAL_WIDTH (s->w);
1820
1821 /* Unless displaying a mode or menu bar line, which are always
1822 fully visible, clip to the visible part of the row. */
1823 if (s->w->pseudo_window_p)
1824 r.height = s->row->visible_height;
1825 else
1826 r.height = s->height;
1827 }
1828 else
1829 {
1830 /* This is a text line that may be partially visible. */
1831 r.x = window_box_left (s->w, s->area);
1832 r.width = window_box_width (s->w, s->area);
1833 r.height = s->row->visible_height;
1834 }
1835
1836 if (s->clip_head)
1837 if (r.x < s->clip_head->x)
1838 {
1839 if (r.width >= s->clip_head->x - r.x)
1840 r.width -= s->clip_head->x - r.x;
1841 else
1842 r.width = 0;
1843 r.x = s->clip_head->x;
1844 }
1845 if (s->clip_tail)
1846 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1847 {
1848 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1849 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1850 else
1851 r.width = 0;
1852 }
1853
1854 /* If S draws overlapping rows, it's sufficient to use the top and
1855 bottom of the window for clipping because this glyph string
1856 intentionally draws over other lines. */
1857 if (s->for_overlaps)
1858 {
1859 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1860 r.height = window_text_bottom_y (s->w) - r.y;
1861
1862 /* Alas, the above simple strategy does not work for the
1863 environments with anti-aliased text: if the same text is
1864 drawn onto the same place multiple times, it gets thicker.
1865 If the overlap we are processing is for the erased cursor, we
1866 take the intersection with the rectagle of the cursor. */
1867 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1868 {
1869 XRectangle rc, r_save = r;
1870
1871 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1872 rc.y = s->w->phys_cursor.y;
1873 rc.width = s->w->phys_cursor_width;
1874 rc.height = s->w->phys_cursor_height;
1875
1876 x_intersect_rectangles (&r_save, &rc, &r);
1877 }
1878 }
1879 else
1880 {
1881 /* Don't use S->y for clipping because it doesn't take partially
1882 visible lines into account. For example, it can be negative for
1883 partially visible lines at the top of a window. */
1884 if (!s->row->full_width_p
1885 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1886 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1887 else
1888 r.y = max (0, s->row->y);
1889
1890 /* If drawing a tool-bar window, draw it over the internal border
1891 at the top of the window. */
1892 if (WINDOWP (s->f->tool_bar_window)
1893 && s->w == XWINDOW (s->f->tool_bar_window))
1894 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1895 }
1896
1897 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1898
1899 /* If drawing the cursor, don't let glyph draw outside its
1900 advertised boundaries. Cleartype does this under some circumstances. */
1901 if (s->hl == DRAW_CURSOR)
1902 {
1903 struct glyph *glyph = s->first_glyph;
1904 int height, max_y;
1905
1906 if (s->x > r.x)
1907 {
1908 r.width -= s->x - r.x;
1909 r.x = s->x;
1910 }
1911 r.width = min (r.width, glyph->pixel_width);
1912
1913 /* If r.y is below window bottom, ensure that we still see a cursor. */
1914 height = min (glyph->ascent + glyph->descent,
1915 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1916 max_y = window_text_bottom_y (s->w) - height;
1917 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1918 if (s->ybase - glyph->ascent > max_y)
1919 {
1920 r.y = max_y;
1921 r.height = height;
1922 }
1923 else
1924 {
1925 /* Don't draw cursor glyph taller than our actual glyph. */
1926 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1927 if (height < r.height)
1928 {
1929 max_y = r.y + r.height;
1930 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1931 r.height = min (max_y - r.y, height);
1932 }
1933 }
1934 }
1935
1936 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1937 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1938 {
1939 #ifdef CONVERT_FROM_XRECT
1940 CONVERT_FROM_XRECT (r, *rects);
1941 #else
1942 *rects = r;
1943 #endif
1944 return 1;
1945 }
1946 else
1947 {
1948 /* If we are processing overlapping and allowed to return
1949 multiple clipping rectangles, we exclude the row of the glyph
1950 string from the clipping rectangle. This is to avoid drawing
1951 the same text on the environment with anti-aliasing. */
1952 #ifdef CONVERT_FROM_XRECT
1953 XRectangle rs[2];
1954 #else
1955 XRectangle *rs = rects;
1956 #endif
1957 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1958
1959 if (s->for_overlaps & OVERLAPS_PRED)
1960 {
1961 rs[i] = r;
1962 if (r.y + r.height > row_y)
1963 {
1964 if (r.y < row_y)
1965 rs[i].height = row_y - r.y;
1966 else
1967 rs[i].height = 0;
1968 }
1969 i++;
1970 }
1971 if (s->for_overlaps & OVERLAPS_SUCC)
1972 {
1973 rs[i] = r;
1974 if (r.y < row_y + s->row->visible_height)
1975 {
1976 if (r.y + r.height > row_y + s->row->visible_height)
1977 {
1978 rs[i].y = row_y + s->row->visible_height;
1979 rs[i].height = r.y + r.height - rs[i].y;
1980 }
1981 else
1982 rs[i].height = 0;
1983 }
1984 i++;
1985 }
1986
1987 n = i;
1988 #ifdef CONVERT_FROM_XRECT
1989 for (i = 0; i < n; i++)
1990 CONVERT_FROM_XRECT (rs[i], rects[i]);
1991 #endif
1992 return n;
1993 }
1994 }
1995
1996 /* EXPORT:
1997 Return in *NR the clipping rectangle for glyph string S. */
1998
1999 void
2000 get_glyph_string_clip_rect (s, nr)
2001 struct glyph_string *s;
2002 NativeRectangle *nr;
2003 {
2004 get_glyph_string_clip_rects (s, nr, 1);
2005 }
2006
2007
2008 /* EXPORT:
2009 Return the position and height of the phys cursor in window W.
2010 Set w->phys_cursor_width to width of phys cursor.
2011 */
2012
2013 void
2014 get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
2015 struct window *w;
2016 struct glyph_row *row;
2017 struct glyph *glyph;
2018 int *xp, *yp, *heightp;
2019 {
2020 struct frame *f = XFRAME (WINDOW_FRAME (w));
2021 int x, y, wd, h, h0, y0;
2022
2023 /* Compute the width of the rectangle to draw. If on a stretch
2024 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2025 rectangle as wide as the glyph, but use a canonical character
2026 width instead. */
2027 wd = glyph->pixel_width - 1;
2028 #ifdef HAVE_NTGUI
2029 wd++; /* Why? */
2030 #endif
2031
2032 x = w->phys_cursor.x;
2033 if (x < 0)
2034 {
2035 wd += x;
2036 x = 0;
2037 }
2038
2039 if (glyph->type == STRETCH_GLYPH
2040 && !x_stretch_cursor_p)
2041 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2042 w->phys_cursor_width = wd;
2043
2044 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2045
2046 /* If y is below window bottom, ensure that we still see a cursor. */
2047 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2048
2049 h = max (h0, glyph->ascent + glyph->descent);
2050 h0 = min (h0, glyph->ascent + glyph->descent);
2051
2052 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2053 if (y < y0)
2054 {
2055 h = max (h - (y0 - y) + 1, h0);
2056 y = y0 - 1;
2057 }
2058 else
2059 {
2060 y0 = window_text_bottom_y (w) - h0;
2061 if (y > y0)
2062 {
2063 h += y - y0;
2064 y = y0;
2065 }
2066 }
2067
2068 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2069 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2070 *heightp = h;
2071 }
2072
2073 /*
2074 * Remember which glyph the mouse is over.
2075 */
2076
2077 void
2078 remember_mouse_glyph (f, gx, gy, rect)
2079 struct frame *f;
2080 int gx, gy;
2081 NativeRectangle *rect;
2082 {
2083 Lisp_Object window;
2084 struct window *w;
2085 struct glyph_row *r, *gr, *end_row;
2086 enum window_part part;
2087 enum glyph_row_area area;
2088 int x, y, width, height;
2089
2090 /* Try to determine frame pixel position and size of the glyph under
2091 frame pixel coordinates X/Y on frame F. */
2092
2093 window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0);
2094 if (NILP (window))
2095 {
2096 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2097 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2098 goto virtual_glyph;
2099 }
2100
2101 w = XWINDOW (window);
2102 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2103 height = WINDOW_FRAME_LINE_HEIGHT (w);
2104
2105 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2106 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2107
2108 if (w->pseudo_window_p)
2109 {
2110 area = TEXT_AREA;
2111 part = ON_MODE_LINE; /* Don't adjust margin. */
2112 goto text_glyph;
2113 }
2114
2115 switch (part)
2116 {
2117 case ON_LEFT_MARGIN:
2118 area = LEFT_MARGIN_AREA;
2119 goto text_glyph;
2120
2121 case ON_RIGHT_MARGIN:
2122 area = RIGHT_MARGIN_AREA;
2123 goto text_glyph;
2124
2125 case ON_HEADER_LINE:
2126 case ON_MODE_LINE:
2127 gr = (part == ON_HEADER_LINE
2128 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2129 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2130 gy = gr->y;
2131 area = TEXT_AREA;
2132 goto text_glyph_row_found;
2133
2134 case ON_TEXT:
2135 area = TEXT_AREA;
2136
2137 text_glyph:
2138 gr = 0; gy = 0;
2139 for (; r <= end_row && r->enabled_p; ++r)
2140 if (r->y + r->height > y)
2141 {
2142 gr = r; gy = r->y;
2143 break;
2144 }
2145
2146 text_glyph_row_found:
2147 if (gr && gy <= y)
2148 {
2149 struct glyph *g = gr->glyphs[area];
2150 struct glyph *end = g + gr->used[area];
2151
2152 height = gr->height;
2153 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2154 if (gx + g->pixel_width > x)
2155 break;
2156
2157 if (g < end)
2158 {
2159 if (g->type == IMAGE_GLYPH)
2160 {
2161 /* Don't remember when mouse is over image, as
2162 image may have hot-spots. */
2163 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2164 return;
2165 }
2166 width = g->pixel_width;
2167 }
2168 else
2169 {
2170 /* Use nominal char spacing at end of line. */
2171 x -= gx;
2172 gx += (x / width) * width;
2173 }
2174
2175 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2176 gx += window_box_left_offset (w, area);
2177 }
2178 else
2179 {
2180 /* Use nominal line height at end of window. */
2181 gx = (x / width) * width;
2182 y -= gy;
2183 gy += (y / height) * height;
2184 }
2185 break;
2186
2187 case ON_LEFT_FRINGE:
2188 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2189 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2190 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2191 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2192 goto row_glyph;
2193
2194 case ON_RIGHT_FRINGE:
2195 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2196 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2197 : window_box_right_offset (w, TEXT_AREA));
2198 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2199 goto row_glyph;
2200
2201 case ON_SCROLL_BAR:
2202 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2203 ? 0
2204 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2205 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2206 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2207 : 0)));
2208 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2209
2210 row_glyph:
2211 gr = 0, gy = 0;
2212 for (; r <= end_row && r->enabled_p; ++r)
2213 if (r->y + r->height > y)
2214 {
2215 gr = r; gy = r->y;
2216 break;
2217 }
2218
2219 if (gr && gy <= y)
2220 height = gr->height;
2221 else
2222 {
2223 /* Use nominal line height at end of window. */
2224 y -= gy;
2225 gy += (y / height) * height;
2226 }
2227 break;
2228
2229 default:
2230 ;
2231 virtual_glyph:
2232 /* If there is no glyph under the mouse, then we divide the screen
2233 into a grid of the smallest glyph in the frame, and use that
2234 as our "glyph". */
2235
2236 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2237 round down even for negative values. */
2238 if (gx < 0)
2239 gx -= width - 1;
2240 if (gy < 0)
2241 gy -= height - 1;
2242
2243 gx = (gx / width) * width;
2244 gy = (gy / height) * height;
2245
2246 goto store_rect;
2247 }
2248
2249 gx += WINDOW_LEFT_EDGE_X (w);
2250 gy += WINDOW_TOP_EDGE_Y (w);
2251
2252 store_rect:
2253 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2254
2255 /* Visible feedback for debugging. */
2256 #if 0
2257 #if HAVE_X_WINDOWS
2258 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2259 f->output_data.x->normal_gc,
2260 gx, gy, width, height);
2261 #endif
2262 #endif
2263 }
2264
2265
2266 #endif /* HAVE_WINDOW_SYSTEM */
2267
2268 \f
2269 /***********************************************************************
2270 Lisp form evaluation
2271 ***********************************************************************/
2272
2273 /* Error handler for safe_eval and safe_call. */
2274
2275 static Lisp_Object
2276 safe_eval_handler (arg)
2277 Lisp_Object arg;
2278 {
2279 add_to_log ("Error during redisplay: %s", arg, Qnil);
2280 return Qnil;
2281 }
2282
2283
2284 /* Evaluate SEXPR and return the result, or nil if something went
2285 wrong. Prevent redisplay during the evaluation. */
2286
2287 Lisp_Object
2288 safe_eval (sexpr)
2289 Lisp_Object sexpr;
2290 {
2291 Lisp_Object val;
2292
2293 if (inhibit_eval_during_redisplay)
2294 val = Qnil;
2295 else
2296 {
2297 int count = SPECPDL_INDEX ();
2298 struct gcpro gcpro1;
2299
2300 GCPRO1 (sexpr);
2301 specbind (Qinhibit_redisplay, Qt);
2302 /* Use Qt to ensure debugger does not run,
2303 so there is no possibility of wanting to redisplay. */
2304 val = internal_condition_case_1 (Feval, sexpr, Qt,
2305 safe_eval_handler);
2306 UNGCPRO;
2307 val = unbind_to (count, val);
2308 }
2309
2310 return val;
2311 }
2312
2313
2314 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2315 Return the result, or nil if something went wrong. Prevent
2316 redisplay during the evaluation. */
2317
2318 Lisp_Object
2319 safe_call (nargs, args)
2320 int nargs;
2321 Lisp_Object *args;
2322 {
2323 Lisp_Object val;
2324
2325 if (inhibit_eval_during_redisplay)
2326 val = Qnil;
2327 else
2328 {
2329 int count = SPECPDL_INDEX ();
2330 struct gcpro gcpro1;
2331
2332 GCPRO1 (args[0]);
2333 gcpro1.nvars = nargs;
2334 specbind (Qinhibit_redisplay, Qt);
2335 /* Use Qt to ensure debugger does not run,
2336 so there is no possibility of wanting to redisplay. */
2337 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2338 safe_eval_handler);
2339 UNGCPRO;
2340 val = unbind_to (count, val);
2341 }
2342
2343 return val;
2344 }
2345
2346
2347 /* Call function FN with one argument ARG.
2348 Return the result, or nil if something went wrong. */
2349
2350 Lisp_Object
2351 safe_call1 (fn, arg)
2352 Lisp_Object fn, arg;
2353 {
2354 Lisp_Object args[2];
2355 args[0] = fn;
2356 args[1] = arg;
2357 return safe_call (2, args);
2358 }
2359
2360
2361 \f
2362 /***********************************************************************
2363 Debugging
2364 ***********************************************************************/
2365
2366 #if 0
2367
2368 /* Define CHECK_IT to perform sanity checks on iterators.
2369 This is for debugging. It is too slow to do unconditionally. */
2370
2371 static void
2372 check_it (it)
2373 struct it *it;
2374 {
2375 if (it->method == GET_FROM_STRING)
2376 {
2377 xassert (STRINGP (it->string));
2378 xassert (IT_STRING_CHARPOS (*it) >= 0);
2379 }
2380 else
2381 {
2382 xassert (IT_STRING_CHARPOS (*it) < 0);
2383 if (it->method == GET_FROM_BUFFER)
2384 {
2385 /* Check that character and byte positions agree. */
2386 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2387 }
2388 }
2389
2390 if (it->dpvec)
2391 xassert (it->current.dpvec_index >= 0);
2392 else
2393 xassert (it->current.dpvec_index < 0);
2394 }
2395
2396 #define CHECK_IT(IT) check_it ((IT))
2397
2398 #else /* not 0 */
2399
2400 #define CHECK_IT(IT) (void) 0
2401
2402 #endif /* not 0 */
2403
2404
2405 #if GLYPH_DEBUG
2406
2407 /* Check that the window end of window W is what we expect it
2408 to be---the last row in the current matrix displaying text. */
2409
2410 static void
2411 check_window_end (w)
2412 struct window *w;
2413 {
2414 if (!MINI_WINDOW_P (w)
2415 && !NILP (w->window_end_valid))
2416 {
2417 struct glyph_row *row;
2418 xassert ((row = MATRIX_ROW (w->current_matrix,
2419 XFASTINT (w->window_end_vpos)),
2420 !row->enabled_p
2421 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2422 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2423 }
2424 }
2425
2426 #define CHECK_WINDOW_END(W) check_window_end ((W))
2427
2428 #else /* not GLYPH_DEBUG */
2429
2430 #define CHECK_WINDOW_END(W) (void) 0
2431
2432 #endif /* not GLYPH_DEBUG */
2433
2434
2435 \f
2436 /***********************************************************************
2437 Iterator initialization
2438 ***********************************************************************/
2439
2440 /* Initialize IT for displaying current_buffer in window W, starting
2441 at character position CHARPOS. CHARPOS < 0 means that no buffer
2442 position is specified which is useful when the iterator is assigned
2443 a position later. BYTEPOS is the byte position corresponding to
2444 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2445
2446 If ROW is not null, calls to produce_glyphs with IT as parameter
2447 will produce glyphs in that row.
2448
2449 BASE_FACE_ID is the id of a base face to use. It must be one of
2450 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2451 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2452 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2453
2454 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2455 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2456 will be initialized to use the corresponding mode line glyph row of
2457 the desired matrix of W. */
2458
2459 void
2460 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2461 struct it *it;
2462 struct window *w;
2463 int charpos, bytepos;
2464 struct glyph_row *row;
2465 enum face_id base_face_id;
2466 {
2467 int highlight_region_p;
2468
2469 /* Some precondition checks. */
2470 xassert (w != NULL && it != NULL);
2471 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2472 && charpos <= ZV));
2473
2474 /* If face attributes have been changed since the last redisplay,
2475 free realized faces now because they depend on face definitions
2476 that might have changed. Don't free faces while there might be
2477 desired matrices pending which reference these faces. */
2478 if (face_change_count && !inhibit_free_realized_faces)
2479 {
2480 face_change_count = 0;
2481 free_all_realized_faces (Qnil);
2482 }
2483
2484 /* Use one of the mode line rows of W's desired matrix if
2485 appropriate. */
2486 if (row == NULL)
2487 {
2488 if (base_face_id == MODE_LINE_FACE_ID
2489 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2490 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2491 else if (base_face_id == HEADER_LINE_FACE_ID)
2492 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2493 }
2494
2495 /* Clear IT. */
2496 bzero (it, sizeof *it);
2497 it->current.overlay_string_index = -1;
2498 it->current.dpvec_index = -1;
2499 it->base_face_id = base_face_id;
2500 it->string = Qnil;
2501 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2502
2503 /* The window in which we iterate over current_buffer: */
2504 XSETWINDOW (it->window, w);
2505 it->w = w;
2506 it->f = XFRAME (w->frame);
2507
2508 /* Extra space between lines (on window systems only). */
2509 if (base_face_id == DEFAULT_FACE_ID
2510 && FRAME_WINDOW_P (it->f))
2511 {
2512 if (NATNUMP (current_buffer->extra_line_spacing))
2513 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2514 else if (FLOATP (current_buffer->extra_line_spacing))
2515 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2516 * FRAME_LINE_HEIGHT (it->f));
2517 else if (it->f->extra_line_spacing > 0)
2518 it->extra_line_spacing = it->f->extra_line_spacing;
2519 it->max_extra_line_spacing = 0;
2520 }
2521
2522 /* If realized faces have been removed, e.g. because of face
2523 attribute changes of named faces, recompute them. When running
2524 in batch mode, the face cache of Vterminal_frame is null. If
2525 we happen to get called, make a dummy face cache. */
2526 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2527 init_frame_faces (it->f);
2528 if (FRAME_FACE_CACHE (it->f)->used == 0)
2529 recompute_basic_faces (it->f);
2530
2531 /* Current value of the `slice', `space-width', and 'height' properties. */
2532 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2533 it->space_width = Qnil;
2534 it->font_height = Qnil;
2535 it->override_ascent = -1;
2536
2537 /* Are control characters displayed as `^C'? */
2538 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2539
2540 /* -1 means everything between a CR and the following line end
2541 is invisible. >0 means lines indented more than this value are
2542 invisible. */
2543 it->selective = (INTEGERP (current_buffer->selective_display)
2544 ? XFASTINT (current_buffer->selective_display)
2545 : (!NILP (current_buffer->selective_display)
2546 ? -1 : 0));
2547 it->selective_display_ellipsis_p
2548 = !NILP (current_buffer->selective_display_ellipses);
2549
2550 /* Display table to use. */
2551 it->dp = window_display_table (w);
2552
2553 /* Are multibyte characters enabled in current_buffer? */
2554 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2555
2556 /* Non-zero if we should highlight the region. */
2557 highlight_region_p
2558 = (!NILP (Vtransient_mark_mode)
2559 && !NILP (current_buffer->mark_active)
2560 && XMARKER (current_buffer->mark)->buffer != 0);
2561
2562 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2563 start and end of a visible region in window IT->w. Set both to
2564 -1 to indicate no region. */
2565 if (highlight_region_p
2566 /* Maybe highlight only in selected window. */
2567 && (/* Either show region everywhere. */
2568 highlight_nonselected_windows
2569 /* Or show region in the selected window. */
2570 || w == XWINDOW (selected_window)
2571 /* Or show the region if we are in the mini-buffer and W is
2572 the window the mini-buffer refers to. */
2573 || (MINI_WINDOW_P (XWINDOW (selected_window))
2574 && WINDOWP (minibuf_selected_window)
2575 && w == XWINDOW (minibuf_selected_window))))
2576 {
2577 int charpos = marker_position (current_buffer->mark);
2578 it->region_beg_charpos = min (PT, charpos);
2579 it->region_end_charpos = max (PT, charpos);
2580 }
2581 else
2582 it->region_beg_charpos = it->region_end_charpos = -1;
2583
2584 /* Get the position at which the redisplay_end_trigger hook should
2585 be run, if it is to be run at all. */
2586 if (MARKERP (w->redisplay_end_trigger)
2587 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2588 it->redisplay_end_trigger_charpos
2589 = marker_position (w->redisplay_end_trigger);
2590 else if (INTEGERP (w->redisplay_end_trigger))
2591 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2592
2593 /* Correct bogus values of tab_width. */
2594 it->tab_width = XINT (current_buffer->tab_width);
2595 if (it->tab_width <= 0 || it->tab_width > 1000)
2596 it->tab_width = 8;
2597
2598 /* Are lines in the display truncated? */
2599 it->truncate_lines_p
2600 = (base_face_id != DEFAULT_FACE_ID
2601 || XINT (it->w->hscroll)
2602 || (truncate_partial_width_windows
2603 && !WINDOW_FULL_WIDTH_P (it->w))
2604 || !NILP (current_buffer->truncate_lines));
2605
2606 /* Get dimensions of truncation and continuation glyphs. These are
2607 displayed as fringe bitmaps under X, so we don't need them for such
2608 frames. */
2609 if (!FRAME_WINDOW_P (it->f))
2610 {
2611 if (it->truncate_lines_p)
2612 {
2613 /* We will need the truncation glyph. */
2614 xassert (it->glyph_row == NULL);
2615 produce_special_glyphs (it, IT_TRUNCATION);
2616 it->truncation_pixel_width = it->pixel_width;
2617 }
2618 else
2619 {
2620 /* We will need the continuation glyph. */
2621 xassert (it->glyph_row == NULL);
2622 produce_special_glyphs (it, IT_CONTINUATION);
2623 it->continuation_pixel_width = it->pixel_width;
2624 }
2625
2626 /* Reset these values to zero because the produce_special_glyphs
2627 above has changed them. */
2628 it->pixel_width = it->ascent = it->descent = 0;
2629 it->phys_ascent = it->phys_descent = 0;
2630 }
2631
2632 /* Set this after getting the dimensions of truncation and
2633 continuation glyphs, so that we don't produce glyphs when calling
2634 produce_special_glyphs, above. */
2635 it->glyph_row = row;
2636 it->area = TEXT_AREA;
2637
2638 /* Get the dimensions of the display area. The display area
2639 consists of the visible window area plus a horizontally scrolled
2640 part to the left of the window. All x-values are relative to the
2641 start of this total display area. */
2642 if (base_face_id != DEFAULT_FACE_ID)
2643 {
2644 /* Mode lines, menu bar in terminal frames. */
2645 it->first_visible_x = 0;
2646 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2647 }
2648 else
2649 {
2650 it->first_visible_x
2651 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2652 it->last_visible_x = (it->first_visible_x
2653 + window_box_width (w, TEXT_AREA));
2654
2655 /* If we truncate lines, leave room for the truncator glyph(s) at
2656 the right margin. Otherwise, leave room for the continuation
2657 glyph(s). Truncation and continuation glyphs are not inserted
2658 for window-based redisplay. */
2659 if (!FRAME_WINDOW_P (it->f))
2660 {
2661 if (it->truncate_lines_p)
2662 it->last_visible_x -= it->truncation_pixel_width;
2663 else
2664 it->last_visible_x -= it->continuation_pixel_width;
2665 }
2666
2667 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2668 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2669 }
2670
2671 /* Leave room for a border glyph. */
2672 if (!FRAME_WINDOW_P (it->f)
2673 && !WINDOW_RIGHTMOST_P (it->w))
2674 it->last_visible_x -= 1;
2675
2676 it->last_visible_y = window_text_bottom_y (w);
2677
2678 /* For mode lines and alike, arrange for the first glyph having a
2679 left box line if the face specifies a box. */
2680 if (base_face_id != DEFAULT_FACE_ID)
2681 {
2682 struct face *face;
2683
2684 it->face_id = base_face_id;
2685
2686 /* If we have a boxed mode line, make the first character appear
2687 with a left box line. */
2688 face = FACE_FROM_ID (it->f, base_face_id);
2689 if (face->box != FACE_NO_BOX)
2690 it->start_of_box_run_p = 1;
2691 }
2692
2693 /* If a buffer position was specified, set the iterator there,
2694 getting overlays and face properties from that position. */
2695 if (charpos >= BUF_BEG (current_buffer))
2696 {
2697 it->end_charpos = ZV;
2698 it->face_id = -1;
2699 IT_CHARPOS (*it) = charpos;
2700
2701 /* Compute byte position if not specified. */
2702 if (bytepos < charpos)
2703 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2704 else
2705 IT_BYTEPOS (*it) = bytepos;
2706
2707 it->start = it->current;
2708
2709 /* Compute faces etc. */
2710 reseat (it, it->current.pos, 1);
2711 }
2712
2713 CHECK_IT (it);
2714 }
2715
2716
2717 /* Initialize IT for the display of window W with window start POS. */
2718
2719 void
2720 start_display (it, w, pos)
2721 struct it *it;
2722 struct window *w;
2723 struct text_pos pos;
2724 {
2725 struct glyph_row *row;
2726 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2727
2728 row = w->desired_matrix->rows + first_vpos;
2729 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2730 it->first_vpos = first_vpos;
2731
2732 /* Don't reseat to previous visible line start if current start
2733 position is in a string or image. */
2734 if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p)
2735 {
2736 int start_at_line_beg_p;
2737 int first_y = it->current_y;
2738
2739 /* If window start is not at a line start, skip forward to POS to
2740 get the correct continuation lines width. */
2741 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2742 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2743 if (!start_at_line_beg_p)
2744 {
2745 int new_x;
2746
2747 reseat_at_previous_visible_line_start (it);
2748 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2749
2750 new_x = it->current_x + it->pixel_width;
2751
2752 /* If lines are continued, this line may end in the middle
2753 of a multi-glyph character (e.g. a control character
2754 displayed as \003, or in the middle of an overlay
2755 string). In this case move_it_to above will not have
2756 taken us to the start of the continuation line but to the
2757 end of the continued line. */
2758 if (it->current_x > 0
2759 && !it->truncate_lines_p /* Lines are continued. */
2760 && (/* And glyph doesn't fit on the line. */
2761 new_x > it->last_visible_x
2762 /* Or it fits exactly and we're on a window
2763 system frame. */
2764 || (new_x == it->last_visible_x
2765 && FRAME_WINDOW_P (it->f))))
2766 {
2767 if (it->current.dpvec_index >= 0
2768 || it->current.overlay_string_index >= 0)
2769 {
2770 set_iterator_to_next (it, 1);
2771 move_it_in_display_line_to (it, -1, -1, 0);
2772 }
2773
2774 it->continuation_lines_width += it->current_x;
2775 }
2776
2777 /* We're starting a new display line, not affected by the
2778 height of the continued line, so clear the appropriate
2779 fields in the iterator structure. */
2780 it->max_ascent = it->max_descent = 0;
2781 it->max_phys_ascent = it->max_phys_descent = 0;
2782
2783 it->current_y = first_y;
2784 it->vpos = 0;
2785 it->current_x = it->hpos = 0;
2786 }
2787 }
2788
2789 #if 0 /* Don't assert the following because start_display is sometimes
2790 called intentionally with a window start that is not at a
2791 line start. Please leave this code in as a comment. */
2792
2793 /* Window start should be on a line start, now. */
2794 xassert (it->continuation_lines_width
2795 || IT_CHARPOS (it) == BEGV
2796 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2797 #endif /* 0 */
2798 }
2799
2800
2801 /* Return 1 if POS is a position in ellipses displayed for invisible
2802 text. W is the window we display, for text property lookup. */
2803
2804 static int
2805 in_ellipses_for_invisible_text_p (pos, w)
2806 struct display_pos *pos;
2807 struct window *w;
2808 {
2809 Lisp_Object prop, window;
2810 int ellipses_p = 0;
2811 int charpos = CHARPOS (pos->pos);
2812
2813 /* If POS specifies a position in a display vector, this might
2814 be for an ellipsis displayed for invisible text. We won't
2815 get the iterator set up for delivering that ellipsis unless
2816 we make sure that it gets aware of the invisible text. */
2817 if (pos->dpvec_index >= 0
2818 && pos->overlay_string_index < 0
2819 && CHARPOS (pos->string_pos) < 0
2820 && charpos > BEGV
2821 && (XSETWINDOW (window, w),
2822 prop = Fget_char_property (make_number (charpos),
2823 Qinvisible, window),
2824 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2825 {
2826 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2827 window);
2828 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2829 }
2830
2831 return ellipses_p;
2832 }
2833
2834
2835 /* Initialize IT for stepping through current_buffer in window W,
2836 starting at position POS that includes overlay string and display
2837 vector/ control character translation position information. Value
2838 is zero if there are overlay strings with newlines at POS. */
2839
2840 static int
2841 init_from_display_pos (it, w, pos)
2842 struct it *it;
2843 struct window *w;
2844 struct display_pos *pos;
2845 {
2846 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2847 int i, overlay_strings_with_newlines = 0;
2848
2849 /* If POS specifies a position in a display vector, this might
2850 be for an ellipsis displayed for invisible text. We won't
2851 get the iterator set up for delivering that ellipsis unless
2852 we make sure that it gets aware of the invisible text. */
2853 if (in_ellipses_for_invisible_text_p (pos, w))
2854 {
2855 --charpos;
2856 bytepos = 0;
2857 }
2858
2859 /* Keep in mind: the call to reseat in init_iterator skips invisible
2860 text, so we might end up at a position different from POS. This
2861 is only a problem when POS is a row start after a newline and an
2862 overlay starts there with an after-string, and the overlay has an
2863 invisible property. Since we don't skip invisible text in
2864 display_line and elsewhere immediately after consuming the
2865 newline before the row start, such a POS will not be in a string,
2866 but the call to init_iterator below will move us to the
2867 after-string. */
2868 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2869
2870 /* This only scans the current chunk -- it should scan all chunks.
2871 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2872 to 16 in 22.1 to make this a lesser problem. */
2873 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2874 {
2875 const char *s = SDATA (it->overlay_strings[i]);
2876 const char *e = s + SBYTES (it->overlay_strings[i]);
2877
2878 while (s < e && *s != '\n')
2879 ++s;
2880
2881 if (s < e)
2882 {
2883 overlay_strings_with_newlines = 1;
2884 break;
2885 }
2886 }
2887
2888 /* If position is within an overlay string, set up IT to the right
2889 overlay string. */
2890 if (pos->overlay_string_index >= 0)
2891 {
2892 int relative_index;
2893
2894 /* If the first overlay string happens to have a `display'
2895 property for an image, the iterator will be set up for that
2896 image, and we have to undo that setup first before we can
2897 correct the overlay string index. */
2898 if (it->method == GET_FROM_IMAGE)
2899 pop_it (it);
2900
2901 /* We already have the first chunk of overlay strings in
2902 IT->overlay_strings. Load more until the one for
2903 pos->overlay_string_index is in IT->overlay_strings. */
2904 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2905 {
2906 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2907 it->current.overlay_string_index = 0;
2908 while (n--)
2909 {
2910 load_overlay_strings (it, 0);
2911 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2912 }
2913 }
2914
2915 it->current.overlay_string_index = pos->overlay_string_index;
2916 relative_index = (it->current.overlay_string_index
2917 % OVERLAY_STRING_CHUNK_SIZE);
2918 it->string = it->overlay_strings[relative_index];
2919 xassert (STRINGP (it->string));
2920 it->current.string_pos = pos->string_pos;
2921 it->method = GET_FROM_STRING;
2922 }
2923
2924 #if 0 /* This is bogus because POS not having an overlay string
2925 position does not mean it's after the string. Example: A
2926 line starting with a before-string and initialization of IT
2927 to the previous row's end position. */
2928 else if (it->current.overlay_string_index >= 0)
2929 {
2930 /* If POS says we're already after an overlay string ending at
2931 POS, make sure to pop the iterator because it will be in
2932 front of that overlay string. When POS is ZV, we've thereby
2933 also ``processed'' overlay strings at ZV. */
2934 while (it->sp)
2935 pop_it (it);
2936 xassert (it->current.overlay_string_index == -1);
2937 xassert (it->method == GET_FROM_BUFFER);
2938 if (CHARPOS (pos->pos) == ZV)
2939 it->overlay_strings_at_end_processed_p = 1;
2940 }
2941 #endif /* 0 */
2942
2943 if (CHARPOS (pos->string_pos) >= 0)
2944 {
2945 /* Recorded position is not in an overlay string, but in another
2946 string. This can only be a string from a `display' property.
2947 IT should already be filled with that string. */
2948 it->current.string_pos = pos->string_pos;
2949 xassert (STRINGP (it->string));
2950 }
2951
2952 /* Restore position in display vector translations, control
2953 character translations or ellipses. */
2954 if (pos->dpvec_index >= 0)
2955 {
2956 if (it->dpvec == NULL)
2957 get_next_display_element (it);
2958 xassert (it->dpvec && it->current.dpvec_index == 0);
2959 it->current.dpvec_index = pos->dpvec_index;
2960 }
2961
2962 CHECK_IT (it);
2963 return !overlay_strings_with_newlines;
2964 }
2965
2966
2967 /* Initialize IT for stepping through current_buffer in window W
2968 starting at ROW->start. */
2969
2970 static void
2971 init_to_row_start (it, w, row)
2972 struct it *it;
2973 struct window *w;
2974 struct glyph_row *row;
2975 {
2976 init_from_display_pos (it, w, &row->start);
2977 it->start = row->start;
2978 it->continuation_lines_width = row->continuation_lines_width;
2979 CHECK_IT (it);
2980 }
2981
2982
2983 /* Initialize IT for stepping through current_buffer in window W
2984 starting in the line following ROW, i.e. starting at ROW->end.
2985 Value is zero if there are overlay strings with newlines at ROW's
2986 end position. */
2987
2988 static int
2989 init_to_row_end (it, w, row)
2990 struct it *it;
2991 struct window *w;
2992 struct glyph_row *row;
2993 {
2994 int success = 0;
2995
2996 if (init_from_display_pos (it, w, &row->end))
2997 {
2998 if (row->continued_p)
2999 it->continuation_lines_width
3000 = row->continuation_lines_width + row->pixel_width;
3001 CHECK_IT (it);
3002 success = 1;
3003 }
3004
3005 return success;
3006 }
3007
3008
3009
3010 \f
3011 /***********************************************************************
3012 Text properties
3013 ***********************************************************************/
3014
3015 /* Called when IT reaches IT->stop_charpos. Handle text property and
3016 overlay changes. Set IT->stop_charpos to the next position where
3017 to stop. */
3018
3019 static void
3020 handle_stop (it)
3021 struct it *it;
3022 {
3023 enum prop_handled handled;
3024 int handle_overlay_change_p;
3025 struct props *p;
3026
3027 it->dpvec = NULL;
3028 it->current.dpvec_index = -1;
3029 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3030 it->ignore_overlay_strings_at_pos_p = 0;
3031
3032 /* Use face of preceding text for ellipsis (if invisible) */
3033 if (it->selective_display_ellipsis_p)
3034 it->saved_face_id = it->face_id;
3035
3036 do
3037 {
3038 handled = HANDLED_NORMALLY;
3039
3040 /* Call text property handlers. */
3041 for (p = it_props; p->handler; ++p)
3042 {
3043 handled = p->handler (it);
3044
3045 if (handled == HANDLED_RECOMPUTE_PROPS)
3046 break;
3047 else if (handled == HANDLED_RETURN)
3048 {
3049 /* We still want to show before and after strings from
3050 overlays even if the actual buffer text is replaced. */
3051 if (!handle_overlay_change_p || it->sp > 1)
3052 return;
3053 if (!get_overlay_strings_1 (it, 0, 0))
3054 return;
3055 it->ignore_overlay_strings_at_pos_p = 1;
3056 it->string_from_display_prop_p = 0;
3057 handle_overlay_change_p = 0;
3058 handled = HANDLED_RECOMPUTE_PROPS;
3059 break;
3060 }
3061 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3062 handle_overlay_change_p = 0;
3063 }
3064
3065 if (handled != HANDLED_RECOMPUTE_PROPS)
3066 {
3067 /* Don't check for overlay strings below when set to deliver
3068 characters from a display vector. */
3069 if (it->method == GET_FROM_DISPLAY_VECTOR)
3070 handle_overlay_change_p = 0;
3071
3072 /* Handle overlay changes. */
3073 if (handle_overlay_change_p)
3074 handled = handle_overlay_change (it);
3075
3076 /* Determine where to stop next. */
3077 if (handled == HANDLED_NORMALLY)
3078 compute_stop_pos (it);
3079 }
3080 }
3081 while (handled == HANDLED_RECOMPUTE_PROPS);
3082 }
3083
3084
3085 /* Compute IT->stop_charpos from text property and overlay change
3086 information for IT's current position. */
3087
3088 static void
3089 compute_stop_pos (it)
3090 struct it *it;
3091 {
3092 register INTERVAL iv, next_iv;
3093 Lisp_Object object, limit, position;
3094
3095 /* If nowhere else, stop at the end. */
3096 it->stop_charpos = it->end_charpos;
3097
3098 if (STRINGP (it->string))
3099 {
3100 /* Strings are usually short, so don't limit the search for
3101 properties. */
3102 object = it->string;
3103 limit = Qnil;
3104 position = make_number (IT_STRING_CHARPOS (*it));
3105 }
3106 else
3107 {
3108 int charpos;
3109
3110 /* If next overlay change is in front of the current stop pos
3111 (which is IT->end_charpos), stop there. Note: value of
3112 next_overlay_change is point-max if no overlay change
3113 follows. */
3114 charpos = next_overlay_change (IT_CHARPOS (*it));
3115 if (charpos < it->stop_charpos)
3116 it->stop_charpos = charpos;
3117
3118 /* If showing the region, we have to stop at the region
3119 start or end because the face might change there. */
3120 if (it->region_beg_charpos > 0)
3121 {
3122 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3123 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3124 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3125 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3126 }
3127
3128 /* Set up variables for computing the stop position from text
3129 property changes. */
3130 XSETBUFFER (object, current_buffer);
3131 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3132 position = make_number (IT_CHARPOS (*it));
3133
3134 }
3135
3136 /* Get the interval containing IT's position. Value is a null
3137 interval if there isn't such an interval. */
3138 iv = validate_interval_range (object, &position, &position, 0);
3139 if (!NULL_INTERVAL_P (iv))
3140 {
3141 Lisp_Object values_here[LAST_PROP_IDX];
3142 struct props *p;
3143
3144 /* Get properties here. */
3145 for (p = it_props; p->handler; ++p)
3146 values_here[p->idx] = textget (iv->plist, *p->name);
3147
3148 /* Look for an interval following iv that has different
3149 properties. */
3150 for (next_iv = next_interval (iv);
3151 (!NULL_INTERVAL_P (next_iv)
3152 && (NILP (limit)
3153 || XFASTINT (limit) > next_iv->position));
3154 next_iv = next_interval (next_iv))
3155 {
3156 for (p = it_props; p->handler; ++p)
3157 {
3158 Lisp_Object new_value;
3159
3160 new_value = textget (next_iv->plist, *p->name);
3161 if (!EQ (values_here[p->idx], new_value))
3162 break;
3163 }
3164
3165 if (p->handler)
3166 break;
3167 }
3168
3169 if (!NULL_INTERVAL_P (next_iv))
3170 {
3171 if (INTEGERP (limit)
3172 && next_iv->position >= XFASTINT (limit))
3173 /* No text property change up to limit. */
3174 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3175 else
3176 /* Text properties change in next_iv. */
3177 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3178 }
3179 }
3180
3181 xassert (STRINGP (it->string)
3182 || (it->stop_charpos >= BEGV
3183 && it->stop_charpos >= IT_CHARPOS (*it)));
3184 }
3185
3186
3187 /* Return the position of the next overlay change after POS in
3188 current_buffer. Value is point-max if no overlay change
3189 follows. This is like `next-overlay-change' but doesn't use
3190 xmalloc. */
3191
3192 static int
3193 next_overlay_change (pos)
3194 int pos;
3195 {
3196 int noverlays;
3197 int endpos;
3198 Lisp_Object *overlays;
3199 int i;
3200
3201 /* Get all overlays at the given position. */
3202 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3203
3204 /* If any of these overlays ends before endpos,
3205 use its ending point instead. */
3206 for (i = 0; i < noverlays; ++i)
3207 {
3208 Lisp_Object oend;
3209 int oendpos;
3210
3211 oend = OVERLAY_END (overlays[i]);
3212 oendpos = OVERLAY_POSITION (oend);
3213 endpos = min (endpos, oendpos);
3214 }
3215
3216 return endpos;
3217 }
3218
3219
3220 \f
3221 /***********************************************************************
3222 Fontification
3223 ***********************************************************************/
3224
3225 /* Handle changes in the `fontified' property of the current buffer by
3226 calling hook functions from Qfontification_functions to fontify
3227 regions of text. */
3228
3229 static enum prop_handled
3230 handle_fontified_prop (it)
3231 struct it *it;
3232 {
3233 Lisp_Object prop, pos;
3234 enum prop_handled handled = HANDLED_NORMALLY;
3235
3236 if (!NILP (Vmemory_full))
3237 return handled;
3238
3239 /* Get the value of the `fontified' property at IT's current buffer
3240 position. (The `fontified' property doesn't have a special
3241 meaning in strings.) If the value is nil, call functions from
3242 Qfontification_functions. */
3243 if (!STRINGP (it->string)
3244 && it->s == NULL
3245 && !NILP (Vfontification_functions)
3246 && !NILP (Vrun_hooks)
3247 && (pos = make_number (IT_CHARPOS (*it)),
3248 prop = Fget_char_property (pos, Qfontified, Qnil),
3249 NILP (prop)))
3250 {
3251 int count = SPECPDL_INDEX ();
3252 Lisp_Object val;
3253
3254 val = Vfontification_functions;
3255 specbind (Qfontification_functions, Qnil);
3256
3257 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3258 safe_call1 (val, pos);
3259 else
3260 {
3261 Lisp_Object globals, fn;
3262 struct gcpro gcpro1, gcpro2;
3263
3264 globals = Qnil;
3265 GCPRO2 (val, globals);
3266
3267 for (; CONSP (val); val = XCDR (val))
3268 {
3269 fn = XCAR (val);
3270
3271 if (EQ (fn, Qt))
3272 {
3273 /* A value of t indicates this hook has a local
3274 binding; it means to run the global binding too.
3275 In a global value, t should not occur. If it
3276 does, we must ignore it to avoid an endless
3277 loop. */
3278 for (globals = Fdefault_value (Qfontification_functions);
3279 CONSP (globals);
3280 globals = XCDR (globals))
3281 {
3282 fn = XCAR (globals);
3283 if (!EQ (fn, Qt))
3284 safe_call1 (fn, pos);
3285 }
3286 }
3287 else
3288 safe_call1 (fn, pos);
3289 }
3290
3291 UNGCPRO;
3292 }
3293
3294 unbind_to (count, Qnil);
3295
3296 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3297 something. This avoids an endless loop if they failed to
3298 fontify the text for which reason ever. */
3299 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3300 handled = HANDLED_RECOMPUTE_PROPS;
3301 }
3302
3303 return handled;
3304 }
3305
3306
3307 \f
3308 /***********************************************************************
3309 Faces
3310 ***********************************************************************/
3311
3312 /* Set up iterator IT from face properties at its current position.
3313 Called from handle_stop. */
3314
3315 static enum prop_handled
3316 handle_face_prop (it)
3317 struct it *it;
3318 {
3319 int new_face_id, next_stop;
3320
3321 if (!STRINGP (it->string))
3322 {
3323 new_face_id
3324 = face_at_buffer_position (it->w,
3325 IT_CHARPOS (*it),
3326 it->region_beg_charpos,
3327 it->region_end_charpos,
3328 &next_stop,
3329 (IT_CHARPOS (*it)
3330 + TEXT_PROP_DISTANCE_LIMIT),
3331 0);
3332
3333 /* Is this a start of a run of characters with box face?
3334 Caveat: this can be called for a freshly initialized
3335 iterator; face_id is -1 in this case. We know that the new
3336 face will not change until limit, i.e. if the new face has a
3337 box, all characters up to limit will have one. But, as
3338 usual, we don't know whether limit is really the end. */
3339 if (new_face_id != it->face_id)
3340 {
3341 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3342
3343 /* If new face has a box but old face has not, this is
3344 the start of a run of characters with box, i.e. it has
3345 a shadow on the left side. The value of face_id of the
3346 iterator will be -1 if this is the initial call that gets
3347 the face. In this case, we have to look in front of IT's
3348 position and see whether there is a face != new_face_id. */
3349 it->start_of_box_run_p
3350 = (new_face->box != FACE_NO_BOX
3351 && (it->face_id >= 0
3352 || IT_CHARPOS (*it) == BEG
3353 || new_face_id != face_before_it_pos (it)));
3354 it->face_box_p = new_face->box != FACE_NO_BOX;
3355 }
3356 }
3357 else
3358 {
3359 int base_face_id, bufpos;
3360
3361 if (it->current.overlay_string_index >= 0)
3362 bufpos = IT_CHARPOS (*it);
3363 else
3364 bufpos = 0;
3365
3366 /* For strings from a buffer, i.e. overlay strings or strings
3367 from a `display' property, use the face at IT's current
3368 buffer position as the base face to merge with, so that
3369 overlay strings appear in the same face as surrounding
3370 text, unless they specify their own faces. */
3371 base_face_id = underlying_face_id (it);
3372
3373 new_face_id = face_at_string_position (it->w,
3374 it->string,
3375 IT_STRING_CHARPOS (*it),
3376 bufpos,
3377 it->region_beg_charpos,
3378 it->region_end_charpos,
3379 &next_stop,
3380 base_face_id, 0);
3381
3382 #if 0 /* This shouldn't be neccessary. Let's check it. */
3383 /* If IT is used to display a mode line we would really like to
3384 use the mode line face instead of the frame's default face. */
3385 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3386 && new_face_id == DEFAULT_FACE_ID)
3387 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3388 #endif
3389
3390 /* Is this a start of a run of characters with box? Caveat:
3391 this can be called for a freshly allocated iterator; face_id
3392 is -1 is this case. We know that the new face will not
3393 change until the next check pos, i.e. if the new face has a
3394 box, all characters up to that position will have a
3395 box. But, as usual, we don't know whether that position
3396 is really the end. */
3397 if (new_face_id != it->face_id)
3398 {
3399 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3400 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3401
3402 /* If new face has a box but old face hasn't, this is the
3403 start of a run of characters with box, i.e. it has a
3404 shadow on the left side. */
3405 it->start_of_box_run_p
3406 = new_face->box && (old_face == NULL || !old_face->box);
3407 it->face_box_p = new_face->box != FACE_NO_BOX;
3408 }
3409 }
3410
3411 it->face_id = new_face_id;
3412 return HANDLED_NORMALLY;
3413 }
3414
3415
3416 /* Return the ID of the face ``underlying'' IT's current position,
3417 which is in a string. If the iterator is associated with a
3418 buffer, return the face at IT's current buffer position.
3419 Otherwise, use the iterator's base_face_id. */
3420
3421 static int
3422 underlying_face_id (it)
3423 struct it *it;
3424 {
3425 int face_id = it->base_face_id, i;
3426
3427 xassert (STRINGP (it->string));
3428
3429 for (i = it->sp - 1; i >= 0; --i)
3430 if (NILP (it->stack[i].string))
3431 face_id = it->stack[i].face_id;
3432
3433 return face_id;
3434 }
3435
3436
3437 /* Compute the face one character before or after the current position
3438 of IT. BEFORE_P non-zero means get the face in front of IT's
3439 position. Value is the id of the face. */
3440
3441 static int
3442 face_before_or_after_it_pos (it, before_p)
3443 struct it *it;
3444 int before_p;
3445 {
3446 int face_id, limit;
3447 int next_check_charpos;
3448 struct text_pos pos;
3449
3450 xassert (it->s == NULL);
3451
3452 if (STRINGP (it->string))
3453 {
3454 int bufpos, base_face_id;
3455
3456 /* No face change past the end of the string (for the case
3457 we are padding with spaces). No face change before the
3458 string start. */
3459 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3460 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3461 return it->face_id;
3462
3463 /* Set pos to the position before or after IT's current position. */
3464 if (before_p)
3465 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3466 else
3467 /* For composition, we must check the character after the
3468 composition. */
3469 pos = (it->what == IT_COMPOSITION
3470 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3471 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3472
3473 if (it->current.overlay_string_index >= 0)
3474 bufpos = IT_CHARPOS (*it);
3475 else
3476 bufpos = 0;
3477
3478 base_face_id = underlying_face_id (it);
3479
3480 /* Get the face for ASCII, or unibyte. */
3481 face_id = face_at_string_position (it->w,
3482 it->string,
3483 CHARPOS (pos),
3484 bufpos,
3485 it->region_beg_charpos,
3486 it->region_end_charpos,
3487 &next_check_charpos,
3488 base_face_id, 0);
3489
3490 /* Correct the face for charsets different from ASCII. Do it
3491 for the multibyte case only. The face returned above is
3492 suitable for unibyte text if IT->string is unibyte. */
3493 if (STRING_MULTIBYTE (it->string))
3494 {
3495 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3496 int rest = SBYTES (it->string) - BYTEPOS (pos);
3497 int c, len;
3498 struct face *face = FACE_FROM_ID (it->f, face_id);
3499
3500 c = string_char_and_length (p, rest, &len);
3501 face_id = FACE_FOR_CHAR (it->f, face, c);
3502 }
3503 }
3504 else
3505 {
3506 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3507 || (IT_CHARPOS (*it) <= BEGV && before_p))
3508 return it->face_id;
3509
3510 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3511 pos = it->current.pos;
3512
3513 if (before_p)
3514 DEC_TEXT_POS (pos, it->multibyte_p);
3515 else
3516 {
3517 if (it->what == IT_COMPOSITION)
3518 /* For composition, we must check the position after the
3519 composition. */
3520 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3521 else
3522 INC_TEXT_POS (pos, it->multibyte_p);
3523 }
3524
3525 /* Determine face for CHARSET_ASCII, or unibyte. */
3526 face_id = face_at_buffer_position (it->w,
3527 CHARPOS (pos),
3528 it->region_beg_charpos,
3529 it->region_end_charpos,
3530 &next_check_charpos,
3531 limit, 0);
3532
3533 /* Correct the face for charsets different from ASCII. Do it
3534 for the multibyte case only. The face returned above is
3535 suitable for unibyte text if current_buffer is unibyte. */
3536 if (it->multibyte_p)
3537 {
3538 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3539 struct face *face = FACE_FROM_ID (it->f, face_id);
3540 face_id = FACE_FOR_CHAR (it->f, face, c);
3541 }
3542 }
3543
3544 return face_id;
3545 }
3546
3547
3548 \f
3549 /***********************************************************************
3550 Invisible text
3551 ***********************************************************************/
3552
3553 /* Set up iterator IT from invisible properties at its current
3554 position. Called from handle_stop. */
3555
3556 static enum prop_handled
3557 handle_invisible_prop (it)
3558 struct it *it;
3559 {
3560 enum prop_handled handled = HANDLED_NORMALLY;
3561
3562 if (STRINGP (it->string))
3563 {
3564 extern Lisp_Object Qinvisible;
3565 Lisp_Object prop, end_charpos, limit, charpos;
3566
3567 /* Get the value of the invisible text property at the
3568 current position. Value will be nil if there is no such
3569 property. */
3570 charpos = make_number (IT_STRING_CHARPOS (*it));
3571 prop = Fget_text_property (charpos, Qinvisible, it->string);
3572
3573 if (!NILP (prop)
3574 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3575 {
3576 handled = HANDLED_RECOMPUTE_PROPS;
3577
3578 /* Get the position at which the next change of the
3579 invisible text property can be found in IT->string.
3580 Value will be nil if the property value is the same for
3581 all the rest of IT->string. */
3582 XSETINT (limit, SCHARS (it->string));
3583 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3584 it->string, limit);
3585
3586 /* Text at current position is invisible. The next
3587 change in the property is at position end_charpos.
3588 Move IT's current position to that position. */
3589 if (INTEGERP (end_charpos)
3590 && XFASTINT (end_charpos) < XFASTINT (limit))
3591 {
3592 struct text_pos old;
3593 old = it->current.string_pos;
3594 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3595 compute_string_pos (&it->current.string_pos, old, it->string);
3596 }
3597 else
3598 {
3599 /* The rest of the string is invisible. If this is an
3600 overlay string, proceed with the next overlay string
3601 or whatever comes and return a character from there. */
3602 if (it->current.overlay_string_index >= 0)
3603 {
3604 next_overlay_string (it);
3605 /* Don't check for overlay strings when we just
3606 finished processing them. */
3607 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3608 }
3609 else
3610 {
3611 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3612 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3613 }
3614 }
3615 }
3616 }
3617 else
3618 {
3619 int invis_p, newpos, next_stop, start_charpos;
3620 Lisp_Object pos, prop, overlay;
3621
3622 /* First of all, is there invisible text at this position? */
3623 start_charpos = IT_CHARPOS (*it);
3624 pos = make_number (IT_CHARPOS (*it));
3625 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3626 &overlay);
3627 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3628
3629 /* If we are on invisible text, skip over it. */
3630 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3631 {
3632 /* Record whether we have to display an ellipsis for the
3633 invisible text. */
3634 int display_ellipsis_p = invis_p == 2;
3635
3636 handled = HANDLED_RECOMPUTE_PROPS;
3637
3638 /* Loop skipping over invisible text. The loop is left at
3639 ZV or with IT on the first char being visible again. */
3640 do
3641 {
3642 /* Try to skip some invisible text. Return value is the
3643 position reached which can be equal to IT's position
3644 if there is nothing invisible here. This skips both
3645 over invisible text properties and overlays with
3646 invisible property. */
3647 newpos = skip_invisible (IT_CHARPOS (*it),
3648 &next_stop, ZV, it->window);
3649
3650 /* If we skipped nothing at all we weren't at invisible
3651 text in the first place. If everything to the end of
3652 the buffer was skipped, end the loop. */
3653 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3654 invis_p = 0;
3655 else
3656 {
3657 /* We skipped some characters but not necessarily
3658 all there are. Check if we ended up on visible
3659 text. Fget_char_property returns the property of
3660 the char before the given position, i.e. if we
3661 get invis_p = 0, this means that the char at
3662 newpos is visible. */
3663 pos = make_number (newpos);
3664 prop = Fget_char_property (pos, Qinvisible, it->window);
3665 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3666 }
3667
3668 /* If we ended up on invisible text, proceed to
3669 skip starting with next_stop. */
3670 if (invis_p)
3671 IT_CHARPOS (*it) = next_stop;
3672
3673 /* If there are adjacent invisible texts, don't lose the
3674 second one's ellipsis. */
3675 if (invis_p == 2)
3676 display_ellipsis_p = 1;
3677 }
3678 while (invis_p);
3679
3680 /* The position newpos is now either ZV or on visible text. */
3681 IT_CHARPOS (*it) = newpos;
3682 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3683
3684 /* If there are before-strings at the start of invisible
3685 text, and the text is invisible because of a text
3686 property, arrange to show before-strings because 20.x did
3687 it that way. (If the text is invisible because of an
3688 overlay property instead of a text property, this is
3689 already handled in the overlay code.) */
3690 if (NILP (overlay)
3691 && get_overlay_strings (it, start_charpos))
3692 {
3693 handled = HANDLED_RECOMPUTE_PROPS;
3694 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3695 }
3696 else if (display_ellipsis_p)
3697 {
3698 /* Make sure that the glyphs of the ellipsis will get
3699 correct `charpos' values. If we would not update
3700 it->position here, the glyphs would belong to the
3701 last visible character _before_ the invisible
3702 text, which confuses `set_cursor_from_row'.
3703
3704 We use the last invisible position instead of the
3705 first because this way the cursor is always drawn on
3706 the first "." of the ellipsis, whenever PT is inside
3707 the invisible text. Otherwise the cursor would be
3708 placed _after_ the ellipsis when the point is after the
3709 first invisible character. */
3710 if (!STRINGP (it->object))
3711 {
3712 it->position.charpos = IT_CHARPOS (*it) - 1;
3713 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3714 }
3715 setup_for_ellipsis (it, 0);
3716 }
3717 }
3718 }
3719
3720 return handled;
3721 }
3722
3723
3724 /* Make iterator IT return `...' next.
3725 Replaces LEN characters from buffer. */
3726
3727 static void
3728 setup_for_ellipsis (it, len)
3729 struct it *it;
3730 int len;
3731 {
3732 /* Use the display table definition for `...'. Invalid glyphs
3733 will be handled by the method returning elements from dpvec. */
3734 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3735 {
3736 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3737 it->dpvec = v->contents;
3738 it->dpend = v->contents + v->size;
3739 }
3740 else
3741 {
3742 /* Default `...'. */
3743 it->dpvec = default_invis_vector;
3744 it->dpend = default_invis_vector + 3;
3745 }
3746
3747 it->dpvec_char_len = len;
3748 it->current.dpvec_index = 0;
3749 it->dpvec_face_id = -1;
3750
3751 /* Remember the current face id in case glyphs specify faces.
3752 IT's face is restored in set_iterator_to_next.
3753 saved_face_id was set to preceding char's face in handle_stop. */
3754 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3755 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3756
3757 it->method = GET_FROM_DISPLAY_VECTOR;
3758 it->ellipsis_p = 1;
3759 }
3760
3761
3762 \f
3763 /***********************************************************************
3764 'display' property
3765 ***********************************************************************/
3766
3767 /* Set up iterator IT from `display' property at its current position.
3768 Called from handle_stop.
3769 We return HANDLED_RETURN if some part of the display property
3770 overrides the display of the buffer text itself.
3771 Otherwise we return HANDLED_NORMALLY. */
3772
3773 static enum prop_handled
3774 handle_display_prop (it)
3775 struct it *it;
3776 {
3777 Lisp_Object prop, object;
3778 struct text_pos *position;
3779 /* Nonzero if some property replaces the display of the text itself. */
3780 int display_replaced_p = 0;
3781
3782 if (STRINGP (it->string))
3783 {
3784 object = it->string;
3785 position = &it->current.string_pos;
3786 }
3787 else
3788 {
3789 XSETWINDOW (object, it->w);
3790 position = &it->current.pos;
3791 }
3792
3793 /* Reset those iterator values set from display property values. */
3794 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3795 it->space_width = Qnil;
3796 it->font_height = Qnil;
3797 it->voffset = 0;
3798
3799 /* We don't support recursive `display' properties, i.e. string
3800 values that have a string `display' property, that have a string
3801 `display' property etc. */
3802 if (!it->string_from_display_prop_p)
3803 it->area = TEXT_AREA;
3804
3805 prop = Fget_char_property (make_number (position->charpos),
3806 Qdisplay, object);
3807 if (NILP (prop))
3808 return HANDLED_NORMALLY;
3809
3810 if (!STRINGP (it->string))
3811 object = it->w->buffer;
3812
3813 if (CONSP (prop)
3814 /* Simple properties. */
3815 && !EQ (XCAR (prop), Qimage)
3816 && !EQ (XCAR (prop), Qspace)
3817 && !EQ (XCAR (prop), Qwhen)
3818 && !EQ (XCAR (prop), Qslice)
3819 && !EQ (XCAR (prop), Qspace_width)
3820 && !EQ (XCAR (prop), Qheight)
3821 && !EQ (XCAR (prop), Qraise)
3822 /* Marginal area specifications. */
3823 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3824 && !EQ (XCAR (prop), Qleft_fringe)
3825 && !EQ (XCAR (prop), Qright_fringe)
3826 && !NILP (XCAR (prop)))
3827 {
3828 for (; CONSP (prop); prop = XCDR (prop))
3829 {
3830 if (handle_single_display_spec (it, XCAR (prop), object,
3831 position, display_replaced_p))
3832 display_replaced_p = 1;
3833 }
3834 }
3835 else if (VECTORP (prop))
3836 {
3837 int i;
3838 for (i = 0; i < ASIZE (prop); ++i)
3839 if (handle_single_display_spec (it, AREF (prop, i), object,
3840 position, display_replaced_p))
3841 display_replaced_p = 1;
3842 }
3843 else
3844 {
3845 int ret = handle_single_display_spec (it, prop, object, position, 0);
3846 if (ret < 0) /* Replaced by "", i.e. nothing. */
3847 return HANDLED_RECOMPUTE_PROPS;
3848 if (ret)
3849 display_replaced_p = 1;
3850 }
3851
3852 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3853 }
3854
3855
3856 /* Value is the position of the end of the `display' property starting
3857 at START_POS in OBJECT. */
3858
3859 static struct text_pos
3860 display_prop_end (it, object, start_pos)
3861 struct it *it;
3862 Lisp_Object object;
3863 struct text_pos start_pos;
3864 {
3865 Lisp_Object end;
3866 struct text_pos end_pos;
3867
3868 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3869 Qdisplay, object, Qnil);
3870 CHARPOS (end_pos) = XFASTINT (end);
3871 if (STRINGP (object))
3872 compute_string_pos (&end_pos, start_pos, it->string);
3873 else
3874 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3875
3876 return end_pos;
3877 }
3878
3879
3880 /* Set up IT from a single `display' specification PROP. OBJECT
3881 is the object in which the `display' property was found. *POSITION
3882 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3883 means that we previously saw a display specification which already
3884 replaced text display with something else, for example an image;
3885 we ignore such properties after the first one has been processed.
3886
3887 If PROP is a `space' or `image' specification, and in some other
3888 cases too, set *POSITION to the position where the `display'
3889 property ends.
3890
3891 Value is non-zero if something was found which replaces the display
3892 of buffer or string text. Specifically, the value is -1 if that
3893 "something" is "nothing". */
3894
3895 static int
3896 handle_single_display_spec (it, spec, object, position,
3897 display_replaced_before_p)
3898 struct it *it;
3899 Lisp_Object spec;
3900 Lisp_Object object;
3901 struct text_pos *position;
3902 int display_replaced_before_p;
3903 {
3904 Lisp_Object form;
3905 Lisp_Object location, value;
3906 struct text_pos start_pos, save_pos;
3907 int valid_p;
3908
3909 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3910 If the result is non-nil, use VALUE instead of SPEC. */
3911 form = Qt;
3912 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3913 {
3914 spec = XCDR (spec);
3915 if (!CONSP (spec))
3916 return 0;
3917 form = XCAR (spec);
3918 spec = XCDR (spec);
3919 }
3920
3921 if (!NILP (form) && !EQ (form, Qt))
3922 {
3923 int count = SPECPDL_INDEX ();
3924 struct gcpro gcpro1;
3925
3926 /* Bind `object' to the object having the `display' property, a
3927 buffer or string. Bind `position' to the position in the
3928 object where the property was found, and `buffer-position'
3929 to the current position in the buffer. */
3930 specbind (Qobject, object);
3931 specbind (Qposition, make_number (CHARPOS (*position)));
3932 specbind (Qbuffer_position,
3933 make_number (STRINGP (object)
3934 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3935 GCPRO1 (form);
3936 form = safe_eval (form);
3937 UNGCPRO;
3938 unbind_to (count, Qnil);
3939 }
3940
3941 if (NILP (form))
3942 return 0;
3943
3944 /* Handle `(height HEIGHT)' specifications. */
3945 if (CONSP (spec)
3946 && EQ (XCAR (spec), Qheight)
3947 && CONSP (XCDR (spec)))
3948 {
3949 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3950 return 0;
3951
3952 it->font_height = XCAR (XCDR (spec));
3953 if (!NILP (it->font_height))
3954 {
3955 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3956 int new_height = -1;
3957
3958 if (CONSP (it->font_height)
3959 && (EQ (XCAR (it->font_height), Qplus)
3960 || EQ (XCAR (it->font_height), Qminus))
3961 && CONSP (XCDR (it->font_height))
3962 && INTEGERP (XCAR (XCDR (it->font_height))))
3963 {
3964 /* `(+ N)' or `(- N)' where N is an integer. */
3965 int steps = XINT (XCAR (XCDR (it->font_height)));
3966 if (EQ (XCAR (it->font_height), Qplus))
3967 steps = - steps;
3968 it->face_id = smaller_face (it->f, it->face_id, steps);
3969 }
3970 else if (FUNCTIONP (it->font_height))
3971 {
3972 /* Call function with current height as argument.
3973 Value is the new height. */
3974 Lisp_Object height;
3975 height = safe_call1 (it->font_height,
3976 face->lface[LFACE_HEIGHT_INDEX]);
3977 if (NUMBERP (height))
3978 new_height = XFLOATINT (height);
3979 }
3980 else if (NUMBERP (it->font_height))
3981 {
3982 /* Value is a multiple of the canonical char height. */
3983 struct face *face;
3984
3985 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3986 new_height = (XFLOATINT (it->font_height)
3987 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3988 }
3989 else
3990 {
3991 /* Evaluate IT->font_height with `height' bound to the
3992 current specified height to get the new height. */
3993 int count = SPECPDL_INDEX ();
3994
3995 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3996 value = safe_eval (it->font_height);
3997 unbind_to (count, Qnil);
3998
3999 if (NUMBERP (value))
4000 new_height = XFLOATINT (value);
4001 }
4002
4003 if (new_height > 0)
4004 it->face_id = face_with_height (it->f, it->face_id, new_height);
4005 }
4006
4007 return 0;
4008 }
4009
4010 /* Handle `(space_width WIDTH)'. */
4011 if (CONSP (spec)
4012 && EQ (XCAR (spec), Qspace_width)
4013 && CONSP (XCDR (spec)))
4014 {
4015 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
4016 return 0;
4017
4018 value = XCAR (XCDR (spec));
4019 if (NUMBERP (value) && XFLOATINT (value) > 0)
4020 it->space_width = value;
4021
4022 return 0;
4023 }
4024
4025 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4026 if (CONSP (spec)
4027 && EQ (XCAR (spec), Qslice))
4028 {
4029 Lisp_Object tem;
4030
4031 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
4032 return 0;
4033
4034 if (tem = XCDR (spec), CONSP (tem))
4035 {
4036 it->slice.x = XCAR (tem);
4037 if (tem = XCDR (tem), CONSP (tem))
4038 {
4039 it->slice.y = XCAR (tem);
4040 if (tem = XCDR (tem), CONSP (tem))
4041 {
4042 it->slice.width = XCAR (tem);
4043 if (tem = XCDR (tem), CONSP (tem))
4044 it->slice.height = XCAR (tem);
4045 }
4046 }
4047 }
4048
4049 return 0;
4050 }
4051
4052 /* Handle `(raise FACTOR)'. */
4053 if (CONSP (spec)
4054 && EQ (XCAR (spec), Qraise)
4055 && CONSP (XCDR (spec)))
4056 {
4057 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
4058 return 0;
4059
4060 #ifdef HAVE_WINDOW_SYSTEM
4061 value = XCAR (XCDR (spec));
4062 if (NUMBERP (value))
4063 {
4064 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4065 it->voffset = - (XFLOATINT (value)
4066 * (FONT_HEIGHT (face->font)));
4067 }
4068 #endif /* HAVE_WINDOW_SYSTEM */
4069
4070 return 0;
4071 }
4072
4073 /* Don't handle the other kinds of display specifications
4074 inside a string that we got from a `display' property. */
4075 if (it->string_from_display_prop_p)
4076 return 0;
4077
4078 /* Characters having this form of property are not displayed, so
4079 we have to find the end of the property. */
4080 start_pos = *position;
4081 *position = display_prop_end (it, object, start_pos);
4082 value = Qnil;
4083
4084 /* Stop the scan at that end position--we assume that all
4085 text properties change there. */
4086 it->stop_charpos = position->charpos;
4087
4088 /* Handle `(left-fringe BITMAP [FACE])'
4089 and `(right-fringe BITMAP [FACE])'. */
4090 if (CONSP (spec)
4091 && (EQ (XCAR (spec), Qleft_fringe)
4092 || EQ (XCAR (spec), Qright_fringe))
4093 && CONSP (XCDR (spec)))
4094 {
4095 int face_id = DEFAULT_FACE_ID;
4096 int fringe_bitmap;
4097
4098 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
4099 /* If we return here, POSITION has been advanced
4100 across the text with this property. */
4101 return 0;
4102
4103 #ifdef HAVE_WINDOW_SYSTEM
4104 value = XCAR (XCDR (spec));
4105 if (!SYMBOLP (value)
4106 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4107 /* If we return here, POSITION has been advanced
4108 across the text with this property. */
4109 return 0;
4110
4111 if (CONSP (XCDR (XCDR (spec))))
4112 {
4113 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4114 int face_id2 = lookup_derived_face (it->f, face_name,
4115 'A', FRINGE_FACE_ID, 0);
4116 if (face_id2 >= 0)
4117 face_id = face_id2;
4118 }
4119
4120 /* Save current settings of IT so that we can restore them
4121 when we are finished with the glyph property value. */
4122
4123 save_pos = it->position;
4124 it->position = *position;
4125 push_it (it);
4126 it->position = save_pos;
4127
4128 it->area = TEXT_AREA;
4129 it->what = IT_IMAGE;
4130 it->image_id = -1; /* no image */
4131 it->position = start_pos;
4132 it->object = NILP (object) ? it->w->buffer : object;
4133 it->method = GET_FROM_IMAGE;
4134 it->face_id = face_id;
4135
4136 /* Say that we haven't consumed the characters with
4137 `display' property yet. The call to pop_it in
4138 set_iterator_to_next will clean this up. */
4139 *position = start_pos;
4140
4141 if (EQ (XCAR (spec), Qleft_fringe))
4142 {
4143 it->left_user_fringe_bitmap = fringe_bitmap;
4144 it->left_user_fringe_face_id = face_id;
4145 }
4146 else
4147 {
4148 it->right_user_fringe_bitmap = fringe_bitmap;
4149 it->right_user_fringe_face_id = face_id;
4150 }
4151 #endif /* HAVE_WINDOW_SYSTEM */
4152 return 1;
4153 }
4154
4155 /* Prepare to handle `((margin left-margin) ...)',
4156 `((margin right-margin) ...)' and `((margin nil) ...)'
4157 prefixes for display specifications. */
4158 location = Qunbound;
4159 if (CONSP (spec) && CONSP (XCAR (spec)))
4160 {
4161 Lisp_Object tem;
4162
4163 value = XCDR (spec);
4164 if (CONSP (value))
4165 value = XCAR (value);
4166
4167 tem = XCAR (spec);
4168 if (EQ (XCAR (tem), Qmargin)
4169 && (tem = XCDR (tem),
4170 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4171 (NILP (tem)
4172 || EQ (tem, Qleft_margin)
4173 || EQ (tem, Qright_margin))))
4174 location = tem;
4175 }
4176
4177 if (EQ (location, Qunbound))
4178 {
4179 location = Qnil;
4180 value = spec;
4181 }
4182
4183 /* After this point, VALUE is the property after any
4184 margin prefix has been stripped. It must be a string,
4185 an image specification, or `(space ...)'.
4186
4187 LOCATION specifies where to display: `left-margin',
4188 `right-margin' or nil. */
4189
4190 valid_p = (STRINGP (value)
4191 #ifdef HAVE_WINDOW_SYSTEM
4192 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
4193 #endif /* not HAVE_WINDOW_SYSTEM */
4194 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4195
4196 if (valid_p && !display_replaced_before_p)
4197 {
4198 /* Save current settings of IT so that we can restore them
4199 when we are finished with the glyph property value. */
4200 save_pos = it->position;
4201 it->position = *position;
4202 push_it (it);
4203 it->position = save_pos;
4204
4205 if (NILP (location))
4206 it->area = TEXT_AREA;
4207 else if (EQ (location, Qleft_margin))
4208 it->area = LEFT_MARGIN_AREA;
4209 else
4210 it->area = RIGHT_MARGIN_AREA;
4211
4212 if (STRINGP (value))
4213 {
4214 if (SCHARS (value) == 0)
4215 {
4216 pop_it (it);
4217 return -1; /* Replaced by "", i.e. nothing. */
4218 }
4219 it->string = value;
4220 it->multibyte_p = STRING_MULTIBYTE (it->string);
4221 it->current.overlay_string_index = -1;
4222 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4223 it->end_charpos = it->string_nchars = SCHARS (it->string);
4224 it->method = GET_FROM_STRING;
4225 it->stop_charpos = 0;
4226 it->string_from_display_prop_p = 1;
4227 /* Say that we haven't consumed the characters with
4228 `display' property yet. The call to pop_it in
4229 set_iterator_to_next will clean this up. */
4230 *position = start_pos;
4231 }
4232 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4233 {
4234 it->method = GET_FROM_STRETCH;
4235 it->object = value;
4236 *position = it->position = start_pos;
4237 }
4238 #ifdef HAVE_WINDOW_SYSTEM
4239 else
4240 {
4241 it->what = IT_IMAGE;
4242 it->image_id = lookup_image (it->f, value);
4243 it->position = start_pos;
4244 it->object = NILP (object) ? it->w->buffer : object;
4245 it->method = GET_FROM_IMAGE;
4246
4247 /* Say that we haven't consumed the characters with
4248 `display' property yet. The call to pop_it in
4249 set_iterator_to_next will clean this up. */
4250 *position = start_pos;
4251 }
4252 #endif /* HAVE_WINDOW_SYSTEM */
4253
4254 return 1;
4255 }
4256
4257 /* Invalid property or property not supported. Restore
4258 POSITION to what it was before. */
4259 *position = start_pos;
4260 return 0;
4261 }
4262
4263
4264 /* Check if SPEC is a display specification value whose text should be
4265 treated as intangible. */
4266
4267 static int
4268 single_display_spec_intangible_p (prop)
4269 Lisp_Object prop;
4270 {
4271 /* Skip over `when FORM'. */
4272 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4273 {
4274 prop = XCDR (prop);
4275 if (!CONSP (prop))
4276 return 0;
4277 prop = XCDR (prop);
4278 }
4279
4280 if (STRINGP (prop))
4281 return 1;
4282
4283 if (!CONSP (prop))
4284 return 0;
4285
4286 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4287 we don't need to treat text as intangible. */
4288 if (EQ (XCAR (prop), Qmargin))
4289 {
4290 prop = XCDR (prop);
4291 if (!CONSP (prop))
4292 return 0;
4293
4294 prop = XCDR (prop);
4295 if (!CONSP (prop)
4296 || EQ (XCAR (prop), Qleft_margin)
4297 || EQ (XCAR (prop), Qright_margin))
4298 return 0;
4299 }
4300
4301 return (CONSP (prop)
4302 && (EQ (XCAR (prop), Qimage)
4303 || EQ (XCAR (prop), Qspace)));
4304 }
4305
4306
4307 /* Check if PROP is a display property value whose text should be
4308 treated as intangible. */
4309
4310 int
4311 display_prop_intangible_p (prop)
4312 Lisp_Object prop;
4313 {
4314 if (CONSP (prop)
4315 && CONSP (XCAR (prop))
4316 && !EQ (Qmargin, XCAR (XCAR (prop))))
4317 {
4318 /* A list of sub-properties. */
4319 while (CONSP (prop))
4320 {
4321 if (single_display_spec_intangible_p (XCAR (prop)))
4322 return 1;
4323 prop = XCDR (prop);
4324 }
4325 }
4326 else if (VECTORP (prop))
4327 {
4328 /* A vector of sub-properties. */
4329 int i;
4330 for (i = 0; i < ASIZE (prop); ++i)
4331 if (single_display_spec_intangible_p (AREF (prop, i)))
4332 return 1;
4333 }
4334 else
4335 return single_display_spec_intangible_p (prop);
4336
4337 return 0;
4338 }
4339
4340
4341 /* Return 1 if PROP is a display sub-property value containing STRING. */
4342
4343 static int
4344 single_display_spec_string_p (prop, string)
4345 Lisp_Object prop, string;
4346 {
4347 if (EQ (string, prop))
4348 return 1;
4349
4350 /* Skip over `when FORM'. */
4351 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4352 {
4353 prop = XCDR (prop);
4354 if (!CONSP (prop))
4355 return 0;
4356 prop = XCDR (prop);
4357 }
4358
4359 if (CONSP (prop))
4360 /* Skip over `margin LOCATION'. */
4361 if (EQ (XCAR (prop), Qmargin))
4362 {
4363 prop = XCDR (prop);
4364 if (!CONSP (prop))
4365 return 0;
4366
4367 prop = XCDR (prop);
4368 if (!CONSP (prop))
4369 return 0;
4370 }
4371
4372 return CONSP (prop) && EQ (XCAR (prop), string);
4373 }
4374
4375
4376 /* Return 1 if STRING appears in the `display' property PROP. */
4377
4378 static int
4379 display_prop_string_p (prop, string)
4380 Lisp_Object prop, string;
4381 {
4382 if (CONSP (prop)
4383 && CONSP (XCAR (prop))
4384 && !EQ (Qmargin, XCAR (XCAR (prop))))
4385 {
4386 /* A list of sub-properties. */
4387 while (CONSP (prop))
4388 {
4389 if (single_display_spec_string_p (XCAR (prop), string))
4390 return 1;
4391 prop = XCDR (prop);
4392 }
4393 }
4394 else if (VECTORP (prop))
4395 {
4396 /* A vector of sub-properties. */
4397 int i;
4398 for (i = 0; i < ASIZE (prop); ++i)
4399 if (single_display_spec_string_p (AREF (prop, i), string))
4400 return 1;
4401 }
4402 else
4403 return single_display_spec_string_p (prop, string);
4404
4405 return 0;
4406 }
4407
4408
4409 /* Determine from which buffer position in W's buffer STRING comes
4410 from. AROUND_CHARPOS is an approximate position where it could
4411 be from. Value is the buffer position or 0 if it couldn't be
4412 determined.
4413
4414 W's buffer must be current.
4415
4416 This function is necessary because we don't record buffer positions
4417 in glyphs generated from strings (to keep struct glyph small).
4418 This function may only use code that doesn't eval because it is
4419 called asynchronously from note_mouse_highlight. */
4420
4421 int
4422 string_buffer_position (w, string, around_charpos)
4423 struct window *w;
4424 Lisp_Object string;
4425 int around_charpos;
4426 {
4427 Lisp_Object limit, prop, pos;
4428 const int MAX_DISTANCE = 1000;
4429 int found = 0;
4430
4431 pos = make_number (around_charpos);
4432 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4433 while (!found && !EQ (pos, limit))
4434 {
4435 prop = Fget_char_property (pos, Qdisplay, Qnil);
4436 if (!NILP (prop) && display_prop_string_p (prop, string))
4437 found = 1;
4438 else
4439 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4440 }
4441
4442 if (!found)
4443 {
4444 pos = make_number (around_charpos);
4445 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4446 while (!found && !EQ (pos, limit))
4447 {
4448 prop = Fget_char_property (pos, Qdisplay, Qnil);
4449 if (!NILP (prop) && display_prop_string_p (prop, string))
4450 found = 1;
4451 else
4452 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4453 limit);
4454 }
4455 }
4456
4457 return found ? XINT (pos) : 0;
4458 }
4459
4460
4461 \f
4462 /***********************************************************************
4463 `composition' property
4464 ***********************************************************************/
4465
4466 /* Set up iterator IT from `composition' property at its current
4467 position. Called from handle_stop. */
4468
4469 static enum prop_handled
4470 handle_composition_prop (it)
4471 struct it *it;
4472 {
4473 Lisp_Object prop, string;
4474 int pos, pos_byte, end;
4475 enum prop_handled handled = HANDLED_NORMALLY;
4476
4477 if (STRINGP (it->string))
4478 {
4479 pos = IT_STRING_CHARPOS (*it);
4480 pos_byte = IT_STRING_BYTEPOS (*it);
4481 string = it->string;
4482 }
4483 else
4484 {
4485 pos = IT_CHARPOS (*it);
4486 pos_byte = IT_BYTEPOS (*it);
4487 string = Qnil;
4488 }
4489
4490 /* If there's a valid composition and point is not inside of the
4491 composition (in the case that the composition is from the current
4492 buffer), draw a glyph composed from the composition components. */
4493 if (find_composition (pos, -1, &pos, &end, &prop, string)
4494 && COMPOSITION_VALID_P (pos, end, prop)
4495 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4496 {
4497 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4498
4499 if (id >= 0)
4500 {
4501 struct composition *cmp = composition_table[id];
4502
4503 if (cmp->glyph_len == 0)
4504 {
4505 /* No glyph. */
4506 if (STRINGP (it->string))
4507 {
4508 IT_STRING_CHARPOS (*it) = end;
4509 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string,
4510 end);
4511 }
4512 else
4513 {
4514 IT_CHARPOS (*it) = end;
4515 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end);
4516 }
4517 return HANDLED_RECOMPUTE_PROPS;
4518 }
4519
4520 it->stop_charpos = end;
4521 push_it (it);
4522
4523 it->method = GET_FROM_COMPOSITION;
4524 it->cmp_id = id;
4525 it->cmp_len = COMPOSITION_LENGTH (prop);
4526 /* For a terminal, draw only the first character of the
4527 components. */
4528 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4529 it->len = (STRINGP (it->string)
4530 ? string_char_to_byte (it->string, end)
4531 : CHAR_TO_BYTE (end)) - pos_byte;
4532 handled = HANDLED_RETURN;
4533 }
4534 }
4535
4536 return handled;
4537 }
4538
4539
4540 \f
4541 /***********************************************************************
4542 Overlay strings
4543 ***********************************************************************/
4544
4545 /* The following structure is used to record overlay strings for
4546 later sorting in load_overlay_strings. */
4547
4548 struct overlay_entry
4549 {
4550 Lisp_Object overlay;
4551 Lisp_Object string;
4552 int priority;
4553 int after_string_p;
4554 };
4555
4556
4557 /* Set up iterator IT from overlay strings at its current position.
4558 Called from handle_stop. */
4559
4560 static enum prop_handled
4561 handle_overlay_change (it)
4562 struct it *it;
4563 {
4564 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4565 return HANDLED_RECOMPUTE_PROPS;
4566 else
4567 return HANDLED_NORMALLY;
4568 }
4569
4570
4571 /* Set up the next overlay string for delivery by IT, if there is an
4572 overlay string to deliver. Called by set_iterator_to_next when the
4573 end of the current overlay string is reached. If there are more
4574 overlay strings to display, IT->string and
4575 IT->current.overlay_string_index are set appropriately here.
4576 Otherwise IT->string is set to nil. */
4577
4578 static void
4579 next_overlay_string (it)
4580 struct it *it;
4581 {
4582 ++it->current.overlay_string_index;
4583 if (it->current.overlay_string_index == it->n_overlay_strings)
4584 {
4585 /* No more overlay strings. Restore IT's settings to what
4586 they were before overlay strings were processed, and
4587 continue to deliver from current_buffer. */
4588 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4589
4590 pop_it (it);
4591 xassert (it->sp > 0
4592 || it->method == GET_FROM_COMPOSITION
4593 || (NILP (it->string)
4594 && it->method == GET_FROM_BUFFER
4595 && it->stop_charpos >= BEGV
4596 && it->stop_charpos <= it->end_charpos));
4597 it->current.overlay_string_index = -1;
4598 it->n_overlay_strings = 0;
4599
4600 /* If we're at the end of the buffer, record that we have
4601 processed the overlay strings there already, so that
4602 next_element_from_buffer doesn't try it again. */
4603 if (IT_CHARPOS (*it) >= it->end_charpos)
4604 it->overlay_strings_at_end_processed_p = 1;
4605
4606 /* If we have to display `...' for invisible text, set
4607 the iterator up for that. */
4608 if (display_ellipsis_p)
4609 setup_for_ellipsis (it, 0);
4610 }
4611 else
4612 {
4613 /* There are more overlay strings to process. If
4614 IT->current.overlay_string_index has advanced to a position
4615 where we must load IT->overlay_strings with more strings, do
4616 it. */
4617 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4618
4619 if (it->current.overlay_string_index && i == 0)
4620 load_overlay_strings (it, 0);
4621
4622 /* Initialize IT to deliver display elements from the overlay
4623 string. */
4624 it->string = it->overlay_strings[i];
4625 it->multibyte_p = STRING_MULTIBYTE (it->string);
4626 SET_TEXT_POS (it->current.string_pos, 0, 0);
4627 it->method = GET_FROM_STRING;
4628 it->stop_charpos = 0;
4629 }
4630
4631 CHECK_IT (it);
4632 }
4633
4634
4635 /* Compare two overlay_entry structures E1 and E2. Used as a
4636 comparison function for qsort in load_overlay_strings. Overlay
4637 strings for the same position are sorted so that
4638
4639 1. All after-strings come in front of before-strings, except
4640 when they come from the same overlay.
4641
4642 2. Within after-strings, strings are sorted so that overlay strings
4643 from overlays with higher priorities come first.
4644
4645 2. Within before-strings, strings are sorted so that overlay
4646 strings from overlays with higher priorities come last.
4647
4648 Value is analogous to strcmp. */
4649
4650
4651 static int
4652 compare_overlay_entries (e1, e2)
4653 void *e1, *e2;
4654 {
4655 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4656 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4657 int result;
4658
4659 if (entry1->after_string_p != entry2->after_string_p)
4660 {
4661 /* Let after-strings appear in front of before-strings if
4662 they come from different overlays. */
4663 if (EQ (entry1->overlay, entry2->overlay))
4664 result = entry1->after_string_p ? 1 : -1;
4665 else
4666 result = entry1->after_string_p ? -1 : 1;
4667 }
4668 else if (entry1->after_string_p)
4669 /* After-strings sorted in order of decreasing priority. */
4670 result = entry2->priority - entry1->priority;
4671 else
4672 /* Before-strings sorted in order of increasing priority. */
4673 result = entry1->priority - entry2->priority;
4674
4675 return result;
4676 }
4677
4678
4679 /* Load the vector IT->overlay_strings with overlay strings from IT's
4680 current buffer position, or from CHARPOS if that is > 0. Set
4681 IT->n_overlays to the total number of overlay strings found.
4682
4683 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4684 a time. On entry into load_overlay_strings,
4685 IT->current.overlay_string_index gives the number of overlay
4686 strings that have already been loaded by previous calls to this
4687 function.
4688
4689 IT->add_overlay_start contains an additional overlay start
4690 position to consider for taking overlay strings from, if non-zero.
4691 This position comes into play when the overlay has an `invisible'
4692 property, and both before and after-strings. When we've skipped to
4693 the end of the overlay, because of its `invisible' property, we
4694 nevertheless want its before-string to appear.
4695 IT->add_overlay_start will contain the overlay start position
4696 in this case.
4697
4698 Overlay strings are sorted so that after-string strings come in
4699 front of before-string strings. Within before and after-strings,
4700 strings are sorted by overlay priority. See also function
4701 compare_overlay_entries. */
4702
4703 static void
4704 load_overlay_strings (it, charpos)
4705 struct it *it;
4706 int charpos;
4707 {
4708 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4709 Lisp_Object overlay, window, str, invisible;
4710 struct Lisp_Overlay *ov;
4711 int start, end;
4712 int size = 20;
4713 int n = 0, i, j, invis_p;
4714 struct overlay_entry *entries
4715 = (struct overlay_entry *) alloca (size * sizeof *entries);
4716
4717 if (charpos <= 0)
4718 charpos = IT_CHARPOS (*it);
4719
4720 /* Append the overlay string STRING of overlay OVERLAY to vector
4721 `entries' which has size `size' and currently contains `n'
4722 elements. AFTER_P non-zero means STRING is an after-string of
4723 OVERLAY. */
4724 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4725 do \
4726 { \
4727 Lisp_Object priority; \
4728 \
4729 if (n == size) \
4730 { \
4731 int new_size = 2 * size; \
4732 struct overlay_entry *old = entries; \
4733 entries = \
4734 (struct overlay_entry *) alloca (new_size \
4735 * sizeof *entries); \
4736 bcopy (old, entries, size * sizeof *entries); \
4737 size = new_size; \
4738 } \
4739 \
4740 entries[n].string = (STRING); \
4741 entries[n].overlay = (OVERLAY); \
4742 priority = Foverlay_get ((OVERLAY), Qpriority); \
4743 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4744 entries[n].after_string_p = (AFTER_P); \
4745 ++n; \
4746 } \
4747 while (0)
4748
4749 /* Process overlay before the overlay center. */
4750 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4751 {
4752 XSETMISC (overlay, ov);
4753 xassert (OVERLAYP (overlay));
4754 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4755 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4756
4757 if (end < charpos)
4758 break;
4759
4760 /* Skip this overlay if it doesn't start or end at IT's current
4761 position. */
4762 if (end != charpos && start != charpos)
4763 continue;
4764
4765 /* Skip this overlay if it doesn't apply to IT->w. */
4766 window = Foverlay_get (overlay, Qwindow);
4767 if (WINDOWP (window) && XWINDOW (window) != it->w)
4768 continue;
4769
4770 /* If the text ``under'' the overlay is invisible, both before-
4771 and after-strings from this overlay are visible; start and
4772 end position are indistinguishable. */
4773 invisible = Foverlay_get (overlay, Qinvisible);
4774 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4775
4776 /* If overlay has a non-empty before-string, record it. */
4777 if ((start == charpos || (end == charpos && invis_p))
4778 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4779 && SCHARS (str))
4780 RECORD_OVERLAY_STRING (overlay, str, 0);
4781
4782 /* If overlay has a non-empty after-string, record it. */
4783 if ((end == charpos || (start == charpos && invis_p))
4784 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4785 && SCHARS (str))
4786 RECORD_OVERLAY_STRING (overlay, str, 1);
4787 }
4788
4789 /* Process overlays after the overlay center. */
4790 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4791 {
4792 XSETMISC (overlay, ov);
4793 xassert (OVERLAYP (overlay));
4794 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4795 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4796
4797 if (start > charpos)
4798 break;
4799
4800 /* Skip this overlay if it doesn't start or end at IT's current
4801 position. */
4802 if (end != charpos && start != charpos)
4803 continue;
4804
4805 /* Skip this overlay if it doesn't apply to IT->w. */
4806 window = Foverlay_get (overlay, Qwindow);
4807 if (WINDOWP (window) && XWINDOW (window) != it->w)
4808 continue;
4809
4810 /* If the text ``under'' the overlay is invisible, it has a zero
4811 dimension, and both before- and after-strings apply. */
4812 invisible = Foverlay_get (overlay, Qinvisible);
4813 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4814
4815 /* If overlay has a non-empty before-string, record it. */
4816 if ((start == charpos || (end == charpos && invis_p))
4817 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4818 && SCHARS (str))
4819 RECORD_OVERLAY_STRING (overlay, str, 0);
4820
4821 /* If overlay has a non-empty after-string, record it. */
4822 if ((end == charpos || (start == charpos && invis_p))
4823 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4824 && SCHARS (str))
4825 RECORD_OVERLAY_STRING (overlay, str, 1);
4826 }
4827
4828 #undef RECORD_OVERLAY_STRING
4829
4830 /* Sort entries. */
4831 if (n > 1)
4832 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4833
4834 /* Record the total number of strings to process. */
4835 it->n_overlay_strings = n;
4836
4837 /* IT->current.overlay_string_index is the number of overlay strings
4838 that have already been consumed by IT. Copy some of the
4839 remaining overlay strings to IT->overlay_strings. */
4840 i = 0;
4841 j = it->current.overlay_string_index;
4842 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4843 it->overlay_strings[i++] = entries[j++].string;
4844
4845 CHECK_IT (it);
4846 }
4847
4848
4849 /* Get the first chunk of overlay strings at IT's current buffer
4850 position, or at CHARPOS if that is > 0. Value is non-zero if at
4851 least one overlay string was found. */
4852
4853 static int
4854 get_overlay_strings_1 (it, charpos, compute_stop_p)
4855 struct it *it;
4856 int charpos;
4857 {
4858 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4859 process. This fills IT->overlay_strings with strings, and sets
4860 IT->n_overlay_strings to the total number of strings to process.
4861 IT->pos.overlay_string_index has to be set temporarily to zero
4862 because load_overlay_strings needs this; it must be set to -1
4863 when no overlay strings are found because a zero value would
4864 indicate a position in the first overlay string. */
4865 it->current.overlay_string_index = 0;
4866 load_overlay_strings (it, charpos);
4867
4868 /* If we found overlay strings, set up IT to deliver display
4869 elements from the first one. Otherwise set up IT to deliver
4870 from current_buffer. */
4871 if (it->n_overlay_strings)
4872 {
4873 /* Make sure we know settings in current_buffer, so that we can
4874 restore meaningful values when we're done with the overlay
4875 strings. */
4876 if (compute_stop_p)
4877 compute_stop_pos (it);
4878 xassert (it->face_id >= 0);
4879
4880 /* Save IT's settings. They are restored after all overlay
4881 strings have been processed. */
4882 xassert (!compute_stop_p || it->sp == 0);
4883 push_it (it);
4884
4885 /* Set up IT to deliver display elements from the first overlay
4886 string. */
4887 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4888 it->string = it->overlay_strings[0];
4889 it->stop_charpos = 0;
4890 xassert (STRINGP (it->string));
4891 it->end_charpos = SCHARS (it->string);
4892 it->multibyte_p = STRING_MULTIBYTE (it->string);
4893 it->method = GET_FROM_STRING;
4894 return 1;
4895 }
4896
4897 it->current.overlay_string_index = -1;
4898 return 0;
4899 }
4900
4901 static int
4902 get_overlay_strings (it, charpos)
4903 struct it *it;
4904 int charpos;
4905 {
4906 it->string = Qnil;
4907 it->method = GET_FROM_BUFFER;
4908
4909 (void) get_overlay_strings_1 (it, charpos, 1);
4910
4911 CHECK_IT (it);
4912
4913 /* Value is non-zero if we found at least one overlay string. */
4914 return STRINGP (it->string);
4915 }
4916
4917
4918 \f
4919 /***********************************************************************
4920 Saving and restoring state
4921 ***********************************************************************/
4922
4923 /* Save current settings of IT on IT->stack. Called, for example,
4924 before setting up IT for an overlay string, to be able to restore
4925 IT's settings to what they were after the overlay string has been
4926 processed. */
4927
4928 static void
4929 push_it (it)
4930 struct it *it;
4931 {
4932 struct iterator_stack_entry *p;
4933
4934 xassert (it->sp < IT_STACK_SIZE);
4935 p = it->stack + it->sp;
4936
4937 p->stop_charpos = it->stop_charpos;
4938 xassert (it->face_id >= 0);
4939 p->face_id = it->face_id;
4940 p->string = it->string;
4941 p->method = it->method;
4942 switch (p->method)
4943 {
4944 case GET_FROM_IMAGE:
4945 p->u.image.object = it->object;
4946 p->u.image.image_id = it->image_id;
4947 p->u.image.slice = it->slice;
4948 break;
4949 case GET_FROM_COMPOSITION:
4950 p->u.comp.object = it->object;
4951 p->u.comp.c = it->c;
4952 p->u.comp.len = it->len;
4953 p->u.comp.cmp_id = it->cmp_id;
4954 p->u.comp.cmp_len = it->cmp_len;
4955 break;
4956 case GET_FROM_STRETCH:
4957 p->u.stretch.object = it->object;
4958 break;
4959 }
4960 p->position = it->position;
4961 p->current = it->current;
4962 p->end_charpos = it->end_charpos;
4963 p->string_nchars = it->string_nchars;
4964 p->area = it->area;
4965 p->multibyte_p = it->multibyte_p;
4966 p->space_width = it->space_width;
4967 p->font_height = it->font_height;
4968 p->voffset = it->voffset;
4969 p->string_from_display_prop_p = it->string_from_display_prop_p;
4970 p->display_ellipsis_p = 0;
4971 ++it->sp;
4972 }
4973
4974
4975 /* Restore IT's settings from IT->stack. Called, for example, when no
4976 more overlay strings must be processed, and we return to delivering
4977 display elements from a buffer, or when the end of a string from a
4978 `display' property is reached and we return to delivering display
4979 elements from an overlay string, or from a buffer. */
4980
4981 static void
4982 pop_it (it)
4983 struct it *it;
4984 {
4985 struct iterator_stack_entry *p;
4986
4987 xassert (it->sp > 0);
4988 --it->sp;
4989 p = it->stack + it->sp;
4990 it->stop_charpos = p->stop_charpos;
4991 it->face_id = p->face_id;
4992 it->current = p->current;
4993 it->position = p->position;
4994 it->string = p->string;
4995 if (NILP (it->string))
4996 SET_TEXT_POS (it->current.string_pos, -1, -1);
4997 it->method = p->method;
4998 switch (it->method)
4999 {
5000 case GET_FROM_IMAGE:
5001 it->image_id = p->u.image.image_id;
5002 it->object = p->u.image.object;
5003 it->slice = p->u.image.slice;
5004 break;
5005 case GET_FROM_COMPOSITION:
5006 it->object = p->u.comp.object;
5007 it->c = p->u.comp.c;
5008 it->len = p->u.comp.len;
5009 it->cmp_id = p->u.comp.cmp_id;
5010 it->cmp_len = p->u.comp.cmp_len;
5011 break;
5012 case GET_FROM_STRETCH:
5013 it->object = p->u.comp.object;
5014 break;
5015 case GET_FROM_BUFFER:
5016 it->object = it->w->buffer;
5017 break;
5018 case GET_FROM_STRING:
5019 it->object = it->string;
5020 break;
5021 }
5022 it->end_charpos = p->end_charpos;
5023 it->string_nchars = p->string_nchars;
5024 it->area = p->area;
5025 it->multibyte_p = p->multibyte_p;
5026 it->space_width = p->space_width;
5027 it->font_height = p->font_height;
5028 it->voffset = p->voffset;
5029 it->string_from_display_prop_p = p->string_from_display_prop_p;
5030 }
5031
5032
5033 \f
5034 /***********************************************************************
5035 Moving over lines
5036 ***********************************************************************/
5037
5038 /* Set IT's current position to the previous line start. */
5039
5040 static void
5041 back_to_previous_line_start (it)
5042 struct it *it;
5043 {
5044 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5045 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5046 }
5047
5048
5049 /* Move IT to the next line start.
5050
5051 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5052 we skipped over part of the text (as opposed to moving the iterator
5053 continuously over the text). Otherwise, don't change the value
5054 of *SKIPPED_P.
5055
5056 Newlines may come from buffer text, overlay strings, or strings
5057 displayed via the `display' property. That's the reason we can't
5058 simply use find_next_newline_no_quit.
5059
5060 Note that this function may not skip over invisible text that is so
5061 because of text properties and immediately follows a newline. If
5062 it would, function reseat_at_next_visible_line_start, when called
5063 from set_iterator_to_next, would effectively make invisible
5064 characters following a newline part of the wrong glyph row, which
5065 leads to wrong cursor motion. */
5066
5067 static int
5068 forward_to_next_line_start (it, skipped_p)
5069 struct it *it;
5070 int *skipped_p;
5071 {
5072 int old_selective, newline_found_p, n;
5073 const int MAX_NEWLINE_DISTANCE = 500;
5074
5075 /* If already on a newline, just consume it to avoid unintended
5076 skipping over invisible text below. */
5077 if (it->what == IT_CHARACTER
5078 && it->c == '\n'
5079 && CHARPOS (it->position) == IT_CHARPOS (*it))
5080 {
5081 set_iterator_to_next (it, 0);
5082 it->c = 0;
5083 return 1;
5084 }
5085
5086 /* Don't handle selective display in the following. It's (a)
5087 unnecessary because it's done by the caller, and (b) leads to an
5088 infinite recursion because next_element_from_ellipsis indirectly
5089 calls this function. */
5090 old_selective = it->selective;
5091 it->selective = 0;
5092
5093 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5094 from buffer text. */
5095 for (n = newline_found_p = 0;
5096 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5097 n += STRINGP (it->string) ? 0 : 1)
5098 {
5099 if (!get_next_display_element (it))
5100 return 0;
5101 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5102 set_iterator_to_next (it, 0);
5103 }
5104
5105 /* If we didn't find a newline near enough, see if we can use a
5106 short-cut. */
5107 if (!newline_found_p)
5108 {
5109 int start = IT_CHARPOS (*it);
5110 int limit = find_next_newline_no_quit (start, 1);
5111 Lisp_Object pos;
5112
5113 xassert (!STRINGP (it->string));
5114
5115 /* If there isn't any `display' property in sight, and no
5116 overlays, we can just use the position of the newline in
5117 buffer text. */
5118 if (it->stop_charpos >= limit
5119 || ((pos = Fnext_single_property_change (make_number (start),
5120 Qdisplay,
5121 Qnil, make_number (limit)),
5122 NILP (pos))
5123 && next_overlay_change (start) == ZV))
5124 {
5125 IT_CHARPOS (*it) = limit;
5126 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5127 *skipped_p = newline_found_p = 1;
5128 }
5129 else
5130 {
5131 while (get_next_display_element (it)
5132 && !newline_found_p)
5133 {
5134 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5135 set_iterator_to_next (it, 0);
5136 }
5137 }
5138 }
5139
5140 it->selective = old_selective;
5141 return newline_found_p;
5142 }
5143
5144
5145 /* Set IT's current position to the previous visible line start. Skip
5146 invisible text that is so either due to text properties or due to
5147 selective display. Caution: this does not change IT->current_x and
5148 IT->hpos. */
5149
5150 static void
5151 back_to_previous_visible_line_start (it)
5152 struct it *it;
5153 {
5154 while (IT_CHARPOS (*it) > BEGV)
5155 {
5156 back_to_previous_line_start (it);
5157
5158 if (IT_CHARPOS (*it) <= BEGV)
5159 break;
5160
5161 /* If selective > 0, then lines indented more than that values
5162 are invisible. */
5163 if (it->selective > 0
5164 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5165 (double) it->selective)) /* iftc */
5166 continue;
5167
5168 /* Check the newline before point for invisibility. */
5169 {
5170 Lisp_Object prop;
5171 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5172 Qinvisible, it->window);
5173 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5174 continue;
5175 }
5176
5177 if (IT_CHARPOS (*it) <= BEGV)
5178 break;
5179
5180 {
5181 struct it it2;
5182 int pos;
5183 int beg, end;
5184 Lisp_Object val, overlay;
5185
5186 /* If newline is part of a composition, continue from start of composition */
5187 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5188 && beg < IT_CHARPOS (*it))
5189 goto replaced;
5190
5191 /* If newline is replaced by a display property, find start of overlay
5192 or interval and continue search from that point. */
5193 it2 = *it;
5194 pos = --IT_CHARPOS (it2);
5195 --IT_BYTEPOS (it2);
5196 it2.sp = 0;
5197 if (handle_display_prop (&it2) == HANDLED_RETURN
5198 && !NILP (val = get_char_property_and_overlay
5199 (make_number (pos), Qdisplay, Qnil, &overlay))
5200 && (OVERLAYP (overlay)
5201 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5202 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5203 goto replaced;
5204
5205 /* Newline is not replaced by anything -- so we are done. */
5206 break;
5207
5208 replaced:
5209 if (beg < BEGV)
5210 beg = BEGV;
5211 IT_CHARPOS (*it) = beg;
5212 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5213 }
5214 }
5215
5216 it->continuation_lines_width = 0;
5217
5218 xassert (IT_CHARPOS (*it) >= BEGV);
5219 xassert (IT_CHARPOS (*it) == BEGV
5220 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5221 CHECK_IT (it);
5222 }
5223
5224
5225 /* Reseat iterator IT at the previous visible line start. Skip
5226 invisible text that is so either due to text properties or due to
5227 selective display. At the end, update IT's overlay information,
5228 face information etc. */
5229
5230 void
5231 reseat_at_previous_visible_line_start (it)
5232 struct it *it;
5233 {
5234 back_to_previous_visible_line_start (it);
5235 reseat (it, it->current.pos, 1);
5236 CHECK_IT (it);
5237 }
5238
5239
5240 /* Reseat iterator IT on the next visible line start in the current
5241 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5242 preceding the line start. Skip over invisible text that is so
5243 because of selective display. Compute faces, overlays etc at the
5244 new position. Note that this function does not skip over text that
5245 is invisible because of text properties. */
5246
5247 static void
5248 reseat_at_next_visible_line_start (it, on_newline_p)
5249 struct it *it;
5250 int on_newline_p;
5251 {
5252 int newline_found_p, skipped_p = 0;
5253
5254 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5255
5256 /* Skip over lines that are invisible because they are indented
5257 more than the value of IT->selective. */
5258 if (it->selective > 0)
5259 while (IT_CHARPOS (*it) < ZV
5260 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5261 (double) it->selective)) /* iftc */
5262 {
5263 xassert (IT_BYTEPOS (*it) == BEGV
5264 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5265 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5266 }
5267
5268 /* Position on the newline if that's what's requested. */
5269 if (on_newline_p && newline_found_p)
5270 {
5271 if (STRINGP (it->string))
5272 {
5273 if (IT_STRING_CHARPOS (*it) > 0)
5274 {
5275 --IT_STRING_CHARPOS (*it);
5276 --IT_STRING_BYTEPOS (*it);
5277 }
5278 }
5279 else if (IT_CHARPOS (*it) > BEGV)
5280 {
5281 --IT_CHARPOS (*it);
5282 --IT_BYTEPOS (*it);
5283 reseat (it, it->current.pos, 0);
5284 }
5285 }
5286 else if (skipped_p)
5287 reseat (it, it->current.pos, 0);
5288
5289 CHECK_IT (it);
5290 }
5291
5292
5293 \f
5294 /***********************************************************************
5295 Changing an iterator's position
5296 ***********************************************************************/
5297
5298 /* Change IT's current position to POS in current_buffer. If FORCE_P
5299 is non-zero, always check for text properties at the new position.
5300 Otherwise, text properties are only looked up if POS >=
5301 IT->check_charpos of a property. */
5302
5303 static void
5304 reseat (it, pos, force_p)
5305 struct it *it;
5306 struct text_pos pos;
5307 int force_p;
5308 {
5309 int original_pos = IT_CHARPOS (*it);
5310
5311 reseat_1 (it, pos, 0);
5312
5313 /* Determine where to check text properties. Avoid doing it
5314 where possible because text property lookup is very expensive. */
5315 if (force_p
5316 || CHARPOS (pos) > it->stop_charpos
5317 || CHARPOS (pos) < original_pos)
5318 handle_stop (it);
5319
5320 CHECK_IT (it);
5321 }
5322
5323
5324 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5325 IT->stop_pos to POS, also. */
5326
5327 static void
5328 reseat_1 (it, pos, set_stop_p)
5329 struct it *it;
5330 struct text_pos pos;
5331 int set_stop_p;
5332 {
5333 /* Don't call this function when scanning a C string. */
5334 xassert (it->s == NULL);
5335
5336 /* POS must be a reasonable value. */
5337 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5338
5339 it->current.pos = it->position = pos;
5340 it->end_charpos = ZV;
5341 it->dpvec = NULL;
5342 it->current.dpvec_index = -1;
5343 it->current.overlay_string_index = -1;
5344 IT_STRING_CHARPOS (*it) = -1;
5345 IT_STRING_BYTEPOS (*it) = -1;
5346 it->string = Qnil;
5347 it->method = GET_FROM_BUFFER;
5348 it->object = it->w->buffer;
5349 it->area = TEXT_AREA;
5350 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5351 it->sp = 0;
5352 it->string_from_display_prop_p = 0;
5353 it->face_before_selective_p = 0;
5354
5355 if (set_stop_p)
5356 it->stop_charpos = CHARPOS (pos);
5357 }
5358
5359
5360 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5361 If S is non-null, it is a C string to iterate over. Otherwise,
5362 STRING gives a Lisp string to iterate over.
5363
5364 If PRECISION > 0, don't return more then PRECISION number of
5365 characters from the string.
5366
5367 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5368 characters have been returned. FIELD_WIDTH < 0 means an infinite
5369 field width.
5370
5371 MULTIBYTE = 0 means disable processing of multibyte characters,
5372 MULTIBYTE > 0 means enable it,
5373 MULTIBYTE < 0 means use IT->multibyte_p.
5374
5375 IT must be initialized via a prior call to init_iterator before
5376 calling this function. */
5377
5378 static void
5379 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5380 struct it *it;
5381 unsigned char *s;
5382 Lisp_Object string;
5383 int charpos;
5384 int precision, field_width, multibyte;
5385 {
5386 /* No region in strings. */
5387 it->region_beg_charpos = it->region_end_charpos = -1;
5388
5389 /* No text property checks performed by default, but see below. */
5390 it->stop_charpos = -1;
5391
5392 /* Set iterator position and end position. */
5393 bzero (&it->current, sizeof it->current);
5394 it->current.overlay_string_index = -1;
5395 it->current.dpvec_index = -1;
5396 xassert (charpos >= 0);
5397
5398 /* If STRING is specified, use its multibyteness, otherwise use the
5399 setting of MULTIBYTE, if specified. */
5400 if (multibyte >= 0)
5401 it->multibyte_p = multibyte > 0;
5402
5403 if (s == NULL)
5404 {
5405 xassert (STRINGP (string));
5406 it->string = string;
5407 it->s = NULL;
5408 it->end_charpos = it->string_nchars = SCHARS (string);
5409 it->method = GET_FROM_STRING;
5410 it->current.string_pos = string_pos (charpos, string);
5411 }
5412 else
5413 {
5414 it->s = s;
5415 it->string = Qnil;
5416
5417 /* Note that we use IT->current.pos, not it->current.string_pos,
5418 for displaying C strings. */
5419 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5420 if (it->multibyte_p)
5421 {
5422 it->current.pos = c_string_pos (charpos, s, 1);
5423 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5424 }
5425 else
5426 {
5427 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5428 it->end_charpos = it->string_nchars = strlen (s);
5429 }
5430
5431 it->method = GET_FROM_C_STRING;
5432 }
5433
5434 /* PRECISION > 0 means don't return more than PRECISION characters
5435 from the string. */
5436 if (precision > 0 && it->end_charpos - charpos > precision)
5437 it->end_charpos = it->string_nchars = charpos + precision;
5438
5439 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5440 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5441 FIELD_WIDTH < 0 means infinite field width. This is useful for
5442 padding with `-' at the end of a mode line. */
5443 if (field_width < 0)
5444 field_width = INFINITY;
5445 if (field_width > it->end_charpos - charpos)
5446 it->end_charpos = charpos + field_width;
5447
5448 /* Use the standard display table for displaying strings. */
5449 if (DISP_TABLE_P (Vstandard_display_table))
5450 it->dp = XCHAR_TABLE (Vstandard_display_table);
5451
5452 it->stop_charpos = charpos;
5453 CHECK_IT (it);
5454 }
5455
5456
5457 \f
5458 /***********************************************************************
5459 Iteration
5460 ***********************************************************************/
5461
5462 /* Map enum it_method value to corresponding next_element_from_* function. */
5463
5464 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5465 {
5466 next_element_from_buffer,
5467 next_element_from_display_vector,
5468 next_element_from_composition,
5469 next_element_from_string,
5470 next_element_from_c_string,
5471 next_element_from_image,
5472 next_element_from_stretch
5473 };
5474
5475
5476 /* Load IT's display element fields with information about the next
5477 display element from the current position of IT. Value is zero if
5478 end of buffer (or C string) is reached. */
5479
5480 static struct frame *last_escape_glyph_frame = NULL;
5481 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5482 static int last_escape_glyph_merged_face_id = 0;
5483
5484 int
5485 get_next_display_element (it)
5486 struct it *it;
5487 {
5488 /* Non-zero means that we found a display element. Zero means that
5489 we hit the end of what we iterate over. Performance note: the
5490 function pointer `method' used here turns out to be faster than
5491 using a sequence of if-statements. */
5492 int success_p;
5493
5494 get_next:
5495 success_p = (*get_next_element[it->method]) (it);
5496
5497 if (it->what == IT_CHARACTER)
5498 {
5499 /* Map via display table or translate control characters.
5500 IT->c, IT->len etc. have been set to the next character by
5501 the function call above. If we have a display table, and it
5502 contains an entry for IT->c, translate it. Don't do this if
5503 IT->c itself comes from a display table, otherwise we could
5504 end up in an infinite recursion. (An alternative could be to
5505 count the recursion depth of this function and signal an
5506 error when a certain maximum depth is reached.) Is it worth
5507 it? */
5508 if (success_p && it->dpvec == NULL)
5509 {
5510 Lisp_Object dv;
5511
5512 if (it->dp
5513 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5514 VECTORP (dv)))
5515 {
5516 struct Lisp_Vector *v = XVECTOR (dv);
5517
5518 /* Return the first character from the display table
5519 entry, if not empty. If empty, don't display the
5520 current character. */
5521 if (v->size)
5522 {
5523 it->dpvec_char_len = it->len;
5524 it->dpvec = v->contents;
5525 it->dpend = v->contents + v->size;
5526 it->current.dpvec_index = 0;
5527 it->dpvec_face_id = -1;
5528 it->saved_face_id = it->face_id;
5529 it->method = GET_FROM_DISPLAY_VECTOR;
5530 it->ellipsis_p = 0;
5531 }
5532 else
5533 {
5534 set_iterator_to_next (it, 0);
5535 }
5536 goto get_next;
5537 }
5538
5539 /* Translate control characters into `\003' or `^C' form.
5540 Control characters coming from a display table entry are
5541 currently not translated because we use IT->dpvec to hold
5542 the translation. This could easily be changed but I
5543 don't believe that it is worth doing.
5544
5545 If it->multibyte_p is nonzero, eight-bit characters and
5546 non-printable multibyte characters are also translated to
5547 octal form.
5548
5549 If it->multibyte_p is zero, eight-bit characters that
5550 don't have corresponding multibyte char code are also
5551 translated to octal form. */
5552 else if ((it->c < ' '
5553 && (it->area != TEXT_AREA
5554 /* In mode line, treat \n like other crl chars. */
5555 || (it->c != '\t'
5556 && it->glyph_row && it->glyph_row->mode_line_p)
5557 || (it->c != '\n' && it->c != '\t')))
5558 || (it->multibyte_p
5559 ? ((it->c >= 127
5560 && it->len == 1)
5561 || !CHAR_PRINTABLE_P (it->c)
5562 || (!NILP (Vnobreak_char_display)
5563 && (it->c == 0x8a0 || it->c == 0x8ad
5564 || it->c == 0x920 || it->c == 0x92d
5565 || it->c == 0xe20 || it->c == 0xe2d
5566 || it->c == 0xf20 || it->c == 0xf2d)))
5567 : (it->c >= 127
5568 && (!unibyte_display_via_language_environment
5569 || it->c == unibyte_char_to_multibyte (it->c)))))
5570 {
5571 /* IT->c is a control character which must be displayed
5572 either as '\003' or as `^C' where the '\\' and '^'
5573 can be defined in the display table. Fill
5574 IT->ctl_chars with glyphs for what we have to
5575 display. Then, set IT->dpvec to these glyphs. */
5576 GLYPH g;
5577 int ctl_len;
5578 int face_id, lface_id = 0 ;
5579 GLYPH escape_glyph;
5580
5581 /* Handle control characters with ^. */
5582
5583 if (it->c < 128 && it->ctl_arrow_p)
5584 {
5585 g = '^'; /* default glyph for Control */
5586 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5587 if (it->dp
5588 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5589 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5590 {
5591 g = XINT (DISP_CTRL_GLYPH (it->dp));
5592 lface_id = FAST_GLYPH_FACE (g);
5593 }
5594 if (lface_id)
5595 {
5596 g = FAST_GLYPH_CHAR (g);
5597 face_id = merge_faces (it->f, Qt, lface_id,
5598 it->face_id);
5599 }
5600 else if (it->f == last_escape_glyph_frame
5601 && it->face_id == last_escape_glyph_face_id)
5602 {
5603 face_id = last_escape_glyph_merged_face_id;
5604 }
5605 else
5606 {
5607 /* Merge the escape-glyph face into the current face. */
5608 face_id = merge_faces (it->f, Qescape_glyph, 0,
5609 it->face_id);
5610 last_escape_glyph_frame = it->f;
5611 last_escape_glyph_face_id = it->face_id;
5612 last_escape_glyph_merged_face_id = face_id;
5613 }
5614
5615 XSETINT (it->ctl_chars[0], g);
5616 g = it->c ^ 0100;
5617 XSETINT (it->ctl_chars[1], g);
5618 ctl_len = 2;
5619 goto display_control;
5620 }
5621
5622 /* Handle non-break space in the mode where it only gets
5623 highlighting. */
5624
5625 if (EQ (Vnobreak_char_display, Qt)
5626 && (it->c == 0x8a0 || it->c == 0x920
5627 || it->c == 0xe20 || it->c == 0xf20))
5628 {
5629 /* Merge the no-break-space face into the current face. */
5630 face_id = merge_faces (it->f, Qnobreak_space, 0,
5631 it->face_id);
5632
5633 g = it->c = ' ';
5634 XSETINT (it->ctl_chars[0], g);
5635 ctl_len = 1;
5636 goto display_control;
5637 }
5638
5639 /* Handle sequences that start with the "escape glyph". */
5640
5641 /* the default escape glyph is \. */
5642 escape_glyph = '\\';
5643
5644 if (it->dp
5645 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5646 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5647 {
5648 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5649 lface_id = FAST_GLYPH_FACE (escape_glyph);
5650 }
5651 if (lface_id)
5652 {
5653 /* The display table specified a face.
5654 Merge it into face_id and also into escape_glyph. */
5655 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5656 face_id = merge_faces (it->f, Qt, lface_id,
5657 it->face_id);
5658 }
5659 else if (it->f == last_escape_glyph_frame
5660 && it->face_id == last_escape_glyph_face_id)
5661 {
5662 face_id = last_escape_glyph_merged_face_id;
5663 }
5664 else
5665 {
5666 /* Merge the escape-glyph face into the current face. */
5667 face_id = merge_faces (it->f, Qescape_glyph, 0,
5668 it->face_id);
5669 last_escape_glyph_frame = it->f;
5670 last_escape_glyph_face_id = it->face_id;
5671 last_escape_glyph_merged_face_id = face_id;
5672 }
5673
5674 /* Handle soft hyphens in the mode where they only get
5675 highlighting. */
5676
5677 if (EQ (Vnobreak_char_display, Qt)
5678 && (it->c == 0x8ad || it->c == 0x92d
5679 || it->c == 0xe2d || it->c == 0xf2d))
5680 {
5681 g = it->c = '-';
5682 XSETINT (it->ctl_chars[0], g);
5683 ctl_len = 1;
5684 goto display_control;
5685 }
5686
5687 /* Handle non-break space and soft hyphen
5688 with the escape glyph. */
5689
5690 if (it->c == 0x8a0 || it->c == 0x8ad
5691 || it->c == 0x920 || it->c == 0x92d
5692 || it->c == 0xe20 || it->c == 0xe2d
5693 || it->c == 0xf20 || it->c == 0xf2d)
5694 {
5695 XSETINT (it->ctl_chars[0], escape_glyph);
5696 g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-');
5697 XSETINT (it->ctl_chars[1], g);
5698 ctl_len = 2;
5699 goto display_control;
5700 }
5701
5702 {
5703 unsigned char str[MAX_MULTIBYTE_LENGTH];
5704 int len;
5705 int i;
5706
5707 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5708 if (SINGLE_BYTE_CHAR_P (it->c))
5709 str[0] = it->c, len = 1;
5710 else
5711 {
5712 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5713 if (len < 0)
5714 {
5715 /* It's an invalid character, which shouldn't
5716 happen actually, but due to bugs it may
5717 happen. Let's print the char as is, there's
5718 not much meaningful we can do with it. */
5719 str[0] = it->c;
5720 str[1] = it->c >> 8;
5721 str[2] = it->c >> 16;
5722 str[3] = it->c >> 24;
5723 len = 4;
5724 }
5725 }
5726
5727 for (i = 0; i < len; i++)
5728 {
5729 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5730 /* Insert three more glyphs into IT->ctl_chars for
5731 the octal display of the character. */
5732 g = ((str[i] >> 6) & 7) + '0';
5733 XSETINT (it->ctl_chars[i * 4 + 1], g);
5734 g = ((str[i] >> 3) & 7) + '0';
5735 XSETINT (it->ctl_chars[i * 4 + 2], g);
5736 g = (str[i] & 7) + '0';
5737 XSETINT (it->ctl_chars[i * 4 + 3], g);
5738 }
5739 ctl_len = len * 4;
5740 }
5741
5742 display_control:
5743 /* Set up IT->dpvec and return first character from it. */
5744 it->dpvec_char_len = it->len;
5745 it->dpvec = it->ctl_chars;
5746 it->dpend = it->dpvec + ctl_len;
5747 it->current.dpvec_index = 0;
5748 it->dpvec_face_id = face_id;
5749 it->saved_face_id = it->face_id;
5750 it->method = GET_FROM_DISPLAY_VECTOR;
5751 it->ellipsis_p = 0;
5752 goto get_next;
5753 }
5754 }
5755
5756 /* Adjust face id for a multibyte character. There are no
5757 multibyte character in unibyte text. */
5758 if (it->multibyte_p
5759 && success_p
5760 && FRAME_WINDOW_P (it->f))
5761 {
5762 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5763 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5764 }
5765 }
5766
5767 /* Is this character the last one of a run of characters with
5768 box? If yes, set IT->end_of_box_run_p to 1. */
5769 if (it->face_box_p
5770 && it->s == NULL)
5771 {
5772 int face_id;
5773 struct face *face;
5774
5775 it->end_of_box_run_p
5776 = ((face_id = face_after_it_pos (it),
5777 face_id != it->face_id)
5778 && (face = FACE_FROM_ID (it->f, face_id),
5779 face->box == FACE_NO_BOX));
5780 }
5781
5782 /* Value is 0 if end of buffer or string reached. */
5783 return success_p;
5784 }
5785
5786
5787 /* Move IT to the next display element.
5788
5789 RESEAT_P non-zero means if called on a newline in buffer text,
5790 skip to the next visible line start.
5791
5792 Functions get_next_display_element and set_iterator_to_next are
5793 separate because I find this arrangement easier to handle than a
5794 get_next_display_element function that also increments IT's
5795 position. The way it is we can first look at an iterator's current
5796 display element, decide whether it fits on a line, and if it does,
5797 increment the iterator position. The other way around we probably
5798 would either need a flag indicating whether the iterator has to be
5799 incremented the next time, or we would have to implement a
5800 decrement position function which would not be easy to write. */
5801
5802 void
5803 set_iterator_to_next (it, reseat_p)
5804 struct it *it;
5805 int reseat_p;
5806 {
5807 /* Reset flags indicating start and end of a sequence of characters
5808 with box. Reset them at the start of this function because
5809 moving the iterator to a new position might set them. */
5810 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5811
5812 switch (it->method)
5813 {
5814 case GET_FROM_BUFFER:
5815 /* The current display element of IT is a character from
5816 current_buffer. Advance in the buffer, and maybe skip over
5817 invisible lines that are so because of selective display. */
5818 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5819 reseat_at_next_visible_line_start (it, 0);
5820 else
5821 {
5822 xassert (it->len != 0);
5823 IT_BYTEPOS (*it) += it->len;
5824 IT_CHARPOS (*it) += 1;
5825 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5826 }
5827 break;
5828
5829 case GET_FROM_COMPOSITION:
5830 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5831 xassert (it->sp > 0);
5832 pop_it (it);
5833 if (it->method == GET_FROM_STRING)
5834 {
5835 IT_STRING_BYTEPOS (*it) += it->len;
5836 IT_STRING_CHARPOS (*it) += it->cmp_len;
5837 goto consider_string_end;
5838 }
5839 else if (it->method == GET_FROM_BUFFER)
5840 {
5841 IT_BYTEPOS (*it) += it->len;
5842 IT_CHARPOS (*it) += it->cmp_len;
5843 }
5844 break;
5845
5846 case GET_FROM_C_STRING:
5847 /* Current display element of IT is from a C string. */
5848 IT_BYTEPOS (*it) += it->len;
5849 IT_CHARPOS (*it) += 1;
5850 break;
5851
5852 case GET_FROM_DISPLAY_VECTOR:
5853 /* Current display element of IT is from a display table entry.
5854 Advance in the display table definition. Reset it to null if
5855 end reached, and continue with characters from buffers/
5856 strings. */
5857 ++it->current.dpvec_index;
5858
5859 /* Restore face of the iterator to what they were before the
5860 display vector entry (these entries may contain faces). */
5861 it->face_id = it->saved_face_id;
5862
5863 if (it->dpvec + it->current.dpvec_index == it->dpend)
5864 {
5865 int recheck_faces = it->ellipsis_p;
5866
5867 if (it->s)
5868 it->method = GET_FROM_C_STRING;
5869 else if (STRINGP (it->string))
5870 it->method = GET_FROM_STRING;
5871 else
5872 {
5873 it->method = GET_FROM_BUFFER;
5874 it->object = it->w->buffer;
5875 }
5876
5877 it->dpvec = NULL;
5878 it->current.dpvec_index = -1;
5879
5880 /* Skip over characters which were displayed via IT->dpvec. */
5881 if (it->dpvec_char_len < 0)
5882 reseat_at_next_visible_line_start (it, 1);
5883 else if (it->dpvec_char_len > 0)
5884 {
5885 if (it->method == GET_FROM_STRING
5886 && it->n_overlay_strings > 0)
5887 it->ignore_overlay_strings_at_pos_p = 1;
5888 it->len = it->dpvec_char_len;
5889 set_iterator_to_next (it, reseat_p);
5890 }
5891
5892 /* Maybe recheck faces after display vector */
5893 if (recheck_faces)
5894 it->stop_charpos = IT_CHARPOS (*it);
5895 }
5896 break;
5897
5898 case GET_FROM_STRING:
5899 /* Current display element is a character from a Lisp string. */
5900 xassert (it->s == NULL && STRINGP (it->string));
5901 IT_STRING_BYTEPOS (*it) += it->len;
5902 IT_STRING_CHARPOS (*it) += 1;
5903
5904 consider_string_end:
5905
5906 if (it->current.overlay_string_index >= 0)
5907 {
5908 /* IT->string is an overlay string. Advance to the
5909 next, if there is one. */
5910 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5911 next_overlay_string (it);
5912 }
5913 else
5914 {
5915 /* IT->string is not an overlay string. If we reached
5916 its end, and there is something on IT->stack, proceed
5917 with what is on the stack. This can be either another
5918 string, this time an overlay string, or a buffer. */
5919 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5920 && it->sp > 0)
5921 {
5922 pop_it (it);
5923 if (it->method == GET_FROM_STRING)
5924 goto consider_string_end;
5925 }
5926 }
5927 break;
5928
5929 case GET_FROM_IMAGE:
5930 case GET_FROM_STRETCH:
5931 /* The position etc with which we have to proceed are on
5932 the stack. The position may be at the end of a string,
5933 if the `display' property takes up the whole string. */
5934 xassert (it->sp > 0);
5935 pop_it (it);
5936 if (it->method == GET_FROM_STRING)
5937 goto consider_string_end;
5938 break;
5939
5940 default:
5941 /* There are no other methods defined, so this should be a bug. */
5942 abort ();
5943 }
5944
5945 xassert (it->method != GET_FROM_STRING
5946 || (STRINGP (it->string)
5947 && IT_STRING_CHARPOS (*it) >= 0));
5948 }
5949
5950 /* Load IT's display element fields with information about the next
5951 display element which comes from a display table entry or from the
5952 result of translating a control character to one of the forms `^C'
5953 or `\003'.
5954
5955 IT->dpvec holds the glyphs to return as characters.
5956 IT->saved_face_id holds the face id before the display vector--
5957 it is restored into IT->face_idin set_iterator_to_next. */
5958
5959 static int
5960 next_element_from_display_vector (it)
5961 struct it *it;
5962 {
5963 /* Precondition. */
5964 xassert (it->dpvec && it->current.dpvec_index >= 0);
5965
5966 it->face_id = it->saved_face_id;
5967
5968 if (INTEGERP (*it->dpvec)
5969 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5970 {
5971 GLYPH g;
5972
5973 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5974 it->c = FAST_GLYPH_CHAR (g);
5975 it->len = CHAR_BYTES (it->c);
5976
5977 /* The entry may contain a face id to use. Such a face id is
5978 the id of a Lisp face, not a realized face. A face id of
5979 zero means no face is specified. */
5980 if (it->dpvec_face_id >= 0)
5981 it->face_id = it->dpvec_face_id;
5982 else
5983 {
5984 int lface_id = FAST_GLYPH_FACE (g);
5985 if (lface_id > 0)
5986 it->face_id = merge_faces (it->f, Qt, lface_id,
5987 it->saved_face_id);
5988 }
5989 }
5990 else
5991 /* Display table entry is invalid. Return a space. */
5992 it->c = ' ', it->len = 1;
5993
5994 /* Don't change position and object of the iterator here. They are
5995 still the values of the character that had this display table
5996 entry or was translated, and that's what we want. */
5997 it->what = IT_CHARACTER;
5998 return 1;
5999 }
6000
6001
6002 /* Load IT with the next display element from Lisp string IT->string.
6003 IT->current.string_pos is the current position within the string.
6004 If IT->current.overlay_string_index >= 0, the Lisp string is an
6005 overlay string. */
6006
6007 static int
6008 next_element_from_string (it)
6009 struct it *it;
6010 {
6011 struct text_pos position;
6012
6013 xassert (STRINGP (it->string));
6014 xassert (IT_STRING_CHARPOS (*it) >= 0);
6015 position = it->current.string_pos;
6016
6017 /* Time to check for invisible text? */
6018 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6019 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6020 {
6021 handle_stop (it);
6022
6023 /* Since a handler may have changed IT->method, we must
6024 recurse here. */
6025 return get_next_display_element (it);
6026 }
6027
6028 if (it->current.overlay_string_index >= 0)
6029 {
6030 /* Get the next character from an overlay string. In overlay
6031 strings, There is no field width or padding with spaces to
6032 do. */
6033 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6034 {
6035 it->what = IT_EOB;
6036 return 0;
6037 }
6038 else if (STRING_MULTIBYTE (it->string))
6039 {
6040 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6041 const unsigned char *s = (SDATA (it->string)
6042 + IT_STRING_BYTEPOS (*it));
6043 it->c = string_char_and_length (s, remaining, &it->len);
6044 }
6045 else
6046 {
6047 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6048 it->len = 1;
6049 }
6050 }
6051 else
6052 {
6053 /* Get the next character from a Lisp string that is not an
6054 overlay string. Such strings come from the mode line, for
6055 example. We may have to pad with spaces, or truncate the
6056 string. See also next_element_from_c_string. */
6057 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6058 {
6059 it->what = IT_EOB;
6060 return 0;
6061 }
6062 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6063 {
6064 /* Pad with spaces. */
6065 it->c = ' ', it->len = 1;
6066 CHARPOS (position) = BYTEPOS (position) = -1;
6067 }
6068 else if (STRING_MULTIBYTE (it->string))
6069 {
6070 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6071 const unsigned char *s = (SDATA (it->string)
6072 + IT_STRING_BYTEPOS (*it));
6073 it->c = string_char_and_length (s, maxlen, &it->len);
6074 }
6075 else
6076 {
6077 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6078 it->len = 1;
6079 }
6080 }
6081
6082 /* Record what we have and where it came from. */
6083 it->what = IT_CHARACTER;
6084 it->object = it->string;
6085 it->position = position;
6086 return 1;
6087 }
6088
6089
6090 /* Load IT with next display element from C string IT->s.
6091 IT->string_nchars is the maximum number of characters to return
6092 from the string. IT->end_charpos may be greater than
6093 IT->string_nchars when this function is called, in which case we
6094 may have to return padding spaces. Value is zero if end of string
6095 reached, including padding spaces. */
6096
6097 static int
6098 next_element_from_c_string (it)
6099 struct it *it;
6100 {
6101 int success_p = 1;
6102
6103 xassert (it->s);
6104 it->what = IT_CHARACTER;
6105 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6106 it->object = Qnil;
6107
6108 /* IT's position can be greater IT->string_nchars in case a field
6109 width or precision has been specified when the iterator was
6110 initialized. */
6111 if (IT_CHARPOS (*it) >= it->end_charpos)
6112 {
6113 /* End of the game. */
6114 it->what = IT_EOB;
6115 success_p = 0;
6116 }
6117 else if (IT_CHARPOS (*it) >= it->string_nchars)
6118 {
6119 /* Pad with spaces. */
6120 it->c = ' ', it->len = 1;
6121 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6122 }
6123 else if (it->multibyte_p)
6124 {
6125 /* Implementation note: The calls to strlen apparently aren't a
6126 performance problem because there is no noticeable performance
6127 difference between Emacs running in unibyte or multibyte mode. */
6128 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6129 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
6130 maxlen, &it->len);
6131 }
6132 else
6133 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6134
6135 return success_p;
6136 }
6137
6138
6139 /* Set up IT to return characters from an ellipsis, if appropriate.
6140 The definition of the ellipsis glyphs may come from a display table
6141 entry. This function Fills IT with the first glyph from the
6142 ellipsis if an ellipsis is to be displayed. */
6143
6144 static int
6145 next_element_from_ellipsis (it)
6146 struct it *it;
6147 {
6148 if (it->selective_display_ellipsis_p)
6149 setup_for_ellipsis (it, it->len);
6150 else
6151 {
6152 /* The face at the current position may be different from the
6153 face we find after the invisible text. Remember what it
6154 was in IT->saved_face_id, and signal that it's there by
6155 setting face_before_selective_p. */
6156 it->saved_face_id = it->face_id;
6157 it->method = GET_FROM_BUFFER;
6158 it->object = it->w->buffer;
6159 reseat_at_next_visible_line_start (it, 1);
6160 it->face_before_selective_p = 1;
6161 }
6162
6163 return get_next_display_element (it);
6164 }
6165
6166
6167 /* Deliver an image display element. The iterator IT is already
6168 filled with image information (done in handle_display_prop). Value
6169 is always 1. */
6170
6171
6172 static int
6173 next_element_from_image (it)
6174 struct it *it;
6175 {
6176 it->what = IT_IMAGE;
6177 return 1;
6178 }
6179
6180
6181 /* Fill iterator IT with next display element from a stretch glyph
6182 property. IT->object is the value of the text property. Value is
6183 always 1. */
6184
6185 static int
6186 next_element_from_stretch (it)
6187 struct it *it;
6188 {
6189 it->what = IT_STRETCH;
6190 return 1;
6191 }
6192
6193
6194 /* Load IT with the next display element from current_buffer. Value
6195 is zero if end of buffer reached. IT->stop_charpos is the next
6196 position at which to stop and check for text properties or buffer
6197 end. */
6198
6199 static int
6200 next_element_from_buffer (it)
6201 struct it *it;
6202 {
6203 int success_p = 1;
6204
6205 /* Check this assumption, otherwise, we would never enter the
6206 if-statement, below. */
6207 xassert (IT_CHARPOS (*it) >= BEGV
6208 && IT_CHARPOS (*it) <= it->stop_charpos);
6209
6210 if (IT_CHARPOS (*it) >= it->stop_charpos)
6211 {
6212 if (IT_CHARPOS (*it) >= it->end_charpos)
6213 {
6214 int overlay_strings_follow_p;
6215
6216 /* End of the game, except when overlay strings follow that
6217 haven't been returned yet. */
6218 if (it->overlay_strings_at_end_processed_p)
6219 overlay_strings_follow_p = 0;
6220 else
6221 {
6222 it->overlay_strings_at_end_processed_p = 1;
6223 overlay_strings_follow_p = get_overlay_strings (it, 0);
6224 }
6225
6226 if (overlay_strings_follow_p)
6227 success_p = get_next_display_element (it);
6228 else
6229 {
6230 it->what = IT_EOB;
6231 it->position = it->current.pos;
6232 success_p = 0;
6233 }
6234 }
6235 else
6236 {
6237 handle_stop (it);
6238 return get_next_display_element (it);
6239 }
6240 }
6241 else
6242 {
6243 /* No face changes, overlays etc. in sight, so just return a
6244 character from current_buffer. */
6245 unsigned char *p;
6246
6247 /* Maybe run the redisplay end trigger hook. Performance note:
6248 This doesn't seem to cost measurable time. */
6249 if (it->redisplay_end_trigger_charpos
6250 && it->glyph_row
6251 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6252 run_redisplay_end_trigger_hook (it);
6253
6254 /* Get the next character, maybe multibyte. */
6255 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6256 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6257 {
6258 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
6259 - IT_BYTEPOS (*it));
6260 it->c = string_char_and_length (p, maxlen, &it->len);
6261 }
6262 else
6263 it->c = *p, it->len = 1;
6264
6265 /* Record what we have and where it came from. */
6266 it->what = IT_CHARACTER;;
6267 it->object = it->w->buffer;
6268 it->position = it->current.pos;
6269
6270 /* Normally we return the character found above, except when we
6271 really want to return an ellipsis for selective display. */
6272 if (it->selective)
6273 {
6274 if (it->c == '\n')
6275 {
6276 /* A value of selective > 0 means hide lines indented more
6277 than that number of columns. */
6278 if (it->selective > 0
6279 && IT_CHARPOS (*it) + 1 < ZV
6280 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6281 IT_BYTEPOS (*it) + 1,
6282 (double) it->selective)) /* iftc */
6283 {
6284 success_p = next_element_from_ellipsis (it);
6285 it->dpvec_char_len = -1;
6286 }
6287 }
6288 else if (it->c == '\r' && it->selective == -1)
6289 {
6290 /* A value of selective == -1 means that everything from the
6291 CR to the end of the line is invisible, with maybe an
6292 ellipsis displayed for it. */
6293 success_p = next_element_from_ellipsis (it);
6294 it->dpvec_char_len = -1;
6295 }
6296 }
6297 }
6298
6299 /* Value is zero if end of buffer reached. */
6300 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6301 return success_p;
6302 }
6303
6304
6305 /* Run the redisplay end trigger hook for IT. */
6306
6307 static void
6308 run_redisplay_end_trigger_hook (it)
6309 struct it *it;
6310 {
6311 Lisp_Object args[3];
6312
6313 /* IT->glyph_row should be non-null, i.e. we should be actually
6314 displaying something, or otherwise we should not run the hook. */
6315 xassert (it->glyph_row);
6316
6317 /* Set up hook arguments. */
6318 args[0] = Qredisplay_end_trigger_functions;
6319 args[1] = it->window;
6320 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6321 it->redisplay_end_trigger_charpos = 0;
6322
6323 /* Since we are *trying* to run these functions, don't try to run
6324 them again, even if they get an error. */
6325 it->w->redisplay_end_trigger = Qnil;
6326 Frun_hook_with_args (3, args);
6327
6328 /* Notice if it changed the face of the character we are on. */
6329 handle_face_prop (it);
6330 }
6331
6332
6333 /* Deliver a composition display element. The iterator IT is already
6334 filled with composition information (done in
6335 handle_composition_prop). Value is always 1. */
6336
6337 static int
6338 next_element_from_composition (it)
6339 struct it *it;
6340 {
6341 it->what = IT_COMPOSITION;
6342 it->position = (STRINGP (it->string)
6343 ? it->current.string_pos
6344 : it->current.pos);
6345 if (STRINGP (it->string))
6346 it->object = it->string;
6347 else
6348 it->object = it->w->buffer;
6349 return 1;
6350 }
6351
6352
6353 \f
6354 /***********************************************************************
6355 Moving an iterator without producing glyphs
6356 ***********************************************************************/
6357
6358 /* Check if iterator is at a position corresponding to a valid buffer
6359 position after some move_it_ call. */
6360
6361 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6362 ((it)->method == GET_FROM_STRING \
6363 ? IT_STRING_CHARPOS (*it) == 0 \
6364 : 1)
6365
6366
6367 /* Move iterator IT to a specified buffer or X position within one
6368 line on the display without producing glyphs.
6369
6370 OP should be a bit mask including some or all of these bits:
6371 MOVE_TO_X: Stop on reaching x-position TO_X.
6372 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
6373 Regardless of OP's value, stop in reaching the end of the display line.
6374
6375 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6376 This means, in particular, that TO_X includes window's horizontal
6377 scroll amount.
6378
6379 The return value has several possible values that
6380 say what condition caused the scan to stop:
6381
6382 MOVE_POS_MATCH_OR_ZV
6383 - when TO_POS or ZV was reached.
6384
6385 MOVE_X_REACHED
6386 -when TO_X was reached before TO_POS or ZV were reached.
6387
6388 MOVE_LINE_CONTINUED
6389 - when we reached the end of the display area and the line must
6390 be continued.
6391
6392 MOVE_LINE_TRUNCATED
6393 - when we reached the end of the display area and the line is
6394 truncated.
6395
6396 MOVE_NEWLINE_OR_CR
6397 - when we stopped at a line end, i.e. a newline or a CR and selective
6398 display is on. */
6399
6400 static enum move_it_result
6401 move_it_in_display_line_to (it, to_charpos, to_x, op)
6402 struct it *it;
6403 int to_charpos, to_x, op;
6404 {
6405 enum move_it_result result = MOVE_UNDEFINED;
6406 struct glyph_row *saved_glyph_row;
6407
6408 /* Don't produce glyphs in produce_glyphs. */
6409 saved_glyph_row = it->glyph_row;
6410 it->glyph_row = NULL;
6411
6412 #define BUFFER_POS_REACHED_P() \
6413 ((op & MOVE_TO_POS) != 0 \
6414 && BUFFERP (it->object) \
6415 && IT_CHARPOS (*it) >= to_charpos \
6416 && (it->method == GET_FROM_BUFFER \
6417 || (it->method == GET_FROM_DISPLAY_VECTOR \
6418 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6419
6420
6421 while (1)
6422 {
6423 int x, i, ascent = 0, descent = 0;
6424
6425 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
6426 if ((op & MOVE_TO_POS) != 0
6427 && BUFFERP (it->object)
6428 && it->method == GET_FROM_BUFFER
6429 && IT_CHARPOS (*it) > to_charpos)
6430 {
6431 result = MOVE_POS_MATCH_OR_ZV;
6432 break;
6433 }
6434
6435 /* Stop when ZV reached.
6436 We used to stop here when TO_CHARPOS reached as well, but that is
6437 too soon if this glyph does not fit on this line. So we handle it
6438 explicitly below. */
6439 if (!get_next_display_element (it)
6440 || (it->truncate_lines_p
6441 && BUFFER_POS_REACHED_P ()))
6442 {
6443 result = MOVE_POS_MATCH_OR_ZV;
6444 break;
6445 }
6446
6447 /* The call to produce_glyphs will get the metrics of the
6448 display element IT is loaded with. We record in x the
6449 x-position before this display element in case it does not
6450 fit on the line. */
6451 x = it->current_x;
6452
6453 /* Remember the line height so far in case the next element doesn't
6454 fit on the line. */
6455 if (!it->truncate_lines_p)
6456 {
6457 ascent = it->max_ascent;
6458 descent = it->max_descent;
6459 }
6460
6461 PRODUCE_GLYPHS (it);
6462
6463 if (it->area != TEXT_AREA)
6464 {
6465 set_iterator_to_next (it, 1);
6466 continue;
6467 }
6468
6469 /* The number of glyphs we get back in IT->nglyphs will normally
6470 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
6471 character on a terminal frame, or (iii) a line end. For the
6472 second case, IT->nglyphs - 1 padding glyphs will be present
6473 (on X frames, there is only one glyph produced for a
6474 composite character.
6475
6476 The behavior implemented below means, for continuation lines,
6477 that as many spaces of a TAB as fit on the current line are
6478 displayed there. For terminal frames, as many glyphs of a
6479 multi-glyph character are displayed in the current line, too.
6480 This is what the old redisplay code did, and we keep it that
6481 way. Under X, the whole shape of a complex character must
6482 fit on the line or it will be completely displayed in the
6483 next line.
6484
6485 Note that both for tabs and padding glyphs, all glyphs have
6486 the same width. */
6487 if (it->nglyphs)
6488 {
6489 /* More than one glyph or glyph doesn't fit on line. All
6490 glyphs have the same width. */
6491 int single_glyph_width = it->pixel_width / it->nglyphs;
6492 int new_x;
6493 int x_before_this_char = x;
6494 int hpos_before_this_char = it->hpos;
6495
6496 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6497 {
6498 new_x = x + single_glyph_width;
6499
6500 /* We want to leave anything reaching TO_X to the caller. */
6501 if ((op & MOVE_TO_X) && new_x > to_x)
6502 {
6503 if (BUFFER_POS_REACHED_P ())
6504 goto buffer_pos_reached;
6505 it->current_x = x;
6506 result = MOVE_X_REACHED;
6507 break;
6508 }
6509 else if (/* Lines are continued. */
6510 !it->truncate_lines_p
6511 && (/* And glyph doesn't fit on the line. */
6512 new_x > it->last_visible_x
6513 /* Or it fits exactly and we're on a window
6514 system frame. */
6515 || (new_x == it->last_visible_x
6516 && FRAME_WINDOW_P (it->f))))
6517 {
6518 if (/* IT->hpos == 0 means the very first glyph
6519 doesn't fit on the line, e.g. a wide image. */
6520 it->hpos == 0
6521 || (new_x == it->last_visible_x
6522 && FRAME_WINDOW_P (it->f)))
6523 {
6524 ++it->hpos;
6525 it->current_x = new_x;
6526
6527 /* The character's last glyph just barely fits
6528 in this row. */
6529 if (i == it->nglyphs - 1)
6530 {
6531 /* If this is the destination position,
6532 return a position *before* it in this row,
6533 now that we know it fits in this row. */
6534 if (BUFFER_POS_REACHED_P ())
6535 {
6536 it->hpos = hpos_before_this_char;
6537 it->current_x = x_before_this_char;
6538 result = MOVE_POS_MATCH_OR_ZV;
6539 break;
6540 }
6541
6542 set_iterator_to_next (it, 1);
6543 #ifdef HAVE_WINDOW_SYSTEM
6544 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6545 {
6546 if (!get_next_display_element (it))
6547 {
6548 result = MOVE_POS_MATCH_OR_ZV;
6549 break;
6550 }
6551 if (BUFFER_POS_REACHED_P ())
6552 {
6553 if (ITERATOR_AT_END_OF_LINE_P (it))
6554 result = MOVE_POS_MATCH_OR_ZV;
6555 else
6556 result = MOVE_LINE_CONTINUED;
6557 break;
6558 }
6559 if (ITERATOR_AT_END_OF_LINE_P (it))
6560 {
6561 result = MOVE_NEWLINE_OR_CR;
6562 break;
6563 }
6564 }
6565 #endif /* HAVE_WINDOW_SYSTEM */
6566 }
6567 }
6568 else
6569 {
6570 it->current_x = x;
6571 it->max_ascent = ascent;
6572 it->max_descent = descent;
6573 }
6574
6575 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6576 IT_CHARPOS (*it)));
6577 result = MOVE_LINE_CONTINUED;
6578 break;
6579 }
6580 else if (BUFFER_POS_REACHED_P ())
6581 goto buffer_pos_reached;
6582 else if (new_x > it->first_visible_x)
6583 {
6584 /* Glyph is visible. Increment number of glyphs that
6585 would be displayed. */
6586 ++it->hpos;
6587 }
6588 else
6589 {
6590 /* Glyph is completely off the left margin of the display
6591 area. Nothing to do. */
6592 }
6593 }
6594
6595 if (result != MOVE_UNDEFINED)
6596 break;
6597 }
6598 else if (BUFFER_POS_REACHED_P ())
6599 {
6600 buffer_pos_reached:
6601 it->current_x = x;
6602 it->max_ascent = ascent;
6603 it->max_descent = descent;
6604 result = MOVE_POS_MATCH_OR_ZV;
6605 break;
6606 }
6607 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6608 {
6609 /* Stop when TO_X specified and reached. This check is
6610 necessary here because of lines consisting of a line end,
6611 only. The line end will not produce any glyphs and we
6612 would never get MOVE_X_REACHED. */
6613 xassert (it->nglyphs == 0);
6614 result = MOVE_X_REACHED;
6615 break;
6616 }
6617
6618 /* Is this a line end? If yes, we're done. */
6619 if (ITERATOR_AT_END_OF_LINE_P (it))
6620 {
6621 result = MOVE_NEWLINE_OR_CR;
6622 break;
6623 }
6624
6625 /* The current display element has been consumed. Advance
6626 to the next. */
6627 set_iterator_to_next (it, 1);
6628
6629 /* Stop if lines are truncated and IT's current x-position is
6630 past the right edge of the window now. */
6631 if (it->truncate_lines_p
6632 && it->current_x >= it->last_visible_x)
6633 {
6634 #ifdef HAVE_WINDOW_SYSTEM
6635 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6636 {
6637 if (!get_next_display_element (it)
6638 || BUFFER_POS_REACHED_P ())
6639 {
6640 result = MOVE_POS_MATCH_OR_ZV;
6641 break;
6642 }
6643 if (ITERATOR_AT_END_OF_LINE_P (it))
6644 {
6645 result = MOVE_NEWLINE_OR_CR;
6646 break;
6647 }
6648 }
6649 #endif /* HAVE_WINDOW_SYSTEM */
6650 result = MOVE_LINE_TRUNCATED;
6651 break;
6652 }
6653 }
6654
6655 #undef BUFFER_POS_REACHED_P
6656
6657 /* Restore the iterator settings altered at the beginning of this
6658 function. */
6659 it->glyph_row = saved_glyph_row;
6660 return result;
6661 }
6662
6663
6664 /* Move IT forward until it satisfies one or more of the criteria in
6665 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6666
6667 OP is a bit-mask that specifies where to stop, and in particular,
6668 which of those four position arguments makes a difference. See the
6669 description of enum move_operation_enum.
6670
6671 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6672 screen line, this function will set IT to the next position >
6673 TO_CHARPOS. */
6674
6675 void
6676 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6677 struct it *it;
6678 int to_charpos, to_x, to_y, to_vpos;
6679 int op;
6680 {
6681 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6682 int line_height;
6683 int reached = 0;
6684
6685 for (;;)
6686 {
6687 if (op & MOVE_TO_VPOS)
6688 {
6689 /* If no TO_CHARPOS and no TO_X specified, stop at the
6690 start of the line TO_VPOS. */
6691 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6692 {
6693 if (it->vpos == to_vpos)
6694 {
6695 reached = 1;
6696 break;
6697 }
6698 else
6699 skip = move_it_in_display_line_to (it, -1, -1, 0);
6700 }
6701 else
6702 {
6703 /* TO_VPOS >= 0 means stop at TO_X in the line at
6704 TO_VPOS, or at TO_POS, whichever comes first. */
6705 if (it->vpos == to_vpos)
6706 {
6707 reached = 2;
6708 break;
6709 }
6710
6711 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6712
6713 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6714 {
6715 reached = 3;
6716 break;
6717 }
6718 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6719 {
6720 /* We have reached TO_X but not in the line we want. */
6721 skip = move_it_in_display_line_to (it, to_charpos,
6722 -1, MOVE_TO_POS);
6723 if (skip == MOVE_POS_MATCH_OR_ZV)
6724 {
6725 reached = 4;
6726 break;
6727 }
6728 }
6729 }
6730 }
6731 else if (op & MOVE_TO_Y)
6732 {
6733 struct it it_backup;
6734
6735 /* TO_Y specified means stop at TO_X in the line containing
6736 TO_Y---or at TO_CHARPOS if this is reached first. The
6737 problem is that we can't really tell whether the line
6738 contains TO_Y before we have completely scanned it, and
6739 this may skip past TO_X. What we do is to first scan to
6740 TO_X.
6741
6742 If TO_X is not specified, use a TO_X of zero. The reason
6743 is to make the outcome of this function more predictable.
6744 If we didn't use TO_X == 0, we would stop at the end of
6745 the line which is probably not what a caller would expect
6746 to happen. */
6747 skip = move_it_in_display_line_to (it, to_charpos,
6748 ((op & MOVE_TO_X)
6749 ? to_x : 0),
6750 (MOVE_TO_X
6751 | (op & MOVE_TO_POS)));
6752
6753 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6754 if (skip == MOVE_POS_MATCH_OR_ZV)
6755 {
6756 reached = 5;
6757 break;
6758 }
6759
6760 /* If TO_X was reached, we would like to know whether TO_Y
6761 is in the line. This can only be said if we know the
6762 total line height which requires us to scan the rest of
6763 the line. */
6764 if (skip == MOVE_X_REACHED)
6765 {
6766 it_backup = *it;
6767 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6768 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6769 op & MOVE_TO_POS);
6770 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6771 }
6772
6773 /* Now, decide whether TO_Y is in this line. */
6774 line_height = it->max_ascent + it->max_descent;
6775 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6776
6777 if (to_y >= it->current_y
6778 && to_y < it->current_y + line_height)
6779 {
6780 if (skip == MOVE_X_REACHED)
6781 /* If TO_Y is in this line and TO_X was reached above,
6782 we scanned too far. We have to restore IT's settings
6783 to the ones before skipping. */
6784 *it = it_backup;
6785 reached = 6;
6786 }
6787 else if (skip == MOVE_X_REACHED)
6788 {
6789 skip = skip2;
6790 if (skip == MOVE_POS_MATCH_OR_ZV)
6791 reached = 7;
6792 }
6793
6794 if (reached)
6795 break;
6796 }
6797 else if (BUFFERP (it->object)
6798 && it->method == GET_FROM_BUFFER
6799 && IT_CHARPOS (*it) >= to_charpos)
6800 skip = MOVE_POS_MATCH_OR_ZV;
6801 else
6802 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6803
6804 switch (skip)
6805 {
6806 case MOVE_POS_MATCH_OR_ZV:
6807 reached = 8;
6808 goto out;
6809
6810 case MOVE_NEWLINE_OR_CR:
6811 set_iterator_to_next (it, 1);
6812 it->continuation_lines_width = 0;
6813 break;
6814
6815 case MOVE_LINE_TRUNCATED:
6816 it->continuation_lines_width = 0;
6817 reseat_at_next_visible_line_start (it, 0);
6818 if ((op & MOVE_TO_POS) != 0
6819 && IT_CHARPOS (*it) > to_charpos)
6820 {
6821 reached = 9;
6822 goto out;
6823 }
6824 break;
6825
6826 case MOVE_LINE_CONTINUED:
6827 it->continuation_lines_width += it->current_x;
6828 break;
6829
6830 default:
6831 abort ();
6832 }
6833
6834 /* Reset/increment for the next run. */
6835 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6836 it->current_x = it->hpos = 0;
6837 it->current_y += it->max_ascent + it->max_descent;
6838 ++it->vpos;
6839 last_height = it->max_ascent + it->max_descent;
6840 last_max_ascent = it->max_ascent;
6841 it->max_ascent = it->max_descent = 0;
6842 }
6843
6844 out:
6845
6846 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6847 }
6848
6849
6850 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6851
6852 If DY > 0, move IT backward at least that many pixels. DY = 0
6853 means move IT backward to the preceding line start or BEGV. This
6854 function may move over more than DY pixels if IT->current_y - DY
6855 ends up in the middle of a line; in this case IT->current_y will be
6856 set to the top of the line moved to. */
6857
6858 void
6859 move_it_vertically_backward (it, dy)
6860 struct it *it;
6861 int dy;
6862 {
6863 int nlines, h;
6864 struct it it2, it3;
6865 int start_pos;
6866
6867 move_further_back:
6868 xassert (dy >= 0);
6869
6870 start_pos = IT_CHARPOS (*it);
6871
6872 /* Estimate how many newlines we must move back. */
6873 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6874
6875 /* Set the iterator's position that many lines back. */
6876 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6877 back_to_previous_visible_line_start (it);
6878
6879 /* Reseat the iterator here. When moving backward, we don't want
6880 reseat to skip forward over invisible text, set up the iterator
6881 to deliver from overlay strings at the new position etc. So,
6882 use reseat_1 here. */
6883 reseat_1 (it, it->current.pos, 1);
6884
6885 /* We are now surely at a line start. */
6886 it->current_x = it->hpos = 0;
6887 it->continuation_lines_width = 0;
6888
6889 /* Move forward and see what y-distance we moved. First move to the
6890 start of the next line so that we get its height. We need this
6891 height to be able to tell whether we reached the specified
6892 y-distance. */
6893 it2 = *it;
6894 it2.max_ascent = it2.max_descent = 0;
6895 do
6896 {
6897 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6898 MOVE_TO_POS | MOVE_TO_VPOS);
6899 }
6900 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
6901 xassert (IT_CHARPOS (*it) >= BEGV);
6902 it3 = it2;
6903
6904 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6905 xassert (IT_CHARPOS (*it) >= BEGV);
6906 /* H is the actual vertical distance from the position in *IT
6907 and the starting position. */
6908 h = it2.current_y - it->current_y;
6909 /* NLINES is the distance in number of lines. */
6910 nlines = it2.vpos - it->vpos;
6911
6912 /* Correct IT's y and vpos position
6913 so that they are relative to the starting point. */
6914 it->vpos -= nlines;
6915 it->current_y -= h;
6916
6917 if (dy == 0)
6918 {
6919 /* DY == 0 means move to the start of the screen line. The
6920 value of nlines is > 0 if continuation lines were involved. */
6921 if (nlines > 0)
6922 move_it_by_lines (it, nlines, 1);
6923 #if 0
6924 /* I think this assert is bogus if buffer contains
6925 invisible text or images. KFS. */
6926 xassert (IT_CHARPOS (*it) <= start_pos);
6927 #endif
6928 }
6929 else
6930 {
6931 /* The y-position we try to reach, relative to *IT.
6932 Note that H has been subtracted in front of the if-statement. */
6933 int target_y = it->current_y + h - dy;
6934 int y0 = it3.current_y;
6935 int y1 = line_bottom_y (&it3);
6936 int line_height = y1 - y0;
6937
6938 /* If we did not reach target_y, try to move further backward if
6939 we can. If we moved too far backward, try to move forward. */
6940 if (target_y < it->current_y
6941 /* This is heuristic. In a window that's 3 lines high, with
6942 a line height of 13 pixels each, recentering with point
6943 on the bottom line will try to move -39/2 = 19 pixels
6944 backward. Try to avoid moving into the first line. */
6945 && (it->current_y - target_y
6946 > min (window_box_height (it->w), line_height * 2 / 3))
6947 && IT_CHARPOS (*it) > BEGV)
6948 {
6949 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6950 target_y - it->current_y));
6951 dy = it->current_y - target_y;
6952 goto move_further_back;
6953 }
6954 else if (target_y >= it->current_y + line_height
6955 && IT_CHARPOS (*it) < ZV)
6956 {
6957 /* Should move forward by at least one line, maybe more.
6958
6959 Note: Calling move_it_by_lines can be expensive on
6960 terminal frames, where compute_motion is used (via
6961 vmotion) to do the job, when there are very long lines
6962 and truncate-lines is nil. That's the reason for
6963 treating terminal frames specially here. */
6964
6965 if (!FRAME_WINDOW_P (it->f))
6966 move_it_vertically (it, target_y - (it->current_y + line_height));
6967 else
6968 {
6969 do
6970 {
6971 move_it_by_lines (it, 1, 1);
6972 }
6973 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6974 }
6975
6976 #if 0
6977 /* I think this assert is bogus if buffer contains
6978 invisible text or images. KFS. */
6979 xassert (IT_CHARPOS (*it) >= BEGV);
6980 #endif
6981 }
6982 }
6983 }
6984
6985
6986 /* Move IT by a specified amount of pixel lines DY. DY negative means
6987 move backwards. DY = 0 means move to start of screen line. At the
6988 end, IT will be on the start of a screen line. */
6989
6990 void
6991 move_it_vertically (it, dy)
6992 struct it *it;
6993 int dy;
6994 {
6995 if (dy <= 0)
6996 move_it_vertically_backward (it, -dy);
6997 else
6998 {
6999 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7000 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7001 MOVE_TO_POS | MOVE_TO_Y);
7002 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7003
7004 /* If buffer ends in ZV without a newline, move to the start of
7005 the line to satisfy the post-condition. */
7006 if (IT_CHARPOS (*it) == ZV
7007 && ZV > BEGV
7008 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7009 move_it_by_lines (it, 0, 0);
7010 }
7011 }
7012
7013
7014 /* Move iterator IT past the end of the text line it is in. */
7015
7016 void
7017 move_it_past_eol (it)
7018 struct it *it;
7019 {
7020 enum move_it_result rc;
7021
7022 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7023 if (rc == MOVE_NEWLINE_OR_CR)
7024 set_iterator_to_next (it, 0);
7025 }
7026
7027
7028 #if 0 /* Currently not used. */
7029
7030 /* Return non-zero if some text between buffer positions START_CHARPOS
7031 and END_CHARPOS is invisible. IT->window is the window for text
7032 property lookup. */
7033
7034 static int
7035 invisible_text_between_p (it, start_charpos, end_charpos)
7036 struct it *it;
7037 int start_charpos, end_charpos;
7038 {
7039 Lisp_Object prop, limit;
7040 int invisible_found_p;
7041
7042 xassert (it != NULL && start_charpos <= end_charpos);
7043
7044 /* Is text at START invisible? */
7045 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
7046 it->window);
7047 if (TEXT_PROP_MEANS_INVISIBLE (prop))
7048 invisible_found_p = 1;
7049 else
7050 {
7051 limit = Fnext_single_char_property_change (make_number (start_charpos),
7052 Qinvisible, Qnil,
7053 make_number (end_charpos));
7054 invisible_found_p = XFASTINT (limit) < end_charpos;
7055 }
7056
7057 return invisible_found_p;
7058 }
7059
7060 #endif /* 0 */
7061
7062
7063 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7064 negative means move up. DVPOS == 0 means move to the start of the
7065 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7066 NEED_Y_P is zero, IT->current_y will be left unchanged.
7067
7068 Further optimization ideas: If we would know that IT->f doesn't use
7069 a face with proportional font, we could be faster for
7070 truncate-lines nil. */
7071
7072 void
7073 move_it_by_lines (it, dvpos, need_y_p)
7074 struct it *it;
7075 int dvpos, need_y_p;
7076 {
7077 struct position pos;
7078
7079 if (!FRAME_WINDOW_P (it->f))
7080 {
7081 struct text_pos textpos;
7082
7083 /* We can use vmotion on frames without proportional fonts. */
7084 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7085 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7086 reseat (it, textpos, 1);
7087 it->vpos += pos.vpos;
7088 it->current_y += pos.vpos;
7089 }
7090 else if (dvpos == 0)
7091 {
7092 /* DVPOS == 0 means move to the start of the screen line. */
7093 move_it_vertically_backward (it, 0);
7094 xassert (it->current_x == 0 && it->hpos == 0);
7095 /* Let next call to line_bottom_y calculate real line height */
7096 last_height = 0;
7097 }
7098 else if (dvpos > 0)
7099 {
7100 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7101 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7102 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7103 }
7104 else
7105 {
7106 struct it it2;
7107 int start_charpos, i;
7108
7109 /* Start at the beginning of the screen line containing IT's
7110 position. This may actually move vertically backwards,
7111 in case of overlays, so adjust dvpos accordingly. */
7112 dvpos += it->vpos;
7113 move_it_vertically_backward (it, 0);
7114 dvpos -= it->vpos;
7115
7116 /* Go back -DVPOS visible lines and reseat the iterator there. */
7117 start_charpos = IT_CHARPOS (*it);
7118 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7119 back_to_previous_visible_line_start (it);
7120 reseat (it, it->current.pos, 1);
7121
7122 /* Move further back if we end up in a string or an image. */
7123 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7124 {
7125 /* First try to move to start of display line. */
7126 dvpos += it->vpos;
7127 move_it_vertically_backward (it, 0);
7128 dvpos -= it->vpos;
7129 if (IT_POS_VALID_AFTER_MOVE_P (it))
7130 break;
7131 /* If start of line is still in string or image,
7132 move further back. */
7133 back_to_previous_visible_line_start (it);
7134 reseat (it, it->current.pos, 1);
7135 dvpos--;
7136 }
7137
7138 it->current_x = it->hpos = 0;
7139
7140 /* Above call may have moved too far if continuation lines
7141 are involved. Scan forward and see if it did. */
7142 it2 = *it;
7143 it2.vpos = it2.current_y = 0;
7144 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7145 it->vpos -= it2.vpos;
7146 it->current_y -= it2.current_y;
7147 it->current_x = it->hpos = 0;
7148
7149 /* If we moved too far back, move IT some lines forward. */
7150 if (it2.vpos > -dvpos)
7151 {
7152 int delta = it2.vpos + dvpos;
7153 it2 = *it;
7154 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7155 /* Move back again if we got too far ahead. */
7156 if (IT_CHARPOS (*it) >= start_charpos)
7157 *it = it2;
7158 }
7159 }
7160 }
7161
7162 /* Return 1 if IT points into the middle of a display vector. */
7163
7164 int
7165 in_display_vector_p (it)
7166 struct it *it;
7167 {
7168 return (it->method == GET_FROM_DISPLAY_VECTOR
7169 && it->current.dpvec_index > 0
7170 && it->dpvec + it->current.dpvec_index != it->dpend);
7171 }
7172
7173 \f
7174 /***********************************************************************
7175 Messages
7176 ***********************************************************************/
7177
7178
7179 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7180 to *Messages*. */
7181
7182 void
7183 add_to_log (format, arg1, arg2)
7184 char *format;
7185 Lisp_Object arg1, arg2;
7186 {
7187 Lisp_Object args[3];
7188 Lisp_Object msg, fmt;
7189 char *buffer;
7190 int len;
7191 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7192 USE_SAFE_ALLOCA;
7193
7194 /* Do nothing if called asynchronously. Inserting text into
7195 a buffer may call after-change-functions and alike and
7196 that would means running Lisp asynchronously. */
7197 if (handling_signal)
7198 return;
7199
7200 fmt = msg = Qnil;
7201 GCPRO4 (fmt, msg, arg1, arg2);
7202
7203 args[0] = fmt = build_string (format);
7204 args[1] = arg1;
7205 args[2] = arg2;
7206 msg = Fformat (3, args);
7207
7208 len = SBYTES (msg) + 1;
7209 SAFE_ALLOCA (buffer, char *, len);
7210 bcopy (SDATA (msg), buffer, len);
7211
7212 message_dolog (buffer, len - 1, 1, 0);
7213 SAFE_FREE ();
7214
7215 UNGCPRO;
7216 }
7217
7218
7219 /* Output a newline in the *Messages* buffer if "needs" one. */
7220
7221 void
7222 message_log_maybe_newline ()
7223 {
7224 if (message_log_need_newline)
7225 message_dolog ("", 0, 1, 0);
7226 }
7227
7228
7229 /* Add a string M of length NBYTES to the message log, optionally
7230 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7231 nonzero, means interpret the contents of M as multibyte. This
7232 function calls low-level routines in order to bypass text property
7233 hooks, etc. which might not be safe to run.
7234
7235 This may GC (insert may run before/after change hooks),
7236 so the buffer M must NOT point to a Lisp string. */
7237
7238 void
7239 message_dolog (m, nbytes, nlflag, multibyte)
7240 const char *m;
7241 int nbytes, nlflag, multibyte;
7242 {
7243 if (!NILP (Vmemory_full))
7244 return;
7245
7246 if (!NILP (Vmessage_log_max))
7247 {
7248 struct buffer *oldbuf;
7249 Lisp_Object oldpoint, oldbegv, oldzv;
7250 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7251 int point_at_end = 0;
7252 int zv_at_end = 0;
7253 Lisp_Object old_deactivate_mark, tem;
7254 struct gcpro gcpro1;
7255
7256 old_deactivate_mark = Vdeactivate_mark;
7257 oldbuf = current_buffer;
7258 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7259 current_buffer->undo_list = Qt;
7260
7261 oldpoint = message_dolog_marker1;
7262 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7263 oldbegv = message_dolog_marker2;
7264 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7265 oldzv = message_dolog_marker3;
7266 set_marker_restricted (oldzv, make_number (ZV), Qnil);
7267 GCPRO1 (old_deactivate_mark);
7268
7269 if (PT == Z)
7270 point_at_end = 1;
7271 if (ZV == Z)
7272 zv_at_end = 1;
7273
7274 BEGV = BEG;
7275 BEGV_BYTE = BEG_BYTE;
7276 ZV = Z;
7277 ZV_BYTE = Z_BYTE;
7278 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7279
7280 /* Insert the string--maybe converting multibyte to single byte
7281 or vice versa, so that all the text fits the buffer. */
7282 if (multibyte
7283 && NILP (current_buffer->enable_multibyte_characters))
7284 {
7285 int i, c, char_bytes;
7286 unsigned char work[1];
7287
7288 /* Convert a multibyte string to single-byte
7289 for the *Message* buffer. */
7290 for (i = 0; i < nbytes; i += char_bytes)
7291 {
7292 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
7293 work[0] = (SINGLE_BYTE_CHAR_P (c)
7294 ? c
7295 : multibyte_char_to_unibyte (c, Qnil));
7296 insert_1_both (work, 1, 1, 1, 0, 0);
7297 }
7298 }
7299 else if (! multibyte
7300 && ! NILP (current_buffer->enable_multibyte_characters))
7301 {
7302 int i, c, char_bytes;
7303 unsigned char *msg = (unsigned char *) m;
7304 unsigned char str[MAX_MULTIBYTE_LENGTH];
7305 /* Convert a single-byte string to multibyte
7306 for the *Message* buffer. */
7307 for (i = 0; i < nbytes; i++)
7308 {
7309 c = unibyte_char_to_multibyte (msg[i]);
7310 char_bytes = CHAR_STRING (c, str);
7311 insert_1_both (str, 1, char_bytes, 1, 0, 0);
7312 }
7313 }
7314 else if (nbytes)
7315 insert_1 (m, nbytes, 1, 0, 0);
7316
7317 if (nlflag)
7318 {
7319 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
7320 insert_1 ("\n", 1, 1, 0, 0);
7321
7322 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
7323 this_bol = PT;
7324 this_bol_byte = PT_BYTE;
7325
7326 /* See if this line duplicates the previous one.
7327 If so, combine duplicates. */
7328 if (this_bol > BEG)
7329 {
7330 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
7331 prev_bol = PT;
7332 prev_bol_byte = PT_BYTE;
7333
7334 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
7335 this_bol, this_bol_byte);
7336 if (dup)
7337 {
7338 del_range_both (prev_bol, prev_bol_byte,
7339 this_bol, this_bol_byte, 0);
7340 if (dup > 1)
7341 {
7342 char dupstr[40];
7343 int duplen;
7344
7345 /* If you change this format, don't forget to also
7346 change message_log_check_duplicate. */
7347 sprintf (dupstr, " [%d times]", dup);
7348 duplen = strlen (dupstr);
7349 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
7350 insert_1 (dupstr, duplen, 1, 0, 1);
7351 }
7352 }
7353 }
7354
7355 /* If we have more than the desired maximum number of lines
7356 in the *Messages* buffer now, delete the oldest ones.
7357 This is safe because we don't have undo in this buffer. */
7358
7359 if (NATNUMP (Vmessage_log_max))
7360 {
7361 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
7362 -XFASTINT (Vmessage_log_max) - 1, 0);
7363 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
7364 }
7365 }
7366 BEGV = XMARKER (oldbegv)->charpos;
7367 BEGV_BYTE = marker_byte_position (oldbegv);
7368
7369 if (zv_at_end)
7370 {
7371 ZV = Z;
7372 ZV_BYTE = Z_BYTE;
7373 }
7374 else
7375 {
7376 ZV = XMARKER (oldzv)->charpos;
7377 ZV_BYTE = marker_byte_position (oldzv);
7378 }
7379
7380 if (point_at_end)
7381 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7382 else
7383 /* We can't do Fgoto_char (oldpoint) because it will run some
7384 Lisp code. */
7385 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
7386 XMARKER (oldpoint)->bytepos);
7387
7388 UNGCPRO;
7389 unchain_marker (XMARKER (oldpoint));
7390 unchain_marker (XMARKER (oldbegv));
7391 unchain_marker (XMARKER (oldzv));
7392
7393 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
7394 set_buffer_internal (oldbuf);
7395 if (NILP (tem))
7396 windows_or_buffers_changed = old_windows_or_buffers_changed;
7397 message_log_need_newline = !nlflag;
7398 Vdeactivate_mark = old_deactivate_mark;
7399 }
7400 }
7401
7402
7403 /* We are at the end of the buffer after just having inserted a newline.
7404 (Note: We depend on the fact we won't be crossing the gap.)
7405 Check to see if the most recent message looks a lot like the previous one.
7406 Return 0 if different, 1 if the new one should just replace it, or a
7407 value N > 1 if we should also append " [N times]". */
7408
7409 static int
7410 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
7411 int prev_bol, this_bol;
7412 int prev_bol_byte, this_bol_byte;
7413 {
7414 int i;
7415 int len = Z_BYTE - 1 - this_bol_byte;
7416 int seen_dots = 0;
7417 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
7418 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
7419
7420 for (i = 0; i < len; i++)
7421 {
7422 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
7423 seen_dots = 1;
7424 if (p1[i] != p2[i])
7425 return seen_dots;
7426 }
7427 p1 += len;
7428 if (*p1 == '\n')
7429 return 2;
7430 if (*p1++ == ' ' && *p1++ == '[')
7431 {
7432 int n = 0;
7433 while (*p1 >= '0' && *p1 <= '9')
7434 n = n * 10 + *p1++ - '0';
7435 if (strncmp (p1, " times]\n", 8) == 0)
7436 return n+1;
7437 }
7438 return 0;
7439 }
7440 \f
7441
7442 /* Display an echo area message M with a specified length of NBYTES
7443 bytes. The string may include null characters. If M is 0, clear
7444 out any existing message, and let the mini-buffer text show
7445 through.
7446
7447 This may GC, so the buffer M must NOT point to a Lisp string. */
7448
7449 void
7450 message2 (m, nbytes, multibyte)
7451 const char *m;
7452 int nbytes;
7453 int multibyte;
7454 {
7455 /* First flush out any partial line written with print. */
7456 message_log_maybe_newline ();
7457 if (m)
7458 message_dolog (m, nbytes, 1, multibyte);
7459 message2_nolog (m, nbytes, multibyte);
7460 }
7461
7462
7463 /* The non-logging counterpart of message2. */
7464
7465 void
7466 message2_nolog (m, nbytes, multibyte)
7467 const char *m;
7468 int nbytes, multibyte;
7469 {
7470 struct frame *sf = SELECTED_FRAME ();
7471 message_enable_multibyte = multibyte;
7472
7473 if (noninteractive)
7474 {
7475 if (noninteractive_need_newline)
7476 putc ('\n', stderr);
7477 noninteractive_need_newline = 0;
7478 if (m)
7479 fwrite (m, nbytes, 1, stderr);
7480 if (cursor_in_echo_area == 0)
7481 fprintf (stderr, "\n");
7482 fflush (stderr);
7483 }
7484 /* A null message buffer means that the frame hasn't really been
7485 initialized yet. Error messages get reported properly by
7486 cmd_error, so this must be just an informative message; toss it. */
7487 else if (INTERACTIVE
7488 && sf->glyphs_initialized_p
7489 && FRAME_MESSAGE_BUF (sf))
7490 {
7491 Lisp_Object mini_window;
7492 struct frame *f;
7493
7494 /* Get the frame containing the mini-buffer
7495 that the selected frame is using. */
7496 mini_window = FRAME_MINIBUF_WINDOW (sf);
7497 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7498
7499 FRAME_SAMPLE_VISIBILITY (f);
7500 if (FRAME_VISIBLE_P (sf)
7501 && ! FRAME_VISIBLE_P (f))
7502 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
7503
7504 if (m)
7505 {
7506 set_message (m, Qnil, nbytes, multibyte);
7507 if (minibuffer_auto_raise)
7508 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7509 }
7510 else
7511 clear_message (1, 1);
7512
7513 do_pending_window_change (0);
7514 echo_area_display (1);
7515 do_pending_window_change (0);
7516 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
7517 (*frame_up_to_date_hook) (f);
7518 }
7519 }
7520
7521
7522 /* Display an echo area message M with a specified length of NBYTES
7523 bytes. The string may include null characters. If M is not a
7524 string, clear out any existing message, and let the mini-buffer
7525 text show through.
7526
7527 This function cancels echoing. */
7528
7529 void
7530 message3 (m, nbytes, multibyte)
7531 Lisp_Object m;
7532 int nbytes;
7533 int multibyte;
7534 {
7535 struct gcpro gcpro1;
7536
7537 GCPRO1 (m);
7538 clear_message (1,1);
7539 cancel_echoing ();
7540
7541 /* First flush out any partial line written with print. */
7542 message_log_maybe_newline ();
7543 if (STRINGP (m))
7544 {
7545 char *buffer;
7546 USE_SAFE_ALLOCA;
7547
7548 SAFE_ALLOCA (buffer, char *, nbytes);
7549 bcopy (SDATA (m), buffer, nbytes);
7550 message_dolog (buffer, nbytes, 1, multibyte);
7551 SAFE_FREE ();
7552 }
7553 message3_nolog (m, nbytes, multibyte);
7554
7555 UNGCPRO;
7556 }
7557
7558
7559 /* The non-logging version of message3.
7560 This does not cancel echoing, because it is used for echoing.
7561 Perhaps we need to make a separate function for echoing
7562 and make this cancel echoing. */
7563
7564 void
7565 message3_nolog (m, nbytes, multibyte)
7566 Lisp_Object m;
7567 int nbytes, multibyte;
7568 {
7569 struct frame *sf = SELECTED_FRAME ();
7570 message_enable_multibyte = multibyte;
7571
7572 if (noninteractive)
7573 {
7574 if (noninteractive_need_newline)
7575 putc ('\n', stderr);
7576 noninteractive_need_newline = 0;
7577 if (STRINGP (m))
7578 fwrite (SDATA (m), nbytes, 1, stderr);
7579 if (cursor_in_echo_area == 0)
7580 fprintf (stderr, "\n");
7581 fflush (stderr);
7582 }
7583 /* A null message buffer means that the frame hasn't really been
7584 initialized yet. Error messages get reported properly by
7585 cmd_error, so this must be just an informative message; toss it. */
7586 else if (INTERACTIVE
7587 && sf->glyphs_initialized_p
7588 && FRAME_MESSAGE_BUF (sf))
7589 {
7590 Lisp_Object mini_window;
7591 Lisp_Object frame;
7592 struct frame *f;
7593
7594 /* Get the frame containing the mini-buffer
7595 that the selected frame is using. */
7596 mini_window = FRAME_MINIBUF_WINDOW (sf);
7597 frame = XWINDOW (mini_window)->frame;
7598 f = XFRAME (frame);
7599
7600 FRAME_SAMPLE_VISIBILITY (f);
7601 if (FRAME_VISIBLE_P (sf)
7602 && !FRAME_VISIBLE_P (f))
7603 Fmake_frame_visible (frame);
7604
7605 if (STRINGP (m) && SCHARS (m) > 0)
7606 {
7607 set_message (NULL, m, nbytes, multibyte);
7608 if (minibuffer_auto_raise)
7609 Fraise_frame (frame);
7610 /* Assume we are not echoing.
7611 (If we are, echo_now will override this.) */
7612 echo_message_buffer = Qnil;
7613 }
7614 else
7615 clear_message (1, 1);
7616
7617 do_pending_window_change (0);
7618 echo_area_display (1);
7619 do_pending_window_change (0);
7620 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
7621 (*frame_up_to_date_hook) (f);
7622 }
7623 }
7624
7625
7626 /* Display a null-terminated echo area message M. If M is 0, clear
7627 out any existing message, and let the mini-buffer text show through.
7628
7629 The buffer M must continue to exist until after the echo area gets
7630 cleared or some other message gets displayed there. Do not pass
7631 text that is stored in a Lisp string. Do not pass text in a buffer
7632 that was alloca'd. */
7633
7634 void
7635 message1 (m)
7636 char *m;
7637 {
7638 message2 (m, (m ? strlen (m) : 0), 0);
7639 }
7640
7641
7642 /* The non-logging counterpart of message1. */
7643
7644 void
7645 message1_nolog (m)
7646 char *m;
7647 {
7648 message2_nolog (m, (m ? strlen (m) : 0), 0);
7649 }
7650
7651 /* Display a message M which contains a single %s
7652 which gets replaced with STRING. */
7653
7654 void
7655 message_with_string (m, string, log)
7656 char *m;
7657 Lisp_Object string;
7658 int log;
7659 {
7660 CHECK_STRING (string);
7661
7662 if (noninteractive)
7663 {
7664 if (m)
7665 {
7666 if (noninteractive_need_newline)
7667 putc ('\n', stderr);
7668 noninteractive_need_newline = 0;
7669 fprintf (stderr, m, SDATA (string));
7670 if (cursor_in_echo_area == 0)
7671 fprintf (stderr, "\n");
7672 fflush (stderr);
7673 }
7674 }
7675 else if (INTERACTIVE)
7676 {
7677 /* The frame whose minibuffer we're going to display the message on.
7678 It may be larger than the selected frame, so we need
7679 to use its buffer, not the selected frame's buffer. */
7680 Lisp_Object mini_window;
7681 struct frame *f, *sf = SELECTED_FRAME ();
7682
7683 /* Get the frame containing the minibuffer
7684 that the selected frame is using. */
7685 mini_window = FRAME_MINIBUF_WINDOW (sf);
7686 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7687
7688 /* A null message buffer means that the frame hasn't really been
7689 initialized yet. Error messages get reported properly by
7690 cmd_error, so this must be just an informative message; toss it. */
7691 if (FRAME_MESSAGE_BUF (f))
7692 {
7693 Lisp_Object args[2], message;
7694 struct gcpro gcpro1, gcpro2;
7695
7696 args[0] = build_string (m);
7697 args[1] = message = string;
7698 GCPRO2 (args[0], message);
7699 gcpro1.nvars = 2;
7700
7701 message = Fformat (2, args);
7702
7703 if (log)
7704 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7705 else
7706 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7707
7708 UNGCPRO;
7709
7710 /* Print should start at the beginning of the message
7711 buffer next time. */
7712 message_buf_print = 0;
7713 }
7714 }
7715 }
7716
7717
7718 /* Dump an informative message to the minibuf. If M is 0, clear out
7719 any existing message, and let the mini-buffer text show through. */
7720
7721 /* VARARGS 1 */
7722 void
7723 message (m, a1, a2, a3)
7724 char *m;
7725 EMACS_INT a1, a2, a3;
7726 {
7727 if (noninteractive)
7728 {
7729 if (m)
7730 {
7731 if (noninteractive_need_newline)
7732 putc ('\n', stderr);
7733 noninteractive_need_newline = 0;
7734 fprintf (stderr, m, a1, a2, a3);
7735 if (cursor_in_echo_area == 0)
7736 fprintf (stderr, "\n");
7737 fflush (stderr);
7738 }
7739 }
7740 else if (INTERACTIVE)
7741 {
7742 /* The frame whose mini-buffer we're going to display the message
7743 on. It may be larger than the selected frame, so we need to
7744 use its buffer, not the selected frame's buffer. */
7745 Lisp_Object mini_window;
7746 struct frame *f, *sf = SELECTED_FRAME ();
7747
7748 /* Get the frame containing the mini-buffer
7749 that the selected frame is using. */
7750 mini_window = FRAME_MINIBUF_WINDOW (sf);
7751 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7752
7753 /* A null message buffer means that the frame hasn't really been
7754 initialized yet. Error messages get reported properly by
7755 cmd_error, so this must be just an informative message; toss
7756 it. */
7757 if (FRAME_MESSAGE_BUF (f))
7758 {
7759 if (m)
7760 {
7761 int len;
7762 #ifdef NO_ARG_ARRAY
7763 char *a[3];
7764 a[0] = (char *) a1;
7765 a[1] = (char *) a2;
7766 a[2] = (char *) a3;
7767
7768 len = doprnt (FRAME_MESSAGE_BUF (f),
7769 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7770 #else
7771 len = doprnt (FRAME_MESSAGE_BUF (f),
7772 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7773 (char **) &a1);
7774 #endif /* NO_ARG_ARRAY */
7775
7776 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7777 }
7778 else
7779 message1 (0);
7780
7781 /* Print should start at the beginning of the message
7782 buffer next time. */
7783 message_buf_print = 0;
7784 }
7785 }
7786 }
7787
7788
7789 /* The non-logging version of message. */
7790
7791 void
7792 message_nolog (m, a1, a2, a3)
7793 char *m;
7794 EMACS_INT a1, a2, a3;
7795 {
7796 Lisp_Object old_log_max;
7797 old_log_max = Vmessage_log_max;
7798 Vmessage_log_max = Qnil;
7799 message (m, a1, a2, a3);
7800 Vmessage_log_max = old_log_max;
7801 }
7802
7803
7804 /* Display the current message in the current mini-buffer. This is
7805 only called from error handlers in process.c, and is not time
7806 critical. */
7807
7808 void
7809 update_echo_area ()
7810 {
7811 if (!NILP (echo_area_buffer[0]))
7812 {
7813 Lisp_Object string;
7814 string = Fcurrent_message ();
7815 message3 (string, SBYTES (string),
7816 !NILP (current_buffer->enable_multibyte_characters));
7817 }
7818 }
7819
7820
7821 /* Make sure echo area buffers in `echo_buffers' are live.
7822 If they aren't, make new ones. */
7823
7824 static void
7825 ensure_echo_area_buffers ()
7826 {
7827 int i;
7828
7829 for (i = 0; i < 2; ++i)
7830 if (!BUFFERP (echo_buffer[i])
7831 || NILP (XBUFFER (echo_buffer[i])->name))
7832 {
7833 char name[30];
7834 Lisp_Object old_buffer;
7835 int j;
7836
7837 old_buffer = echo_buffer[i];
7838 sprintf (name, " *Echo Area %d*", i);
7839 echo_buffer[i] = Fget_buffer_create (build_string (name));
7840 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7841
7842 for (j = 0; j < 2; ++j)
7843 if (EQ (old_buffer, echo_area_buffer[j]))
7844 echo_area_buffer[j] = echo_buffer[i];
7845 }
7846 }
7847
7848
7849 /* Call FN with args A1..A4 with either the current or last displayed
7850 echo_area_buffer as current buffer.
7851
7852 WHICH zero means use the current message buffer
7853 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7854 from echo_buffer[] and clear it.
7855
7856 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7857 suitable buffer from echo_buffer[] and clear it.
7858
7859 Value is what FN returns. */
7860
7861 static int
7862 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7863 struct window *w;
7864 int which;
7865 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7866 EMACS_INT a1;
7867 Lisp_Object a2;
7868 EMACS_INT a3, a4;
7869 {
7870 Lisp_Object buffer;
7871 int this_one, the_other, clear_buffer_p, rc;
7872 int count = SPECPDL_INDEX ();
7873
7874 /* If buffers aren't live, make new ones. */
7875 ensure_echo_area_buffers ();
7876
7877 clear_buffer_p = 0;
7878
7879 if (which == 0)
7880 this_one = 0, the_other = 1;
7881 else if (which > 0)
7882 this_one = 1, the_other = 0;
7883
7884 /* Choose a suitable buffer from echo_buffer[] is we don't
7885 have one. */
7886 if (NILP (echo_area_buffer[this_one]))
7887 {
7888 echo_area_buffer[this_one]
7889 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7890 ? echo_buffer[the_other]
7891 : echo_buffer[this_one]);
7892 clear_buffer_p = 1;
7893 }
7894
7895 buffer = echo_area_buffer[this_one];
7896
7897 /* Don't get confused by reusing the buffer used for echoing
7898 for a different purpose. */
7899 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7900 cancel_echoing ();
7901
7902 record_unwind_protect (unwind_with_echo_area_buffer,
7903 with_echo_area_buffer_unwind_data (w));
7904
7905 /* Make the echo area buffer current. Note that for display
7906 purposes, it is not necessary that the displayed window's buffer
7907 == current_buffer, except for text property lookup. So, let's
7908 only set that buffer temporarily here without doing a full
7909 Fset_window_buffer. We must also change w->pointm, though,
7910 because otherwise an assertions in unshow_buffer fails, and Emacs
7911 aborts. */
7912 set_buffer_internal_1 (XBUFFER (buffer));
7913 if (w)
7914 {
7915 w->buffer = buffer;
7916 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7917 }
7918
7919 current_buffer->undo_list = Qt;
7920 current_buffer->read_only = Qnil;
7921 specbind (Qinhibit_read_only, Qt);
7922 specbind (Qinhibit_modification_hooks, Qt);
7923
7924 if (clear_buffer_p && Z > BEG)
7925 del_range (BEG, Z);
7926
7927 xassert (BEGV >= BEG);
7928 xassert (ZV <= Z && ZV >= BEGV);
7929
7930 rc = fn (a1, a2, a3, a4);
7931
7932 xassert (BEGV >= BEG);
7933 xassert (ZV <= Z && ZV >= BEGV);
7934
7935 unbind_to (count, Qnil);
7936 return rc;
7937 }
7938
7939
7940 /* Save state that should be preserved around the call to the function
7941 FN called in with_echo_area_buffer. */
7942
7943 static Lisp_Object
7944 with_echo_area_buffer_unwind_data (w)
7945 struct window *w;
7946 {
7947 int i = 0;
7948 Lisp_Object vector;
7949
7950 /* Reduce consing by keeping one vector in
7951 Vwith_echo_area_save_vector. */
7952 vector = Vwith_echo_area_save_vector;
7953 Vwith_echo_area_save_vector = Qnil;
7954
7955 if (NILP (vector))
7956 vector = Fmake_vector (make_number (7), Qnil);
7957
7958 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7959 AREF (vector, i) = Vdeactivate_mark, ++i;
7960 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7961
7962 if (w)
7963 {
7964 XSETWINDOW (AREF (vector, i), w); ++i;
7965 AREF (vector, i) = w->buffer; ++i;
7966 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7967 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7968 }
7969 else
7970 {
7971 int end = i + 4;
7972 for (; i < end; ++i)
7973 AREF (vector, i) = Qnil;
7974 }
7975
7976 xassert (i == ASIZE (vector));
7977 return vector;
7978 }
7979
7980
7981 /* Restore global state from VECTOR which was created by
7982 with_echo_area_buffer_unwind_data. */
7983
7984 static Lisp_Object
7985 unwind_with_echo_area_buffer (vector)
7986 Lisp_Object vector;
7987 {
7988 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7989 Vdeactivate_mark = AREF (vector, 1);
7990 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7991
7992 if (WINDOWP (AREF (vector, 3)))
7993 {
7994 struct window *w;
7995 Lisp_Object buffer, charpos, bytepos;
7996
7997 w = XWINDOW (AREF (vector, 3));
7998 buffer = AREF (vector, 4);
7999 charpos = AREF (vector, 5);
8000 bytepos = AREF (vector, 6);
8001
8002 w->buffer = buffer;
8003 set_marker_both (w->pointm, buffer,
8004 XFASTINT (charpos), XFASTINT (bytepos));
8005 }
8006
8007 Vwith_echo_area_save_vector = vector;
8008 return Qnil;
8009 }
8010
8011
8012 /* Set up the echo area for use by print functions. MULTIBYTE_P
8013 non-zero means we will print multibyte. */
8014
8015 void
8016 setup_echo_area_for_printing (multibyte_p)
8017 int multibyte_p;
8018 {
8019 /* If we can't find an echo area any more, exit. */
8020 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8021 Fkill_emacs (Qnil);
8022
8023 ensure_echo_area_buffers ();
8024
8025 if (!message_buf_print)
8026 {
8027 /* A message has been output since the last time we printed.
8028 Choose a fresh echo area buffer. */
8029 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8030 echo_area_buffer[0] = echo_buffer[1];
8031 else
8032 echo_area_buffer[0] = echo_buffer[0];
8033
8034 /* Switch to that buffer and clear it. */
8035 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8036 current_buffer->truncate_lines = Qnil;
8037
8038 if (Z > BEG)
8039 {
8040 int count = SPECPDL_INDEX ();
8041 specbind (Qinhibit_read_only, Qt);
8042 /* Note that undo recording is always disabled. */
8043 del_range (BEG, Z);
8044 unbind_to (count, Qnil);
8045 }
8046 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8047
8048 /* Set up the buffer for the multibyteness we need. */
8049 if (multibyte_p
8050 != !NILP (current_buffer->enable_multibyte_characters))
8051 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8052
8053 /* Raise the frame containing the echo area. */
8054 if (minibuffer_auto_raise)
8055 {
8056 struct frame *sf = SELECTED_FRAME ();
8057 Lisp_Object mini_window;
8058 mini_window = FRAME_MINIBUF_WINDOW (sf);
8059 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8060 }
8061
8062 message_log_maybe_newline ();
8063 message_buf_print = 1;
8064 }
8065 else
8066 {
8067 if (NILP (echo_area_buffer[0]))
8068 {
8069 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8070 echo_area_buffer[0] = echo_buffer[1];
8071 else
8072 echo_area_buffer[0] = echo_buffer[0];
8073 }
8074
8075 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8076 {
8077 /* Someone switched buffers between print requests. */
8078 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8079 current_buffer->truncate_lines = Qnil;
8080 }
8081 }
8082 }
8083
8084
8085 /* Display an echo area message in window W. Value is non-zero if W's
8086 height is changed. If display_last_displayed_message_p is
8087 non-zero, display the message that was last displayed, otherwise
8088 display the current message. */
8089
8090 static int
8091 display_echo_area (w)
8092 struct window *w;
8093 {
8094 int i, no_message_p, window_height_changed_p, count;
8095
8096 /* Temporarily disable garbage collections while displaying the echo
8097 area. This is done because a GC can print a message itself.
8098 That message would modify the echo area buffer's contents while a
8099 redisplay of the buffer is going on, and seriously confuse
8100 redisplay. */
8101 count = inhibit_garbage_collection ();
8102
8103 /* If there is no message, we must call display_echo_area_1
8104 nevertheless because it resizes the window. But we will have to
8105 reset the echo_area_buffer in question to nil at the end because
8106 with_echo_area_buffer will sets it to an empty buffer. */
8107 i = display_last_displayed_message_p ? 1 : 0;
8108 no_message_p = NILP (echo_area_buffer[i]);
8109
8110 window_height_changed_p
8111 = with_echo_area_buffer (w, display_last_displayed_message_p,
8112 display_echo_area_1,
8113 (EMACS_INT) w, Qnil, 0, 0);
8114
8115 if (no_message_p)
8116 echo_area_buffer[i] = Qnil;
8117
8118 unbind_to (count, Qnil);
8119 return window_height_changed_p;
8120 }
8121
8122
8123 /* Helper for display_echo_area. Display the current buffer which
8124 contains the current echo area message in window W, a mini-window,
8125 a pointer to which is passed in A1. A2..A4 are currently not used.
8126 Change the height of W so that all of the message is displayed.
8127 Value is non-zero if height of W was changed. */
8128
8129 static int
8130 display_echo_area_1 (a1, a2, a3, a4)
8131 EMACS_INT a1;
8132 Lisp_Object a2;
8133 EMACS_INT a3, a4;
8134 {
8135 struct window *w = (struct window *) a1;
8136 Lisp_Object window;
8137 struct text_pos start;
8138 int window_height_changed_p = 0;
8139
8140 /* Do this before displaying, so that we have a large enough glyph
8141 matrix for the display. If we can't get enough space for the
8142 whole text, display the last N lines. That works by setting w->start. */
8143 window_height_changed_p = resize_mini_window (w, 0);
8144
8145 /* Use the starting position chosen by resize_mini_window. */
8146 SET_TEXT_POS_FROM_MARKER (start, w->start);
8147
8148 /* Display. */
8149 clear_glyph_matrix (w->desired_matrix);
8150 XSETWINDOW (window, w);
8151 try_window (window, start, 0);
8152
8153 return window_height_changed_p;
8154 }
8155
8156
8157 /* Resize the echo area window to exactly the size needed for the
8158 currently displayed message, if there is one. If a mini-buffer
8159 is active, don't shrink it. */
8160
8161 void
8162 resize_echo_area_exactly ()
8163 {
8164 if (BUFFERP (echo_area_buffer[0])
8165 && WINDOWP (echo_area_window))
8166 {
8167 struct window *w = XWINDOW (echo_area_window);
8168 int resized_p;
8169 Lisp_Object resize_exactly;
8170
8171 if (minibuf_level == 0)
8172 resize_exactly = Qt;
8173 else
8174 resize_exactly = Qnil;
8175
8176 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8177 (EMACS_INT) w, resize_exactly, 0, 0);
8178 if (resized_p)
8179 {
8180 ++windows_or_buffers_changed;
8181 ++update_mode_lines;
8182 redisplay_internal (0);
8183 }
8184 }
8185 }
8186
8187
8188 /* Callback function for with_echo_area_buffer, when used from
8189 resize_echo_area_exactly. A1 contains a pointer to the window to
8190 resize, EXACTLY non-nil means resize the mini-window exactly to the
8191 size of the text displayed. A3 and A4 are not used. Value is what
8192 resize_mini_window returns. */
8193
8194 static int
8195 resize_mini_window_1 (a1, exactly, a3, a4)
8196 EMACS_INT a1;
8197 Lisp_Object exactly;
8198 EMACS_INT a3, a4;
8199 {
8200 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8201 }
8202
8203
8204 /* Resize mini-window W to fit the size of its contents. EXACT:P
8205 means size the window exactly to the size needed. Otherwise, it's
8206 only enlarged until W's buffer is empty.
8207
8208 Set W->start to the right place to begin display. If the whole
8209 contents fit, start at the beginning. Otherwise, start so as
8210 to make the end of the contents appear. This is particularly
8211 important for y-or-n-p, but seems desirable generally.
8212
8213 Value is non-zero if the window height has been changed. */
8214
8215 int
8216 resize_mini_window (w, exact_p)
8217 struct window *w;
8218 int exact_p;
8219 {
8220 struct frame *f = XFRAME (w->frame);
8221 int window_height_changed_p = 0;
8222
8223 xassert (MINI_WINDOW_P (w));
8224
8225 /* By default, start display at the beginning. */
8226 set_marker_both (w->start, w->buffer,
8227 BUF_BEGV (XBUFFER (w->buffer)),
8228 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8229
8230 /* Don't resize windows while redisplaying a window; it would
8231 confuse redisplay functions when the size of the window they are
8232 displaying changes from under them. Such a resizing can happen,
8233 for instance, when which-func prints a long message while
8234 we are running fontification-functions. We're running these
8235 functions with safe_call which binds inhibit-redisplay to t. */
8236 if (!NILP (Vinhibit_redisplay))
8237 return 0;
8238
8239 /* Nil means don't try to resize. */
8240 if (NILP (Vresize_mini_windows)
8241 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8242 return 0;
8243
8244 if (!FRAME_MINIBUF_ONLY_P (f))
8245 {
8246 struct it it;
8247 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8248 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8249 int height, max_height;
8250 int unit = FRAME_LINE_HEIGHT (f);
8251 struct text_pos start;
8252 struct buffer *old_current_buffer = NULL;
8253
8254 if (current_buffer != XBUFFER (w->buffer))
8255 {
8256 old_current_buffer = current_buffer;
8257 set_buffer_internal (XBUFFER (w->buffer));
8258 }
8259
8260 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8261
8262 /* Compute the max. number of lines specified by the user. */
8263 if (FLOATP (Vmax_mini_window_height))
8264 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8265 else if (INTEGERP (Vmax_mini_window_height))
8266 max_height = XINT (Vmax_mini_window_height);
8267 else
8268 max_height = total_height / 4;
8269
8270 /* Correct that max. height if it's bogus. */
8271 max_height = max (1, max_height);
8272 max_height = min (total_height, max_height);
8273
8274 /* Find out the height of the text in the window. */
8275 if (it.truncate_lines_p)
8276 height = 1;
8277 else
8278 {
8279 last_height = 0;
8280 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
8281 if (it.max_ascent == 0 && it.max_descent == 0)
8282 height = it.current_y + last_height;
8283 else
8284 height = it.current_y + it.max_ascent + it.max_descent;
8285 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
8286 height = (height + unit - 1) / unit;
8287 }
8288
8289 /* Compute a suitable window start. */
8290 if (height > max_height)
8291 {
8292 height = max_height;
8293 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
8294 move_it_vertically_backward (&it, (height - 1) * unit);
8295 start = it.current.pos;
8296 }
8297 else
8298 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
8299 SET_MARKER_FROM_TEXT_POS (w->start, start);
8300
8301 if (EQ (Vresize_mini_windows, Qgrow_only))
8302 {
8303 /* Let it grow only, until we display an empty message, in which
8304 case the window shrinks again. */
8305 if (height > WINDOW_TOTAL_LINES (w))
8306 {
8307 int old_height = WINDOW_TOTAL_LINES (w);
8308 freeze_window_starts (f, 1);
8309 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8310 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8311 }
8312 else if (height < WINDOW_TOTAL_LINES (w)
8313 && (exact_p || BEGV == ZV))
8314 {
8315 int old_height = WINDOW_TOTAL_LINES (w);
8316 freeze_window_starts (f, 0);
8317 shrink_mini_window (w);
8318 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8319 }
8320 }
8321 else
8322 {
8323 /* Always resize to exact size needed. */
8324 if (height > WINDOW_TOTAL_LINES (w))
8325 {
8326 int old_height = WINDOW_TOTAL_LINES (w);
8327 freeze_window_starts (f, 1);
8328 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8329 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8330 }
8331 else if (height < WINDOW_TOTAL_LINES (w))
8332 {
8333 int old_height = WINDOW_TOTAL_LINES (w);
8334 freeze_window_starts (f, 0);
8335 shrink_mini_window (w);
8336
8337 if (height)
8338 {
8339 freeze_window_starts (f, 1);
8340 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8341 }
8342
8343 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8344 }
8345 }
8346
8347 if (old_current_buffer)
8348 set_buffer_internal (old_current_buffer);
8349 }
8350
8351 return window_height_changed_p;
8352 }
8353
8354
8355 /* Value is the current message, a string, or nil if there is no
8356 current message. */
8357
8358 Lisp_Object
8359 current_message ()
8360 {
8361 Lisp_Object msg;
8362
8363 if (NILP (echo_area_buffer[0]))
8364 msg = Qnil;
8365 else
8366 {
8367 with_echo_area_buffer (0, 0, current_message_1,
8368 (EMACS_INT) &msg, Qnil, 0, 0);
8369 if (NILP (msg))
8370 echo_area_buffer[0] = Qnil;
8371 }
8372
8373 return msg;
8374 }
8375
8376
8377 static int
8378 current_message_1 (a1, a2, a3, a4)
8379 EMACS_INT a1;
8380 Lisp_Object a2;
8381 EMACS_INT a3, a4;
8382 {
8383 Lisp_Object *msg = (Lisp_Object *) a1;
8384
8385 if (Z > BEG)
8386 *msg = make_buffer_string (BEG, Z, 1);
8387 else
8388 *msg = Qnil;
8389 return 0;
8390 }
8391
8392
8393 /* Push the current message on Vmessage_stack for later restauration
8394 by restore_message. Value is non-zero if the current message isn't
8395 empty. This is a relatively infrequent operation, so it's not
8396 worth optimizing. */
8397
8398 int
8399 push_message ()
8400 {
8401 Lisp_Object msg;
8402 msg = current_message ();
8403 Vmessage_stack = Fcons (msg, Vmessage_stack);
8404 return STRINGP (msg);
8405 }
8406
8407
8408 /* Restore message display from the top of Vmessage_stack. */
8409
8410 void
8411 restore_message ()
8412 {
8413 Lisp_Object msg;
8414
8415 xassert (CONSP (Vmessage_stack));
8416 msg = XCAR (Vmessage_stack);
8417 if (STRINGP (msg))
8418 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8419 else
8420 message3_nolog (msg, 0, 0);
8421 }
8422
8423
8424 /* Handler for record_unwind_protect calling pop_message. */
8425
8426 Lisp_Object
8427 pop_message_unwind (dummy)
8428 Lisp_Object dummy;
8429 {
8430 pop_message ();
8431 return Qnil;
8432 }
8433
8434 /* Pop the top-most entry off Vmessage_stack. */
8435
8436 void
8437 pop_message ()
8438 {
8439 xassert (CONSP (Vmessage_stack));
8440 Vmessage_stack = XCDR (Vmessage_stack);
8441 }
8442
8443
8444 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
8445 exits. If the stack is not empty, we have a missing pop_message
8446 somewhere. */
8447
8448 void
8449 check_message_stack ()
8450 {
8451 if (!NILP (Vmessage_stack))
8452 abort ();
8453 }
8454
8455
8456 /* Truncate to NCHARS what will be displayed in the echo area the next
8457 time we display it---but don't redisplay it now. */
8458
8459 void
8460 truncate_echo_area (nchars)
8461 int nchars;
8462 {
8463 if (nchars == 0)
8464 echo_area_buffer[0] = Qnil;
8465 /* A null message buffer means that the frame hasn't really been
8466 initialized yet. Error messages get reported properly by
8467 cmd_error, so this must be just an informative message; toss it. */
8468 else if (!noninteractive
8469 && INTERACTIVE
8470 && !NILP (echo_area_buffer[0]))
8471 {
8472 struct frame *sf = SELECTED_FRAME ();
8473 if (FRAME_MESSAGE_BUF (sf))
8474 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
8475 }
8476 }
8477
8478
8479 /* Helper function for truncate_echo_area. Truncate the current
8480 message to at most NCHARS characters. */
8481
8482 static int
8483 truncate_message_1 (nchars, a2, a3, a4)
8484 EMACS_INT nchars;
8485 Lisp_Object a2;
8486 EMACS_INT a3, a4;
8487 {
8488 if (BEG + nchars < Z)
8489 del_range (BEG + nchars, Z);
8490 if (Z == BEG)
8491 echo_area_buffer[0] = Qnil;
8492 return 0;
8493 }
8494
8495
8496 /* Set the current message to a substring of S or STRING.
8497
8498 If STRING is a Lisp string, set the message to the first NBYTES
8499 bytes from STRING. NBYTES zero means use the whole string. If
8500 STRING is multibyte, the message will be displayed multibyte.
8501
8502 If S is not null, set the message to the first LEN bytes of S. LEN
8503 zero means use the whole string. MULTIBYTE_P non-zero means S is
8504 multibyte. Display the message multibyte in that case.
8505
8506 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
8507 to t before calling set_message_1 (which calls insert).
8508 */
8509
8510 void
8511 set_message (s, string, nbytes, multibyte_p)
8512 const char *s;
8513 Lisp_Object string;
8514 int nbytes, multibyte_p;
8515 {
8516 message_enable_multibyte
8517 = ((s && multibyte_p)
8518 || (STRINGP (string) && STRING_MULTIBYTE (string)));
8519
8520 with_echo_area_buffer (0, 0, set_message_1,
8521 (EMACS_INT) s, string, nbytes, multibyte_p);
8522 message_buf_print = 0;
8523 help_echo_showing_p = 0;
8524 }
8525
8526
8527 /* Helper function for set_message. Arguments have the same meaning
8528 as there, with A1 corresponding to S and A2 corresponding to STRING
8529 This function is called with the echo area buffer being
8530 current. */
8531
8532 static int
8533 set_message_1 (a1, a2, nbytes, multibyte_p)
8534 EMACS_INT a1;
8535 Lisp_Object a2;
8536 EMACS_INT nbytes, multibyte_p;
8537 {
8538 const char *s = (const char *) a1;
8539 Lisp_Object string = a2;
8540
8541 /* Change multibyteness of the echo buffer appropriately. */
8542 if (message_enable_multibyte
8543 != !NILP (current_buffer->enable_multibyte_characters))
8544 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
8545
8546 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
8547
8548 /* Insert new message at BEG. */
8549 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8550 Ferase_buffer ();
8551
8552 if (STRINGP (string))
8553 {
8554 int nchars;
8555
8556 if (nbytes == 0)
8557 nbytes = SBYTES (string);
8558 nchars = string_byte_to_char (string, nbytes);
8559
8560 /* This function takes care of single/multibyte conversion. We
8561 just have to ensure that the echo area buffer has the right
8562 setting of enable_multibyte_characters. */
8563 insert_from_string (string, 0, 0, nchars, nbytes, 1);
8564 }
8565 else if (s)
8566 {
8567 if (nbytes == 0)
8568 nbytes = strlen (s);
8569
8570 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
8571 {
8572 /* Convert from multi-byte to single-byte. */
8573 int i, c, n;
8574 unsigned char work[1];
8575
8576 /* Convert a multibyte string to single-byte. */
8577 for (i = 0; i < nbytes; i += n)
8578 {
8579 c = string_char_and_length (s + i, nbytes - i, &n);
8580 work[0] = (SINGLE_BYTE_CHAR_P (c)
8581 ? c
8582 : multibyte_char_to_unibyte (c, Qnil));
8583 insert_1_both (work, 1, 1, 1, 0, 0);
8584 }
8585 }
8586 else if (!multibyte_p
8587 && !NILP (current_buffer->enable_multibyte_characters))
8588 {
8589 /* Convert from single-byte to multi-byte. */
8590 int i, c, n;
8591 const unsigned char *msg = (const unsigned char *) s;
8592 unsigned char str[MAX_MULTIBYTE_LENGTH];
8593
8594 /* Convert a single-byte string to multibyte. */
8595 for (i = 0; i < nbytes; i++)
8596 {
8597 c = unibyte_char_to_multibyte (msg[i]);
8598 n = CHAR_STRING (c, str);
8599 insert_1_both (str, 1, n, 1, 0, 0);
8600 }
8601 }
8602 else
8603 insert_1 (s, nbytes, 1, 0, 0);
8604 }
8605
8606 return 0;
8607 }
8608
8609
8610 /* Clear messages. CURRENT_P non-zero means clear the current
8611 message. LAST_DISPLAYED_P non-zero means clear the message
8612 last displayed. */
8613
8614 void
8615 clear_message (current_p, last_displayed_p)
8616 int current_p, last_displayed_p;
8617 {
8618 if (current_p)
8619 {
8620 echo_area_buffer[0] = Qnil;
8621 message_cleared_p = 1;
8622 }
8623
8624 if (last_displayed_p)
8625 echo_area_buffer[1] = Qnil;
8626
8627 message_buf_print = 0;
8628 }
8629
8630 /* Clear garbaged frames.
8631
8632 This function is used where the old redisplay called
8633 redraw_garbaged_frames which in turn called redraw_frame which in
8634 turn called clear_frame. The call to clear_frame was a source of
8635 flickering. I believe a clear_frame is not necessary. It should
8636 suffice in the new redisplay to invalidate all current matrices,
8637 and ensure a complete redisplay of all windows. */
8638
8639 static void
8640 clear_garbaged_frames ()
8641 {
8642 if (frame_garbaged)
8643 {
8644 Lisp_Object tail, frame;
8645 int changed_count = 0;
8646
8647 FOR_EACH_FRAME (tail, frame)
8648 {
8649 struct frame *f = XFRAME (frame);
8650
8651 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8652 {
8653 if (f->resized_p)
8654 {
8655 Fredraw_frame (frame);
8656 f->force_flush_display_p = 1;
8657 }
8658 clear_current_matrices (f);
8659 changed_count++;
8660 f->garbaged = 0;
8661 f->resized_p = 0;
8662 }
8663 }
8664
8665 frame_garbaged = 0;
8666 if (changed_count)
8667 ++windows_or_buffers_changed;
8668 }
8669 }
8670
8671
8672 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8673 is non-zero update selected_frame. Value is non-zero if the
8674 mini-windows height has been changed. */
8675
8676 static int
8677 echo_area_display (update_frame_p)
8678 int update_frame_p;
8679 {
8680 Lisp_Object mini_window;
8681 struct window *w;
8682 struct frame *f;
8683 int window_height_changed_p = 0;
8684 struct frame *sf = SELECTED_FRAME ();
8685
8686 mini_window = FRAME_MINIBUF_WINDOW (sf);
8687 w = XWINDOW (mini_window);
8688 f = XFRAME (WINDOW_FRAME (w));
8689
8690 /* Don't display if frame is invisible or not yet initialized. */
8691 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8692 return 0;
8693
8694 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8695 #ifndef MAC_OS8
8696 #ifdef HAVE_WINDOW_SYSTEM
8697 /* When Emacs starts, selected_frame may be a visible terminal
8698 frame, even if we run under a window system. If we let this
8699 through, a message would be displayed on the terminal. */
8700 if (EQ (selected_frame, Vterminal_frame)
8701 && !NILP (Vwindow_system))
8702 return 0;
8703 #endif /* HAVE_WINDOW_SYSTEM */
8704 #endif
8705
8706 /* Redraw garbaged frames. */
8707 if (frame_garbaged)
8708 clear_garbaged_frames ();
8709
8710 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8711 {
8712 echo_area_window = mini_window;
8713 window_height_changed_p = display_echo_area (w);
8714 w->must_be_updated_p = 1;
8715
8716 /* Update the display, unless called from redisplay_internal.
8717 Also don't update the screen during redisplay itself. The
8718 update will happen at the end of redisplay, and an update
8719 here could cause confusion. */
8720 if (update_frame_p && !redisplaying_p)
8721 {
8722 int n = 0;
8723
8724 /* If the display update has been interrupted by pending
8725 input, update mode lines in the frame. Due to the
8726 pending input, it might have been that redisplay hasn't
8727 been called, so that mode lines above the echo area are
8728 garbaged. This looks odd, so we prevent it here. */
8729 if (!display_completed)
8730 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8731
8732 if (window_height_changed_p
8733 /* Don't do this if Emacs is shutting down. Redisplay
8734 needs to run hooks. */
8735 && !NILP (Vrun_hooks))
8736 {
8737 /* Must update other windows. Likewise as in other
8738 cases, don't let this update be interrupted by
8739 pending input. */
8740 int count = SPECPDL_INDEX ();
8741 specbind (Qredisplay_dont_pause, Qt);
8742 windows_or_buffers_changed = 1;
8743 redisplay_internal (0);
8744 unbind_to (count, Qnil);
8745 }
8746 else if (FRAME_WINDOW_P (f) && n == 0)
8747 {
8748 /* Window configuration is the same as before.
8749 Can do with a display update of the echo area,
8750 unless we displayed some mode lines. */
8751 update_single_window (w, 1);
8752 rif->flush_display (f);
8753 }
8754 else
8755 update_frame (f, 1, 1);
8756
8757 /* If cursor is in the echo area, make sure that the next
8758 redisplay displays the minibuffer, so that the cursor will
8759 be replaced with what the minibuffer wants. */
8760 if (cursor_in_echo_area)
8761 ++windows_or_buffers_changed;
8762 }
8763 }
8764 else if (!EQ (mini_window, selected_window))
8765 windows_or_buffers_changed++;
8766
8767 /* The current message is now also the last one displayed. */
8768 echo_area_buffer[1] = echo_area_buffer[0];
8769
8770 /* Prevent redisplay optimization in redisplay_internal by resetting
8771 this_line_start_pos. This is done because the mini-buffer now
8772 displays the message instead of its buffer text. */
8773 if (EQ (mini_window, selected_window))
8774 CHARPOS (this_line_start_pos) = 0;
8775
8776 return window_height_changed_p;
8777 }
8778
8779
8780 \f
8781 /***********************************************************************
8782 Mode Lines and Frame Titles
8783 ***********************************************************************/
8784
8785 /* A buffer for constructing non-propertized mode-line strings and
8786 frame titles in it; allocated from the heap in init_xdisp and
8787 resized as needed in store_mode_line_noprop_char. */
8788
8789 static char *mode_line_noprop_buf;
8790
8791 /* The buffer's end, and a current output position in it. */
8792
8793 static char *mode_line_noprop_buf_end;
8794 static char *mode_line_noprop_ptr;
8795
8796 #define MODE_LINE_NOPROP_LEN(start) \
8797 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
8798
8799 static enum {
8800 MODE_LINE_DISPLAY = 0,
8801 MODE_LINE_TITLE,
8802 MODE_LINE_NOPROP,
8803 MODE_LINE_STRING
8804 } mode_line_target;
8805
8806 /* Alist that caches the results of :propertize.
8807 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
8808 static Lisp_Object mode_line_proptrans_alist;
8809
8810 /* List of strings making up the mode-line. */
8811 static Lisp_Object mode_line_string_list;
8812
8813 /* Base face property when building propertized mode line string. */
8814 static Lisp_Object mode_line_string_face;
8815 static Lisp_Object mode_line_string_face_prop;
8816
8817
8818 /* Unwind data for mode line strings */
8819
8820 static Lisp_Object Vmode_line_unwind_vector;
8821
8822 static Lisp_Object
8823 format_mode_line_unwind_data (obuf, save_proptrans)
8824 struct buffer *obuf;
8825 {
8826 Lisp_Object vector;
8827
8828 /* Reduce consing by keeping one vector in
8829 Vwith_echo_area_save_vector. */
8830 vector = Vmode_line_unwind_vector;
8831 Vmode_line_unwind_vector = Qnil;
8832
8833 if (NILP (vector))
8834 vector = Fmake_vector (make_number (7), Qnil);
8835
8836 AREF (vector, 0) = make_number (mode_line_target);
8837 AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
8838 AREF (vector, 2) = mode_line_string_list;
8839 AREF (vector, 3) = (save_proptrans ? mode_line_proptrans_alist : Qt);
8840 AREF (vector, 4) = mode_line_string_face;
8841 AREF (vector, 5) = mode_line_string_face_prop;
8842
8843 if (obuf)
8844 XSETBUFFER (AREF (vector, 6), obuf);
8845 else
8846 AREF (vector, 6) = Qnil;
8847
8848 return vector;
8849 }
8850
8851 static Lisp_Object
8852 unwind_format_mode_line (vector)
8853 Lisp_Object vector;
8854 {
8855 mode_line_target = XINT (AREF (vector, 0));
8856 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
8857 mode_line_string_list = AREF (vector, 2);
8858 if (! EQ (AREF (vector, 3), Qt))
8859 mode_line_proptrans_alist = AREF (vector, 3);
8860 mode_line_string_face = AREF (vector, 4);
8861 mode_line_string_face_prop = AREF (vector, 5);
8862
8863 if (!NILP (AREF (vector, 6)))
8864 {
8865 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
8866 AREF (vector, 6) = Qnil;
8867 }
8868
8869 Vmode_line_unwind_vector = vector;
8870 return Qnil;
8871 }
8872
8873
8874 /* Store a single character C for the frame title in mode_line_noprop_buf.
8875 Re-allocate mode_line_noprop_buf if necessary. */
8876
8877 static void
8878 #ifdef PROTOTYPES
8879 store_mode_line_noprop_char (char c)
8880 #else
8881 store_mode_line_noprop_char (c)
8882 char c;
8883 #endif
8884 {
8885 /* If output position has reached the end of the allocated buffer,
8886 double the buffer's size. */
8887 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
8888 {
8889 int len = MODE_LINE_NOPROP_LEN (0);
8890 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
8891 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
8892 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
8893 mode_line_noprop_ptr = mode_line_noprop_buf + len;
8894 }
8895
8896 *mode_line_noprop_ptr++ = c;
8897 }
8898
8899
8900 /* Store part of a frame title in mode_line_noprop_buf, beginning at
8901 mode_line_noprop_ptr. STR is the string to store. Do not copy
8902 characters that yield more columns than PRECISION; PRECISION <= 0
8903 means copy the whole string. Pad with spaces until FIELD_WIDTH
8904 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8905 pad. Called from display_mode_element when it is used to build a
8906 frame title. */
8907
8908 static int
8909 store_mode_line_noprop (str, field_width, precision)
8910 const unsigned char *str;
8911 int field_width, precision;
8912 {
8913 int n = 0;
8914 int dummy, nbytes;
8915
8916 /* Copy at most PRECISION chars from STR. */
8917 nbytes = strlen (str);
8918 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8919 while (nbytes--)
8920 store_mode_line_noprop_char (*str++);
8921
8922 /* Fill up with spaces until FIELD_WIDTH reached. */
8923 while (field_width > 0
8924 && n < field_width)
8925 {
8926 store_mode_line_noprop_char (' ');
8927 ++n;
8928 }
8929
8930 return n;
8931 }
8932
8933 /***********************************************************************
8934 Frame Titles
8935 ***********************************************************************/
8936
8937 #ifdef HAVE_WINDOW_SYSTEM
8938
8939 /* Set the title of FRAME, if it has changed. The title format is
8940 Vicon_title_format if FRAME is iconified, otherwise it is
8941 frame_title_format. */
8942
8943 static void
8944 x_consider_frame_title (frame)
8945 Lisp_Object frame;
8946 {
8947 struct frame *f = XFRAME (frame);
8948
8949 if (FRAME_WINDOW_P (f)
8950 || FRAME_MINIBUF_ONLY_P (f)
8951 || f->explicit_name)
8952 {
8953 /* Do we have more than one visible frame on this X display? */
8954 Lisp_Object tail;
8955 Lisp_Object fmt;
8956 int title_start;
8957 char *title;
8958 int len;
8959 struct it it;
8960 int count = SPECPDL_INDEX ();
8961
8962 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8963 {
8964 Lisp_Object other_frame = XCAR (tail);
8965 struct frame *tf = XFRAME (other_frame);
8966
8967 if (tf != f
8968 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8969 && !FRAME_MINIBUF_ONLY_P (tf)
8970 && !EQ (other_frame, tip_frame)
8971 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8972 break;
8973 }
8974
8975 /* Set global variable indicating that multiple frames exist. */
8976 multiple_frames = CONSP (tail);
8977
8978 /* Switch to the buffer of selected window of the frame. Set up
8979 mode_line_target so that display_mode_element will output into
8980 mode_line_noprop_buf; then display the title. */
8981 record_unwind_protect (unwind_format_mode_line,
8982 format_mode_line_unwind_data (current_buffer, 0));
8983
8984 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8985 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8986
8987 mode_line_target = MODE_LINE_TITLE;
8988 title_start = MODE_LINE_NOPROP_LEN (0);
8989 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8990 NULL, DEFAULT_FACE_ID);
8991 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8992 len = MODE_LINE_NOPROP_LEN (title_start);
8993 title = mode_line_noprop_buf + title_start;
8994 unbind_to (count, Qnil);
8995
8996 /* Set the title only if it's changed. This avoids consing in
8997 the common case where it hasn't. (If it turns out that we've
8998 already wasted too much time by walking through the list with
8999 display_mode_element, then we might need to optimize at a
9000 higher level than this.) */
9001 if (! STRINGP (f->name)
9002 || SBYTES (f->name) != len
9003 || bcmp (title, SDATA (f->name), len) != 0)
9004 x_implicitly_set_name (f, make_string (title, len), Qnil);
9005 }
9006 }
9007
9008 #endif /* not HAVE_WINDOW_SYSTEM */
9009
9010
9011
9012 \f
9013 /***********************************************************************
9014 Menu Bars
9015 ***********************************************************************/
9016
9017
9018 /* Prepare for redisplay by updating menu-bar item lists when
9019 appropriate. This can call eval. */
9020
9021 void
9022 prepare_menu_bars ()
9023 {
9024 int all_windows;
9025 struct gcpro gcpro1, gcpro2;
9026 struct frame *f;
9027 Lisp_Object tooltip_frame;
9028
9029 #ifdef HAVE_WINDOW_SYSTEM
9030 tooltip_frame = tip_frame;
9031 #else
9032 tooltip_frame = Qnil;
9033 #endif
9034
9035 /* Update all frame titles based on their buffer names, etc. We do
9036 this before the menu bars so that the buffer-menu will show the
9037 up-to-date frame titles. */
9038 #ifdef HAVE_WINDOW_SYSTEM
9039 if (windows_or_buffers_changed || update_mode_lines)
9040 {
9041 Lisp_Object tail, frame;
9042
9043 FOR_EACH_FRAME (tail, frame)
9044 {
9045 f = XFRAME (frame);
9046 if (!EQ (frame, tooltip_frame)
9047 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9048 x_consider_frame_title (frame);
9049 }
9050 }
9051 #endif /* HAVE_WINDOW_SYSTEM */
9052
9053 /* Update the menu bar item lists, if appropriate. This has to be
9054 done before any actual redisplay or generation of display lines. */
9055 all_windows = (update_mode_lines
9056 || buffer_shared > 1
9057 || windows_or_buffers_changed);
9058 if (all_windows)
9059 {
9060 Lisp_Object tail, frame;
9061 int count = SPECPDL_INDEX ();
9062 /* 1 means that update_menu_bar has run its hooks
9063 so any further calls to update_menu_bar shouldn't do so again. */
9064 int menu_bar_hooks_run = 0;
9065
9066 record_unwind_save_match_data ();
9067
9068 FOR_EACH_FRAME (tail, frame)
9069 {
9070 f = XFRAME (frame);
9071
9072 /* Ignore tooltip frame. */
9073 if (EQ (frame, tooltip_frame))
9074 continue;
9075
9076 /* If a window on this frame changed size, report that to
9077 the user and clear the size-change flag. */
9078 if (FRAME_WINDOW_SIZES_CHANGED (f))
9079 {
9080 Lisp_Object functions;
9081
9082 /* Clear flag first in case we get an error below. */
9083 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9084 functions = Vwindow_size_change_functions;
9085 GCPRO2 (tail, functions);
9086
9087 while (CONSP (functions))
9088 {
9089 call1 (XCAR (functions), frame);
9090 functions = XCDR (functions);
9091 }
9092 UNGCPRO;
9093 }
9094
9095 GCPRO1 (tail);
9096 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9097 #ifdef HAVE_WINDOW_SYSTEM
9098 update_tool_bar (f, 0);
9099 #ifdef MAC_OS
9100 mac_update_title_bar (f, 0);
9101 #endif
9102 #endif
9103 UNGCPRO;
9104 }
9105
9106 unbind_to (count, Qnil);
9107 }
9108 else
9109 {
9110 struct frame *sf = SELECTED_FRAME ();
9111 update_menu_bar (sf, 1, 0);
9112 #ifdef HAVE_WINDOW_SYSTEM
9113 update_tool_bar (sf, 1);
9114 #ifdef MAC_OS
9115 mac_update_title_bar (sf, 1);
9116 #endif
9117 #endif
9118 }
9119
9120 /* Motif needs this. See comment in xmenu.c. Turn it off when
9121 pending_menu_activation is not defined. */
9122 #ifdef USE_X_TOOLKIT
9123 pending_menu_activation = 0;
9124 #endif
9125 }
9126
9127
9128 /* Update the menu bar item list for frame F. This has to be done
9129 before we start to fill in any display lines, because it can call
9130 eval.
9131
9132 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9133
9134 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9135 already ran the menu bar hooks for this redisplay, so there
9136 is no need to run them again. The return value is the
9137 updated value of this flag, to pass to the next call. */
9138
9139 static int
9140 update_menu_bar (f, save_match_data, hooks_run)
9141 struct frame *f;
9142 int save_match_data;
9143 int hooks_run;
9144 {
9145 Lisp_Object window;
9146 register struct window *w;
9147
9148 /* If called recursively during a menu update, do nothing. This can
9149 happen when, for instance, an activate-menubar-hook causes a
9150 redisplay. */
9151 if (inhibit_menubar_update)
9152 return hooks_run;
9153
9154 window = FRAME_SELECTED_WINDOW (f);
9155 w = XWINDOW (window);
9156
9157 #if 0 /* The if statement below this if statement used to include the
9158 condition !NILP (w->update_mode_line), rather than using
9159 update_mode_lines directly, and this if statement may have
9160 been added to make that condition work. Now the if
9161 statement below matches its comment, this isn't needed. */
9162 if (update_mode_lines)
9163 w->update_mode_line = Qt;
9164 #endif
9165
9166 if (FRAME_WINDOW_P (f)
9167 ?
9168 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9169 || defined (USE_GTK)
9170 FRAME_EXTERNAL_MENU_BAR (f)
9171 #else
9172 FRAME_MENU_BAR_LINES (f) > 0
9173 #endif
9174 : FRAME_MENU_BAR_LINES (f) > 0)
9175 {
9176 /* If the user has switched buffers or windows, we need to
9177 recompute to reflect the new bindings. But we'll
9178 recompute when update_mode_lines is set too; that means
9179 that people can use force-mode-line-update to request
9180 that the menu bar be recomputed. The adverse effect on
9181 the rest of the redisplay algorithm is about the same as
9182 windows_or_buffers_changed anyway. */
9183 if (windows_or_buffers_changed
9184 /* This used to test w->update_mode_line, but we believe
9185 there is no need to recompute the menu in that case. */
9186 || update_mode_lines
9187 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9188 < BUF_MODIFF (XBUFFER (w->buffer)))
9189 != !NILP (w->last_had_star))
9190 || ((!NILP (Vtransient_mark_mode)
9191 && !NILP (XBUFFER (w->buffer)->mark_active))
9192 != !NILP (w->region_showing)))
9193 {
9194 struct buffer *prev = current_buffer;
9195 int count = SPECPDL_INDEX ();
9196
9197 specbind (Qinhibit_menubar_update, Qt);
9198
9199 set_buffer_internal_1 (XBUFFER (w->buffer));
9200 if (save_match_data)
9201 record_unwind_save_match_data ();
9202 if (NILP (Voverriding_local_map_menu_flag))
9203 {
9204 specbind (Qoverriding_terminal_local_map, Qnil);
9205 specbind (Qoverriding_local_map, Qnil);
9206 }
9207
9208 if (!hooks_run)
9209 {
9210 /* Run the Lucid hook. */
9211 safe_run_hooks (Qactivate_menubar_hook);
9212
9213 /* If it has changed current-menubar from previous value,
9214 really recompute the menu-bar from the value. */
9215 if (! NILP (Vlucid_menu_bar_dirty_flag))
9216 call0 (Qrecompute_lucid_menubar);
9217
9218 safe_run_hooks (Qmenu_bar_update_hook);
9219
9220 hooks_run = 1;
9221 }
9222
9223 XSETFRAME (Vmenu_updating_frame, f);
9224 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9225
9226 /* Redisplay the menu bar in case we changed it. */
9227 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9228 || defined (USE_GTK)
9229 if (FRAME_WINDOW_P (f))
9230 {
9231 #ifdef MAC_OS
9232 /* All frames on Mac OS share the same menubar. So only
9233 the selected frame should be allowed to set it. */
9234 if (f == SELECTED_FRAME ())
9235 #endif
9236 set_frame_menubar (f, 0, 0);
9237 }
9238 else
9239 /* On a terminal screen, the menu bar is an ordinary screen
9240 line, and this makes it get updated. */
9241 w->update_mode_line = Qt;
9242 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9243 /* In the non-toolkit version, the menu bar is an ordinary screen
9244 line, and this makes it get updated. */
9245 w->update_mode_line = Qt;
9246 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9247
9248 unbind_to (count, Qnil);
9249 set_buffer_internal_1 (prev);
9250 }
9251 }
9252
9253 return hooks_run;
9254 }
9255
9256
9257 \f
9258 /***********************************************************************
9259 Output Cursor
9260 ***********************************************************************/
9261
9262 #ifdef HAVE_WINDOW_SYSTEM
9263
9264 /* EXPORT:
9265 Nominal cursor position -- where to draw output.
9266 HPOS and VPOS are window relative glyph matrix coordinates.
9267 X and Y are window relative pixel coordinates. */
9268
9269 struct cursor_pos output_cursor;
9270
9271
9272 /* EXPORT:
9273 Set the global variable output_cursor to CURSOR. All cursor
9274 positions are relative to updated_window. */
9275
9276 void
9277 set_output_cursor (cursor)
9278 struct cursor_pos *cursor;
9279 {
9280 output_cursor.hpos = cursor->hpos;
9281 output_cursor.vpos = cursor->vpos;
9282 output_cursor.x = cursor->x;
9283 output_cursor.y = cursor->y;
9284 }
9285
9286
9287 /* EXPORT for RIF:
9288 Set a nominal cursor position.
9289
9290 HPOS and VPOS are column/row positions in a window glyph matrix. X
9291 and Y are window text area relative pixel positions.
9292
9293 If this is done during an update, updated_window will contain the
9294 window that is being updated and the position is the future output
9295 cursor position for that window. If updated_window is null, use
9296 selected_window and display the cursor at the given position. */
9297
9298 void
9299 x_cursor_to (vpos, hpos, y, x)
9300 int vpos, hpos, y, x;
9301 {
9302 struct window *w;
9303
9304 /* If updated_window is not set, work on selected_window. */
9305 if (updated_window)
9306 w = updated_window;
9307 else
9308 w = XWINDOW (selected_window);
9309
9310 /* Set the output cursor. */
9311 output_cursor.hpos = hpos;
9312 output_cursor.vpos = vpos;
9313 output_cursor.x = x;
9314 output_cursor.y = y;
9315
9316 /* If not called as part of an update, really display the cursor.
9317 This will also set the cursor position of W. */
9318 if (updated_window == NULL)
9319 {
9320 BLOCK_INPUT;
9321 display_and_set_cursor (w, 1, hpos, vpos, x, y);
9322 if (rif->flush_display_optional)
9323 rif->flush_display_optional (SELECTED_FRAME ());
9324 UNBLOCK_INPUT;
9325 }
9326 }
9327
9328 #endif /* HAVE_WINDOW_SYSTEM */
9329
9330 \f
9331 /***********************************************************************
9332 Tool-bars
9333 ***********************************************************************/
9334
9335 #ifdef HAVE_WINDOW_SYSTEM
9336
9337 /* Where the mouse was last time we reported a mouse event. */
9338
9339 FRAME_PTR last_mouse_frame;
9340
9341 /* Tool-bar item index of the item on which a mouse button was pressed
9342 or -1. */
9343
9344 int last_tool_bar_item;
9345
9346
9347 /* Update the tool-bar item list for frame F. This has to be done
9348 before we start to fill in any display lines. Called from
9349 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9350 and restore it here. */
9351
9352 static void
9353 update_tool_bar (f, save_match_data)
9354 struct frame *f;
9355 int save_match_data;
9356 {
9357 #ifdef USE_GTK
9358 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
9359 #else
9360 int do_update = WINDOWP (f->tool_bar_window)
9361 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
9362 #endif
9363
9364 if (do_update)
9365 {
9366 Lisp_Object window;
9367 struct window *w;
9368
9369 window = FRAME_SELECTED_WINDOW (f);
9370 w = XWINDOW (window);
9371
9372 /* If the user has switched buffers or windows, we need to
9373 recompute to reflect the new bindings. But we'll
9374 recompute when update_mode_lines is set too; that means
9375 that people can use force-mode-line-update to request
9376 that the menu bar be recomputed. The adverse effect on
9377 the rest of the redisplay algorithm is about the same as
9378 windows_or_buffers_changed anyway. */
9379 if (windows_or_buffers_changed
9380 || !NILP (w->update_mode_line)
9381 || update_mode_lines
9382 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9383 < BUF_MODIFF (XBUFFER (w->buffer)))
9384 != !NILP (w->last_had_star))
9385 || ((!NILP (Vtransient_mark_mode)
9386 && !NILP (XBUFFER (w->buffer)->mark_active))
9387 != !NILP (w->region_showing)))
9388 {
9389 struct buffer *prev = current_buffer;
9390 int count = SPECPDL_INDEX ();
9391 Lisp_Object new_tool_bar;
9392 int new_n_tool_bar;
9393 struct gcpro gcpro1;
9394
9395 /* Set current_buffer to the buffer of the selected
9396 window of the frame, so that we get the right local
9397 keymaps. */
9398 set_buffer_internal_1 (XBUFFER (w->buffer));
9399
9400 /* Save match data, if we must. */
9401 if (save_match_data)
9402 record_unwind_save_match_data ();
9403
9404 /* Make sure that we don't accidentally use bogus keymaps. */
9405 if (NILP (Voverriding_local_map_menu_flag))
9406 {
9407 specbind (Qoverriding_terminal_local_map, Qnil);
9408 specbind (Qoverriding_local_map, Qnil);
9409 }
9410
9411 GCPRO1 (new_tool_bar);
9412
9413 /* Build desired tool-bar items from keymaps. */
9414 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
9415 &new_n_tool_bar);
9416
9417 /* Redisplay the tool-bar if we changed it. */
9418 if (new_n_tool_bar != f->n_tool_bar_items
9419 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
9420 {
9421 /* Redisplay that happens asynchronously due to an expose event
9422 may access f->tool_bar_items. Make sure we update both
9423 variables within BLOCK_INPUT so no such event interrupts. */
9424 BLOCK_INPUT;
9425 f->tool_bar_items = new_tool_bar;
9426 f->n_tool_bar_items = new_n_tool_bar;
9427 w->update_mode_line = Qt;
9428 UNBLOCK_INPUT;
9429 }
9430
9431 UNGCPRO;
9432
9433 unbind_to (count, Qnil);
9434 set_buffer_internal_1 (prev);
9435 }
9436 }
9437 }
9438
9439
9440 /* Set F->desired_tool_bar_string to a Lisp string representing frame
9441 F's desired tool-bar contents. F->tool_bar_items must have
9442 been set up previously by calling prepare_menu_bars. */
9443
9444 static void
9445 build_desired_tool_bar_string (f)
9446 struct frame *f;
9447 {
9448 int i, size, size_needed;
9449 struct gcpro gcpro1, gcpro2, gcpro3;
9450 Lisp_Object image, plist, props;
9451
9452 image = plist = props = Qnil;
9453 GCPRO3 (image, plist, props);
9454
9455 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
9456 Otherwise, make a new string. */
9457
9458 /* The size of the string we might be able to reuse. */
9459 size = (STRINGP (f->desired_tool_bar_string)
9460 ? SCHARS (f->desired_tool_bar_string)
9461 : 0);
9462
9463 /* We need one space in the string for each image. */
9464 size_needed = f->n_tool_bar_items;
9465
9466 /* Reuse f->desired_tool_bar_string, if possible. */
9467 if (size < size_needed || NILP (f->desired_tool_bar_string))
9468 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
9469 make_number (' '));
9470 else
9471 {
9472 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
9473 Fremove_text_properties (make_number (0), make_number (size),
9474 props, f->desired_tool_bar_string);
9475 }
9476
9477 /* Put a `display' property on the string for the images to display,
9478 put a `menu_item' property on tool-bar items with a value that
9479 is the index of the item in F's tool-bar item vector. */
9480 for (i = 0; i < f->n_tool_bar_items; ++i)
9481 {
9482 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
9483
9484 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
9485 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
9486 int hmargin, vmargin, relief, idx, end;
9487 extern Lisp_Object QCrelief, QCmargin, QCconversion;
9488
9489 /* If image is a vector, choose the image according to the
9490 button state. */
9491 image = PROP (TOOL_BAR_ITEM_IMAGES);
9492 if (VECTORP (image))
9493 {
9494 if (enabled_p)
9495 idx = (selected_p
9496 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
9497 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
9498 else
9499 idx = (selected_p
9500 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
9501 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
9502
9503 xassert (ASIZE (image) >= idx);
9504 image = AREF (image, idx);
9505 }
9506 else
9507 idx = -1;
9508
9509 /* Ignore invalid image specifications. */
9510 if (!valid_image_p (image))
9511 continue;
9512
9513 /* Display the tool-bar button pressed, or depressed. */
9514 plist = Fcopy_sequence (XCDR (image));
9515
9516 /* Compute margin and relief to draw. */
9517 relief = (tool_bar_button_relief >= 0
9518 ? tool_bar_button_relief
9519 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
9520 hmargin = vmargin = relief;
9521
9522 if (INTEGERP (Vtool_bar_button_margin)
9523 && XINT (Vtool_bar_button_margin) > 0)
9524 {
9525 hmargin += XFASTINT (Vtool_bar_button_margin);
9526 vmargin += XFASTINT (Vtool_bar_button_margin);
9527 }
9528 else if (CONSP (Vtool_bar_button_margin))
9529 {
9530 if (INTEGERP (XCAR (Vtool_bar_button_margin))
9531 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
9532 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
9533
9534 if (INTEGERP (XCDR (Vtool_bar_button_margin))
9535 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
9536 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
9537 }
9538
9539 if (auto_raise_tool_bar_buttons_p)
9540 {
9541 /* Add a `:relief' property to the image spec if the item is
9542 selected. */
9543 if (selected_p)
9544 {
9545 plist = Fplist_put (plist, QCrelief, make_number (-relief));
9546 hmargin -= relief;
9547 vmargin -= relief;
9548 }
9549 }
9550 else
9551 {
9552 /* If image is selected, display it pressed, i.e. with a
9553 negative relief. If it's not selected, display it with a
9554 raised relief. */
9555 plist = Fplist_put (plist, QCrelief,
9556 (selected_p
9557 ? make_number (-relief)
9558 : make_number (relief)));
9559 hmargin -= relief;
9560 vmargin -= relief;
9561 }
9562
9563 /* Put a margin around the image. */
9564 if (hmargin || vmargin)
9565 {
9566 if (hmargin == vmargin)
9567 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
9568 else
9569 plist = Fplist_put (plist, QCmargin,
9570 Fcons (make_number (hmargin),
9571 make_number (vmargin)));
9572 }
9573
9574 /* If button is not enabled, and we don't have special images
9575 for the disabled state, make the image appear disabled by
9576 applying an appropriate algorithm to it. */
9577 if (!enabled_p && idx < 0)
9578 plist = Fplist_put (plist, QCconversion, Qdisabled);
9579
9580 /* Put a `display' text property on the string for the image to
9581 display. Put a `menu-item' property on the string that gives
9582 the start of this item's properties in the tool-bar items
9583 vector. */
9584 image = Fcons (Qimage, plist);
9585 props = list4 (Qdisplay, image,
9586 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
9587
9588 /* Let the last image hide all remaining spaces in the tool bar
9589 string. The string can be longer than needed when we reuse a
9590 previous string. */
9591 if (i + 1 == f->n_tool_bar_items)
9592 end = SCHARS (f->desired_tool_bar_string);
9593 else
9594 end = i + 1;
9595 Fadd_text_properties (make_number (i), make_number (end),
9596 props, f->desired_tool_bar_string);
9597 #undef PROP
9598 }
9599
9600 UNGCPRO;
9601 }
9602
9603
9604 /* Display one line of the tool-bar of frame IT->f.
9605
9606 HEIGHT specifies the desired height of the tool-bar line.
9607 If the actual height of the glyph row is less than HEIGHT, the
9608 row's height is increased to HEIGHT, and the icons are centered
9609 vertically in the new height.
9610
9611 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
9612 count a final empty row in case the tool-bar width exactly matches
9613 the window width.
9614 */
9615
9616 static void
9617 display_tool_bar_line (it, height)
9618 struct it *it;
9619 int height;
9620 {
9621 struct glyph_row *row = it->glyph_row;
9622 int max_x = it->last_visible_x;
9623 struct glyph *last;
9624
9625 prepare_desired_row (row);
9626 row->y = it->current_y;
9627
9628 /* Note that this isn't made use of if the face hasn't a box,
9629 so there's no need to check the face here. */
9630 it->start_of_box_run_p = 1;
9631
9632 while (it->current_x < max_x)
9633 {
9634 int x, n_glyphs_before, i, nglyphs;
9635 struct it it_before;
9636
9637 /* Get the next display element. */
9638 if (!get_next_display_element (it))
9639 {
9640 /* Don't count empty row if we are counting needed tool-bar lines. */
9641 if (height < 0 && !it->hpos)
9642 return;
9643 break;
9644 }
9645
9646 /* Produce glyphs. */
9647 n_glyphs_before = row->used[TEXT_AREA];
9648 it_before = *it;
9649
9650 PRODUCE_GLYPHS (it);
9651
9652 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
9653 i = 0;
9654 x = it_before.current_x;
9655 while (i < nglyphs)
9656 {
9657 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
9658
9659 if (x + glyph->pixel_width > max_x)
9660 {
9661 /* Glyph doesn't fit on line. Backtrack. */
9662 row->used[TEXT_AREA] = n_glyphs_before;
9663 *it = it_before;
9664 /* If this is the only glyph on this line, it will never fit on the
9665 toolbar, so skip it. But ensure there is at least one glyph,
9666 so we don't accidentally disable the tool-bar. */
9667 if (n_glyphs_before == 0
9668 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
9669 break;
9670 goto out;
9671 }
9672
9673 ++it->hpos;
9674 x += glyph->pixel_width;
9675 ++i;
9676 }
9677
9678 /* Stop at line ends. */
9679 if (ITERATOR_AT_END_OF_LINE_P (it))
9680 break;
9681
9682 set_iterator_to_next (it, 1);
9683 }
9684
9685 out:;
9686
9687 row->displays_text_p = row->used[TEXT_AREA] != 0;
9688 /* Use default face for the border below the tool bar. */
9689 if (!row->displays_text_p)
9690 it->face_id = DEFAULT_FACE_ID;
9691 extend_face_to_end_of_line (it);
9692 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
9693 last->right_box_line_p = 1;
9694 if (last == row->glyphs[TEXT_AREA])
9695 last->left_box_line_p = 1;
9696
9697 /* Make line the desired height and center it vertically. */
9698 if ((height -= it->max_ascent + it->max_descent) > 0)
9699 {
9700 /* Don't add more than one line height. */
9701 height %= FRAME_LINE_HEIGHT (it->f);
9702 it->max_ascent += height / 2;
9703 it->max_descent += (height + 1) / 2;
9704 }
9705
9706 compute_line_metrics (it);
9707
9708 /* If line is empty, make it occupy the rest of the tool-bar. */
9709 if (!row->displays_text_p)
9710 {
9711 row->height = row->phys_height = it->last_visible_y - row->y;
9712 row->ascent = row->phys_ascent = 0;
9713 row->extra_line_spacing = 0;
9714 }
9715
9716 row->full_width_p = 1;
9717 row->continued_p = 0;
9718 row->truncated_on_left_p = 0;
9719 row->truncated_on_right_p = 0;
9720
9721 it->current_x = it->hpos = 0;
9722 it->current_y += row->height;
9723 ++it->vpos;
9724 ++it->glyph_row;
9725 }
9726
9727
9728 /* Max tool-bar height. */
9729
9730 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
9731 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
9732
9733 /* Value is the number of screen lines needed to make all tool-bar
9734 items of frame F visible. The number of actual rows needed is
9735 returned in *N_ROWS if non-NULL. */
9736
9737 static int
9738 tool_bar_lines_needed (f, n_rows)
9739 struct frame *f;
9740 int *n_rows;
9741 {
9742 struct window *w = XWINDOW (f->tool_bar_window);
9743 struct it it;
9744 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
9745 the desired matrix, so use (unused) mode-line row as temporary row to
9746 avoid destroying the first tool-bar row. */
9747 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
9748
9749 /* Initialize an iterator for iteration over
9750 F->desired_tool_bar_string in the tool-bar window of frame F. */
9751 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
9752 it.first_visible_x = 0;
9753 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9754 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9755
9756 while (!ITERATOR_AT_END_P (&it))
9757 {
9758 clear_glyph_row (temp_row);
9759 it.glyph_row = temp_row;
9760 display_tool_bar_line (&it, -1);
9761 }
9762 clear_glyph_row (temp_row);
9763
9764 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
9765 if (n_rows)
9766 *n_rows = it.vpos > 0 ? it.vpos : -1;
9767
9768 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
9769 }
9770
9771
9772 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
9773 0, 1, 0,
9774 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
9775 (frame)
9776 Lisp_Object frame;
9777 {
9778 struct frame *f;
9779 struct window *w;
9780 int nlines = 0;
9781
9782 if (NILP (frame))
9783 frame = selected_frame;
9784 else
9785 CHECK_FRAME (frame);
9786 f = XFRAME (frame);
9787
9788 if (WINDOWP (f->tool_bar_window)
9789 || (w = XWINDOW (f->tool_bar_window),
9790 WINDOW_TOTAL_LINES (w) > 0))
9791 {
9792 update_tool_bar (f, 1);
9793 if (f->n_tool_bar_items)
9794 {
9795 build_desired_tool_bar_string (f);
9796 nlines = tool_bar_lines_needed (f, NULL);
9797 }
9798 }
9799
9800 return make_number (nlines);
9801 }
9802
9803
9804 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9805 height should be changed. */
9806
9807 static int
9808 redisplay_tool_bar (f)
9809 struct frame *f;
9810 {
9811 struct window *w;
9812 struct it it;
9813 struct glyph_row *row;
9814 int change_height_p = 0;
9815
9816 #ifdef USE_GTK
9817 if (FRAME_EXTERNAL_TOOL_BAR (f))
9818 update_frame_tool_bar (f);
9819 return 0;
9820 #endif
9821
9822 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9823 do anything. This means you must start with tool-bar-lines
9824 non-zero to get the auto-sizing effect. Or in other words, you
9825 can turn off tool-bars by specifying tool-bar-lines zero. */
9826 if (!WINDOWP (f->tool_bar_window)
9827 || (w = XWINDOW (f->tool_bar_window),
9828 WINDOW_TOTAL_LINES (w) == 0))
9829 return 0;
9830
9831 /* Set up an iterator for the tool-bar window. */
9832 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9833 it.first_visible_x = 0;
9834 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9835 row = it.glyph_row;
9836
9837 /* Build a string that represents the contents of the tool-bar. */
9838 build_desired_tool_bar_string (f);
9839 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9840
9841 if (f->n_tool_bar_rows == 0)
9842 {
9843 int nlines;
9844
9845 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
9846 nlines != WINDOW_TOTAL_LINES (w)))
9847 {
9848 extern Lisp_Object Qtool_bar_lines;
9849 Lisp_Object frame;
9850 int old_height = WINDOW_TOTAL_LINES (w);
9851
9852 XSETFRAME (frame, f);
9853 Fmodify_frame_parameters (frame,
9854 Fcons (Fcons (Qtool_bar_lines,
9855 make_number (nlines)),
9856 Qnil));
9857 if (WINDOW_TOTAL_LINES (w) != old_height)
9858 {
9859 clear_glyph_matrix (w->desired_matrix);
9860 fonts_changed_p = 1;
9861 return 1;
9862 }
9863 }
9864 }
9865
9866 /* Display as many lines as needed to display all tool-bar items. */
9867
9868 if (f->n_tool_bar_rows > 0)
9869 {
9870 int border, rows, height, extra;
9871
9872 if (INTEGERP (Vtool_bar_border))
9873 border = XINT (Vtool_bar_border);
9874 else if (EQ (Vtool_bar_border, Qinternal_border_width))
9875 border = FRAME_INTERNAL_BORDER_WIDTH (f);
9876 else if (EQ (Vtool_bar_border, Qborder_width))
9877 border = f->border_width;
9878 else
9879 border = 0;
9880 if (border < 0)
9881 border = 0;
9882
9883 rows = f->n_tool_bar_rows;
9884 height = max (1, (it.last_visible_y - border) / rows);
9885 extra = it.last_visible_y - border - height * rows;
9886
9887 while (it.current_y < it.last_visible_y)
9888 {
9889 int h = 0;
9890 if (extra > 0 && rows-- > 0)
9891 {
9892 h = (extra + rows - 1) / rows;
9893 extra -= h;
9894 }
9895 display_tool_bar_line (&it, height + h);
9896 }
9897 }
9898 else
9899 {
9900 while (it.current_y < it.last_visible_y)
9901 display_tool_bar_line (&it, 0);
9902 }
9903
9904 /* It doesn't make much sense to try scrolling in the tool-bar
9905 window, so don't do it. */
9906 w->desired_matrix->no_scrolling_p = 1;
9907 w->must_be_updated_p = 1;
9908
9909 if (auto_resize_tool_bars_p)
9910 {
9911 int nlines, nrows;
9912 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
9913
9914 /* If we couldn't display everything, change the tool-bar's
9915 height if there is room for more. */
9916 if (IT_STRING_CHARPOS (it) < it.end_charpos
9917 && it.current_y < max_tool_bar_height)
9918 change_height_p = 1;
9919
9920 row = it.glyph_row - 1;
9921
9922 /* If there are blank lines at the end, except for a partially
9923 visible blank line at the end that is smaller than
9924 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9925 if (!row->displays_text_p
9926 && row->height >= FRAME_LINE_HEIGHT (f))
9927 change_height_p = 1;
9928
9929 /* If row displays tool-bar items, but is partially visible,
9930 change the tool-bar's height. */
9931 if (row->displays_text_p
9932 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
9933 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
9934 change_height_p = 1;
9935
9936 /* Resize windows as needed by changing the `tool-bar-lines'
9937 frame parameter. */
9938 if (change_height_p
9939 && (nlines = tool_bar_lines_needed (f, &nrows),
9940 nlines != WINDOW_TOTAL_LINES (w)))
9941 {
9942 extern Lisp_Object Qtool_bar_lines;
9943 Lisp_Object frame;
9944 int old_height = WINDOW_TOTAL_LINES (w);
9945
9946 XSETFRAME (frame, f);
9947 Fmodify_frame_parameters (frame,
9948 Fcons (Fcons (Qtool_bar_lines,
9949 make_number (nlines)),
9950 Qnil));
9951 if (WINDOW_TOTAL_LINES (w) != old_height)
9952 {
9953 clear_glyph_matrix (w->desired_matrix);
9954 f->n_tool_bar_rows = nrows;
9955 fonts_changed_p = 1;
9956 }
9957 }
9958 }
9959
9960 return change_height_p;
9961 }
9962
9963
9964 /* Get information about the tool-bar item which is displayed in GLYPH
9965 on frame F. Return in *PROP_IDX the index where tool-bar item
9966 properties start in F->tool_bar_items. Value is zero if
9967 GLYPH doesn't display a tool-bar item. */
9968
9969 static int
9970 tool_bar_item_info (f, glyph, prop_idx)
9971 struct frame *f;
9972 struct glyph *glyph;
9973 int *prop_idx;
9974 {
9975 Lisp_Object prop;
9976 int success_p;
9977 int charpos;
9978
9979 /* This function can be called asynchronously, which means we must
9980 exclude any possibility that Fget_text_property signals an
9981 error. */
9982 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
9983 charpos = max (0, charpos);
9984
9985 /* Get the text property `menu-item' at pos. The value of that
9986 property is the start index of this item's properties in
9987 F->tool_bar_items. */
9988 prop = Fget_text_property (make_number (charpos),
9989 Qmenu_item, f->current_tool_bar_string);
9990 if (INTEGERP (prop))
9991 {
9992 *prop_idx = XINT (prop);
9993 success_p = 1;
9994 }
9995 else
9996 success_p = 0;
9997
9998 return success_p;
9999 }
10000
10001 \f
10002 /* Get information about the tool-bar item at position X/Y on frame F.
10003 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10004 the current matrix of the tool-bar window of F, or NULL if not
10005 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10006 item in F->tool_bar_items. Value is
10007
10008 -1 if X/Y is not on a tool-bar item
10009 0 if X/Y is on the same item that was highlighted before.
10010 1 otherwise. */
10011
10012 static int
10013 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
10014 struct frame *f;
10015 int x, y;
10016 struct glyph **glyph;
10017 int *hpos, *vpos, *prop_idx;
10018 {
10019 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10020 struct window *w = XWINDOW (f->tool_bar_window);
10021 int area;
10022
10023 /* Find the glyph under X/Y. */
10024 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10025 if (*glyph == NULL)
10026 return -1;
10027
10028 /* Get the start of this tool-bar item's properties in
10029 f->tool_bar_items. */
10030 if (!tool_bar_item_info (f, *glyph, prop_idx))
10031 return -1;
10032
10033 /* Is mouse on the highlighted item? */
10034 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10035 && *vpos >= dpyinfo->mouse_face_beg_row
10036 && *vpos <= dpyinfo->mouse_face_end_row
10037 && (*vpos > dpyinfo->mouse_face_beg_row
10038 || *hpos >= dpyinfo->mouse_face_beg_col)
10039 && (*vpos < dpyinfo->mouse_face_end_row
10040 || *hpos < dpyinfo->mouse_face_end_col
10041 || dpyinfo->mouse_face_past_end))
10042 return 0;
10043
10044 return 1;
10045 }
10046
10047
10048 /* EXPORT:
10049 Handle mouse button event on the tool-bar of frame F, at
10050 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10051 0 for button release. MODIFIERS is event modifiers for button
10052 release. */
10053
10054 void
10055 handle_tool_bar_click (f, x, y, down_p, modifiers)
10056 struct frame *f;
10057 int x, y, down_p;
10058 unsigned int modifiers;
10059 {
10060 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10061 struct window *w = XWINDOW (f->tool_bar_window);
10062 int hpos, vpos, prop_idx;
10063 struct glyph *glyph;
10064 Lisp_Object enabled_p;
10065
10066 /* If not on the highlighted tool-bar item, return. */
10067 frame_to_window_pixel_xy (w, &x, &y);
10068 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10069 return;
10070
10071 /* If item is disabled, do nothing. */
10072 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10073 if (NILP (enabled_p))
10074 return;
10075
10076 if (down_p)
10077 {
10078 /* Show item in pressed state. */
10079 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10080 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10081 last_tool_bar_item = prop_idx;
10082 }
10083 else
10084 {
10085 Lisp_Object key, frame;
10086 struct input_event event;
10087 EVENT_INIT (event);
10088
10089 /* Show item in released state. */
10090 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10091 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10092
10093 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10094
10095 XSETFRAME (frame, f);
10096 event.kind = TOOL_BAR_EVENT;
10097 event.frame_or_window = frame;
10098 event.arg = frame;
10099 kbd_buffer_store_event (&event);
10100
10101 event.kind = TOOL_BAR_EVENT;
10102 event.frame_or_window = frame;
10103 event.arg = key;
10104 event.modifiers = modifiers;
10105 kbd_buffer_store_event (&event);
10106 last_tool_bar_item = -1;
10107 }
10108 }
10109
10110
10111 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10112 tool-bar window-relative coordinates X/Y. Called from
10113 note_mouse_highlight. */
10114
10115 static void
10116 note_tool_bar_highlight (f, x, y)
10117 struct frame *f;
10118 int x, y;
10119 {
10120 Lisp_Object window = f->tool_bar_window;
10121 struct window *w = XWINDOW (window);
10122 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10123 int hpos, vpos;
10124 struct glyph *glyph;
10125 struct glyph_row *row;
10126 int i;
10127 Lisp_Object enabled_p;
10128 int prop_idx;
10129 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10130 int mouse_down_p, rc;
10131
10132 /* Function note_mouse_highlight is called with negative x(y
10133 values when mouse moves outside of the frame. */
10134 if (x <= 0 || y <= 0)
10135 {
10136 clear_mouse_face (dpyinfo);
10137 return;
10138 }
10139
10140 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10141 if (rc < 0)
10142 {
10143 /* Not on tool-bar item. */
10144 clear_mouse_face (dpyinfo);
10145 return;
10146 }
10147 else if (rc == 0)
10148 /* On same tool-bar item as before. */
10149 goto set_help_echo;
10150
10151 clear_mouse_face (dpyinfo);
10152
10153 /* Mouse is down, but on different tool-bar item? */
10154 mouse_down_p = (dpyinfo->grabbed
10155 && f == last_mouse_frame
10156 && FRAME_LIVE_P (f));
10157 if (mouse_down_p
10158 && last_tool_bar_item != prop_idx)
10159 return;
10160
10161 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10162 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10163
10164 /* If tool-bar item is not enabled, don't highlight it. */
10165 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10166 if (!NILP (enabled_p))
10167 {
10168 /* Compute the x-position of the glyph. In front and past the
10169 image is a space. We include this in the highlighted area. */
10170 row = MATRIX_ROW (w->current_matrix, vpos);
10171 for (i = x = 0; i < hpos; ++i)
10172 x += row->glyphs[TEXT_AREA][i].pixel_width;
10173
10174 /* Record this as the current active region. */
10175 dpyinfo->mouse_face_beg_col = hpos;
10176 dpyinfo->mouse_face_beg_row = vpos;
10177 dpyinfo->mouse_face_beg_x = x;
10178 dpyinfo->mouse_face_beg_y = row->y;
10179 dpyinfo->mouse_face_past_end = 0;
10180
10181 dpyinfo->mouse_face_end_col = hpos + 1;
10182 dpyinfo->mouse_face_end_row = vpos;
10183 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10184 dpyinfo->mouse_face_end_y = row->y;
10185 dpyinfo->mouse_face_window = window;
10186 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10187
10188 /* Display it as active. */
10189 show_mouse_face (dpyinfo, draw);
10190 dpyinfo->mouse_face_image_state = draw;
10191 }
10192
10193 set_help_echo:
10194
10195 /* Set help_echo_string to a help string to display for this tool-bar item.
10196 XTread_socket does the rest. */
10197 help_echo_object = help_echo_window = Qnil;
10198 help_echo_pos = -1;
10199 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10200 if (NILP (help_echo_string))
10201 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10202 }
10203
10204 #endif /* HAVE_WINDOW_SYSTEM */
10205
10206
10207 \f
10208 /************************************************************************
10209 Horizontal scrolling
10210 ************************************************************************/
10211
10212 static int hscroll_window_tree P_ ((Lisp_Object));
10213 static int hscroll_windows P_ ((Lisp_Object));
10214
10215 /* For all leaf windows in the window tree rooted at WINDOW, set their
10216 hscroll value so that PT is (i) visible in the window, and (ii) so
10217 that it is not within a certain margin at the window's left and
10218 right border. Value is non-zero if any window's hscroll has been
10219 changed. */
10220
10221 static int
10222 hscroll_window_tree (window)
10223 Lisp_Object window;
10224 {
10225 int hscrolled_p = 0;
10226 int hscroll_relative_p = FLOATP (Vhscroll_step);
10227 int hscroll_step_abs = 0;
10228 double hscroll_step_rel = 0;
10229
10230 if (hscroll_relative_p)
10231 {
10232 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10233 if (hscroll_step_rel < 0)
10234 {
10235 hscroll_relative_p = 0;
10236 hscroll_step_abs = 0;
10237 }
10238 }
10239 else if (INTEGERP (Vhscroll_step))
10240 {
10241 hscroll_step_abs = XINT (Vhscroll_step);
10242 if (hscroll_step_abs < 0)
10243 hscroll_step_abs = 0;
10244 }
10245 else
10246 hscroll_step_abs = 0;
10247
10248 while (WINDOWP (window))
10249 {
10250 struct window *w = XWINDOW (window);
10251
10252 if (WINDOWP (w->hchild))
10253 hscrolled_p |= hscroll_window_tree (w->hchild);
10254 else if (WINDOWP (w->vchild))
10255 hscrolled_p |= hscroll_window_tree (w->vchild);
10256 else if (w->cursor.vpos >= 0)
10257 {
10258 int h_margin;
10259 int text_area_width;
10260 struct glyph_row *current_cursor_row
10261 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10262 struct glyph_row *desired_cursor_row
10263 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10264 struct glyph_row *cursor_row
10265 = (desired_cursor_row->enabled_p
10266 ? desired_cursor_row
10267 : current_cursor_row);
10268
10269 text_area_width = window_box_width (w, TEXT_AREA);
10270
10271 /* Scroll when cursor is inside this scroll margin. */
10272 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
10273
10274 if ((XFASTINT (w->hscroll)
10275 && w->cursor.x <= h_margin)
10276 || (cursor_row->enabled_p
10277 && cursor_row->truncated_on_right_p
10278 && (w->cursor.x >= text_area_width - h_margin)))
10279 {
10280 struct it it;
10281 int hscroll;
10282 struct buffer *saved_current_buffer;
10283 int pt;
10284 int wanted_x;
10285
10286 /* Find point in a display of infinite width. */
10287 saved_current_buffer = current_buffer;
10288 current_buffer = XBUFFER (w->buffer);
10289
10290 if (w == XWINDOW (selected_window))
10291 pt = BUF_PT (current_buffer);
10292 else
10293 {
10294 pt = marker_position (w->pointm);
10295 pt = max (BEGV, pt);
10296 pt = min (ZV, pt);
10297 }
10298
10299 /* Move iterator to pt starting at cursor_row->start in
10300 a line with infinite width. */
10301 init_to_row_start (&it, w, cursor_row);
10302 it.last_visible_x = INFINITY;
10303 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
10304 current_buffer = saved_current_buffer;
10305
10306 /* Position cursor in window. */
10307 if (!hscroll_relative_p && hscroll_step_abs == 0)
10308 hscroll = max (0, (it.current_x
10309 - (ITERATOR_AT_END_OF_LINE_P (&it)
10310 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
10311 : (text_area_width / 2))))
10312 / FRAME_COLUMN_WIDTH (it.f);
10313 else if (w->cursor.x >= text_area_width - h_margin)
10314 {
10315 if (hscroll_relative_p)
10316 wanted_x = text_area_width * (1 - hscroll_step_rel)
10317 - h_margin;
10318 else
10319 wanted_x = text_area_width
10320 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10321 - h_margin;
10322 hscroll
10323 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10324 }
10325 else
10326 {
10327 if (hscroll_relative_p)
10328 wanted_x = text_area_width * hscroll_step_rel
10329 + h_margin;
10330 else
10331 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10332 + h_margin;
10333 hscroll
10334 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10335 }
10336 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
10337
10338 /* Don't call Fset_window_hscroll if value hasn't
10339 changed because it will prevent redisplay
10340 optimizations. */
10341 if (XFASTINT (w->hscroll) != hscroll)
10342 {
10343 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
10344 w->hscroll = make_number (hscroll);
10345 hscrolled_p = 1;
10346 }
10347 }
10348 }
10349
10350 window = w->next;
10351 }
10352
10353 /* Value is non-zero if hscroll of any leaf window has been changed. */
10354 return hscrolled_p;
10355 }
10356
10357
10358 /* Set hscroll so that cursor is visible and not inside horizontal
10359 scroll margins for all windows in the tree rooted at WINDOW. See
10360 also hscroll_window_tree above. Value is non-zero if any window's
10361 hscroll has been changed. If it has, desired matrices on the frame
10362 of WINDOW are cleared. */
10363
10364 static int
10365 hscroll_windows (window)
10366 Lisp_Object window;
10367 {
10368 int hscrolled_p;
10369
10370 if (automatic_hscrolling_p)
10371 {
10372 hscrolled_p = hscroll_window_tree (window);
10373 if (hscrolled_p)
10374 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
10375 }
10376 else
10377 hscrolled_p = 0;
10378 return hscrolled_p;
10379 }
10380
10381
10382 \f
10383 /************************************************************************
10384 Redisplay
10385 ************************************************************************/
10386
10387 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
10388 to a non-zero value. This is sometimes handy to have in a debugger
10389 session. */
10390
10391 #if GLYPH_DEBUG
10392
10393 /* First and last unchanged row for try_window_id. */
10394
10395 int debug_first_unchanged_at_end_vpos;
10396 int debug_last_unchanged_at_beg_vpos;
10397
10398 /* Delta vpos and y. */
10399
10400 int debug_dvpos, debug_dy;
10401
10402 /* Delta in characters and bytes for try_window_id. */
10403
10404 int debug_delta, debug_delta_bytes;
10405
10406 /* Values of window_end_pos and window_end_vpos at the end of
10407 try_window_id. */
10408
10409 EMACS_INT debug_end_pos, debug_end_vpos;
10410
10411 /* Append a string to W->desired_matrix->method. FMT is a printf
10412 format string. A1...A9 are a supplement for a variable-length
10413 argument list. If trace_redisplay_p is non-zero also printf the
10414 resulting string to stderr. */
10415
10416 static void
10417 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
10418 struct window *w;
10419 char *fmt;
10420 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
10421 {
10422 char buffer[512];
10423 char *method = w->desired_matrix->method;
10424 int len = strlen (method);
10425 int size = sizeof w->desired_matrix->method;
10426 int remaining = size - len - 1;
10427
10428 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
10429 if (len && remaining)
10430 {
10431 method[len] = '|';
10432 --remaining, ++len;
10433 }
10434
10435 strncpy (method + len, buffer, remaining);
10436
10437 if (trace_redisplay_p)
10438 fprintf (stderr, "%p (%s): %s\n",
10439 w,
10440 ((BUFFERP (w->buffer)
10441 && STRINGP (XBUFFER (w->buffer)->name))
10442 ? (char *) SDATA (XBUFFER (w->buffer)->name)
10443 : "no buffer"),
10444 buffer);
10445 }
10446
10447 #endif /* GLYPH_DEBUG */
10448
10449
10450 /* Value is non-zero if all changes in window W, which displays
10451 current_buffer, are in the text between START and END. START is a
10452 buffer position, END is given as a distance from Z. Used in
10453 redisplay_internal for display optimization. */
10454
10455 static INLINE int
10456 text_outside_line_unchanged_p (w, start, end)
10457 struct window *w;
10458 int start, end;
10459 {
10460 int unchanged_p = 1;
10461
10462 /* If text or overlays have changed, see where. */
10463 if (XFASTINT (w->last_modified) < MODIFF
10464 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10465 {
10466 /* Gap in the line? */
10467 if (GPT < start || Z - GPT < end)
10468 unchanged_p = 0;
10469
10470 /* Changes start in front of the line, or end after it? */
10471 if (unchanged_p
10472 && (BEG_UNCHANGED < start - 1
10473 || END_UNCHANGED < end))
10474 unchanged_p = 0;
10475
10476 /* If selective display, can't optimize if changes start at the
10477 beginning of the line. */
10478 if (unchanged_p
10479 && INTEGERP (current_buffer->selective_display)
10480 && XINT (current_buffer->selective_display) > 0
10481 && (BEG_UNCHANGED < start || GPT <= start))
10482 unchanged_p = 0;
10483
10484 /* If there are overlays at the start or end of the line, these
10485 may have overlay strings with newlines in them. A change at
10486 START, for instance, may actually concern the display of such
10487 overlay strings as well, and they are displayed on different
10488 lines. So, quickly rule out this case. (For the future, it
10489 might be desirable to implement something more telling than
10490 just BEG/END_UNCHANGED.) */
10491 if (unchanged_p)
10492 {
10493 if (BEG + BEG_UNCHANGED == start
10494 && overlay_touches_p (start))
10495 unchanged_p = 0;
10496 if (END_UNCHANGED == end
10497 && overlay_touches_p (Z - end))
10498 unchanged_p = 0;
10499 }
10500 }
10501
10502 return unchanged_p;
10503 }
10504
10505
10506 /* Do a frame update, taking possible shortcuts into account. This is
10507 the main external entry point for redisplay.
10508
10509 If the last redisplay displayed an echo area message and that message
10510 is no longer requested, we clear the echo area or bring back the
10511 mini-buffer if that is in use. */
10512
10513 void
10514 redisplay ()
10515 {
10516 redisplay_internal (0);
10517 }
10518
10519
10520 static Lisp_Object
10521 overlay_arrow_string_or_property (var)
10522 Lisp_Object var;
10523 {
10524 Lisp_Object val;
10525
10526 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
10527 return val;
10528
10529 return Voverlay_arrow_string;
10530 }
10531
10532 /* Return 1 if there are any overlay-arrows in current_buffer. */
10533 static int
10534 overlay_arrow_in_current_buffer_p ()
10535 {
10536 Lisp_Object vlist;
10537
10538 for (vlist = Voverlay_arrow_variable_list;
10539 CONSP (vlist);
10540 vlist = XCDR (vlist))
10541 {
10542 Lisp_Object var = XCAR (vlist);
10543 Lisp_Object val;
10544
10545 if (!SYMBOLP (var))
10546 continue;
10547 val = find_symbol_value (var);
10548 if (MARKERP (val)
10549 && current_buffer == XMARKER (val)->buffer)
10550 return 1;
10551 }
10552 return 0;
10553 }
10554
10555
10556 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
10557 has changed. */
10558
10559 static int
10560 overlay_arrows_changed_p ()
10561 {
10562 Lisp_Object vlist;
10563
10564 for (vlist = Voverlay_arrow_variable_list;
10565 CONSP (vlist);
10566 vlist = XCDR (vlist))
10567 {
10568 Lisp_Object var = XCAR (vlist);
10569 Lisp_Object val, pstr;
10570
10571 if (!SYMBOLP (var))
10572 continue;
10573 val = find_symbol_value (var);
10574 if (!MARKERP (val))
10575 continue;
10576 if (! EQ (COERCE_MARKER (val),
10577 Fget (var, Qlast_arrow_position))
10578 || ! (pstr = overlay_arrow_string_or_property (var),
10579 EQ (pstr, Fget (var, Qlast_arrow_string))))
10580 return 1;
10581 }
10582 return 0;
10583 }
10584
10585 /* Mark overlay arrows to be updated on next redisplay. */
10586
10587 static void
10588 update_overlay_arrows (up_to_date)
10589 int up_to_date;
10590 {
10591 Lisp_Object vlist;
10592
10593 for (vlist = Voverlay_arrow_variable_list;
10594 CONSP (vlist);
10595 vlist = XCDR (vlist))
10596 {
10597 Lisp_Object var = XCAR (vlist);
10598
10599 if (!SYMBOLP (var))
10600 continue;
10601
10602 if (up_to_date > 0)
10603 {
10604 Lisp_Object val = find_symbol_value (var);
10605 Fput (var, Qlast_arrow_position,
10606 COERCE_MARKER (val));
10607 Fput (var, Qlast_arrow_string,
10608 overlay_arrow_string_or_property (var));
10609 }
10610 else if (up_to_date < 0
10611 || !NILP (Fget (var, Qlast_arrow_position)))
10612 {
10613 Fput (var, Qlast_arrow_position, Qt);
10614 Fput (var, Qlast_arrow_string, Qt);
10615 }
10616 }
10617 }
10618
10619
10620 /* Return overlay arrow string to display at row.
10621 Return integer (bitmap number) for arrow bitmap in left fringe.
10622 Return nil if no overlay arrow. */
10623
10624 static Lisp_Object
10625 overlay_arrow_at_row (it, row)
10626 struct it *it;
10627 struct glyph_row *row;
10628 {
10629 Lisp_Object vlist;
10630
10631 for (vlist = Voverlay_arrow_variable_list;
10632 CONSP (vlist);
10633 vlist = XCDR (vlist))
10634 {
10635 Lisp_Object var = XCAR (vlist);
10636 Lisp_Object val;
10637
10638 if (!SYMBOLP (var))
10639 continue;
10640
10641 val = find_symbol_value (var);
10642
10643 if (MARKERP (val)
10644 && current_buffer == XMARKER (val)->buffer
10645 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
10646 {
10647 if (FRAME_WINDOW_P (it->f)
10648 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
10649 {
10650 #ifdef HAVE_WINDOW_SYSTEM
10651 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
10652 {
10653 int fringe_bitmap;
10654 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
10655 return make_number (fringe_bitmap);
10656 }
10657 #endif
10658 return make_number (-1); /* Use default arrow bitmap */
10659 }
10660 return overlay_arrow_string_or_property (var);
10661 }
10662 }
10663
10664 return Qnil;
10665 }
10666
10667 /* Return 1 if point moved out of or into a composition. Otherwise
10668 return 0. PREV_BUF and PREV_PT are the last point buffer and
10669 position. BUF and PT are the current point buffer and position. */
10670
10671 int
10672 check_point_in_composition (prev_buf, prev_pt, buf, pt)
10673 struct buffer *prev_buf, *buf;
10674 int prev_pt, pt;
10675 {
10676 int start, end;
10677 Lisp_Object prop;
10678 Lisp_Object buffer;
10679
10680 XSETBUFFER (buffer, buf);
10681 /* Check a composition at the last point if point moved within the
10682 same buffer. */
10683 if (prev_buf == buf)
10684 {
10685 if (prev_pt == pt)
10686 /* Point didn't move. */
10687 return 0;
10688
10689 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
10690 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
10691 && COMPOSITION_VALID_P (start, end, prop)
10692 && start < prev_pt && end > prev_pt)
10693 /* The last point was within the composition. Return 1 iff
10694 point moved out of the composition. */
10695 return (pt <= start || pt >= end);
10696 }
10697
10698 /* Check a composition at the current point. */
10699 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
10700 && find_composition (pt, -1, &start, &end, &prop, buffer)
10701 && COMPOSITION_VALID_P (start, end, prop)
10702 && start < pt && end > pt);
10703 }
10704
10705
10706 /* Reconsider the setting of B->clip_changed which is displayed
10707 in window W. */
10708
10709 static INLINE void
10710 reconsider_clip_changes (w, b)
10711 struct window *w;
10712 struct buffer *b;
10713 {
10714 if (b->clip_changed
10715 && !NILP (w->window_end_valid)
10716 && w->current_matrix->buffer == b
10717 && w->current_matrix->zv == BUF_ZV (b)
10718 && w->current_matrix->begv == BUF_BEGV (b))
10719 b->clip_changed = 0;
10720
10721 /* If display wasn't paused, and W is not a tool bar window, see if
10722 point has been moved into or out of a composition. In that case,
10723 we set b->clip_changed to 1 to force updating the screen. If
10724 b->clip_changed has already been set to 1, we can skip this
10725 check. */
10726 if (!b->clip_changed
10727 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
10728 {
10729 int pt;
10730
10731 if (w == XWINDOW (selected_window))
10732 pt = BUF_PT (current_buffer);
10733 else
10734 pt = marker_position (w->pointm);
10735
10736 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
10737 || pt != XINT (w->last_point))
10738 && check_point_in_composition (w->current_matrix->buffer,
10739 XINT (w->last_point),
10740 XBUFFER (w->buffer), pt))
10741 b->clip_changed = 1;
10742 }
10743 }
10744 \f
10745
10746 /* Select FRAME to forward the values of frame-local variables into C
10747 variables so that the redisplay routines can access those values
10748 directly. */
10749
10750 static void
10751 select_frame_for_redisplay (frame)
10752 Lisp_Object frame;
10753 {
10754 Lisp_Object tail, sym, val;
10755 Lisp_Object old = selected_frame;
10756
10757 selected_frame = frame;
10758
10759 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
10760 if (CONSP (XCAR (tail))
10761 && (sym = XCAR (XCAR (tail)),
10762 SYMBOLP (sym))
10763 && (sym = indirect_variable (sym),
10764 val = SYMBOL_VALUE (sym),
10765 (BUFFER_LOCAL_VALUEP (val)
10766 || SOME_BUFFER_LOCAL_VALUEP (val)))
10767 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10768 /* Use find_symbol_value rather than Fsymbol_value
10769 to avoid an error if it is void. */
10770 find_symbol_value (sym);
10771
10772 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
10773 if (CONSP (XCAR (tail))
10774 && (sym = XCAR (XCAR (tail)),
10775 SYMBOLP (sym))
10776 && (sym = indirect_variable (sym),
10777 val = SYMBOL_VALUE (sym),
10778 (BUFFER_LOCAL_VALUEP (val)
10779 || SOME_BUFFER_LOCAL_VALUEP (val)))
10780 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10781 find_symbol_value (sym);
10782 }
10783
10784
10785 #define STOP_POLLING \
10786 do { if (! polling_stopped_here) stop_polling (); \
10787 polling_stopped_here = 1; } while (0)
10788
10789 #define RESUME_POLLING \
10790 do { if (polling_stopped_here) start_polling (); \
10791 polling_stopped_here = 0; } while (0)
10792
10793
10794 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
10795 response to any user action; therefore, we should preserve the echo
10796 area. (Actually, our caller does that job.) Perhaps in the future
10797 avoid recentering windows if it is not necessary; currently that
10798 causes some problems. */
10799
10800 static void
10801 redisplay_internal (preserve_echo_area)
10802 int preserve_echo_area;
10803 {
10804 struct window *w = XWINDOW (selected_window);
10805 struct frame *f;
10806 int pause;
10807 int must_finish = 0;
10808 struct text_pos tlbufpos, tlendpos;
10809 int number_of_visible_frames;
10810 int count;
10811 struct frame *sf;
10812 int polling_stopped_here = 0;
10813
10814 /* Non-zero means redisplay has to consider all windows on all
10815 frames. Zero means, only selected_window is considered. */
10816 int consider_all_windows_p;
10817
10818 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
10819
10820 /* No redisplay if running in batch mode or frame is not yet fully
10821 initialized, or redisplay is explicitly turned off by setting
10822 Vinhibit_redisplay. */
10823 if (noninteractive
10824 || !NILP (Vinhibit_redisplay))
10825 return;
10826
10827 /* Don't examine these until after testing Vinhibit_redisplay.
10828 When Emacs is shutting down, perhaps because its connection to
10829 X has dropped, we should not look at them at all. */
10830 f = XFRAME (w->frame);
10831 sf = SELECTED_FRAME ();
10832
10833 if (!f->glyphs_initialized_p)
10834 return;
10835
10836 /* The flag redisplay_performed_directly_p is set by
10837 direct_output_for_insert when it already did the whole screen
10838 update necessary. */
10839 if (redisplay_performed_directly_p)
10840 {
10841 redisplay_performed_directly_p = 0;
10842 if (!hscroll_windows (selected_window))
10843 return;
10844 }
10845
10846 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
10847 if (popup_activated ())
10848 return;
10849 #endif
10850
10851 /* I don't think this happens but let's be paranoid. */
10852 if (redisplaying_p)
10853 return;
10854
10855 /* Record a function that resets redisplaying_p to its old value
10856 when we leave this function. */
10857 count = SPECPDL_INDEX ();
10858 record_unwind_protect (unwind_redisplay,
10859 Fcons (make_number (redisplaying_p), selected_frame));
10860 ++redisplaying_p;
10861 specbind (Qinhibit_free_realized_faces, Qnil);
10862
10863 {
10864 Lisp_Object tail, frame;
10865
10866 FOR_EACH_FRAME (tail, frame)
10867 {
10868 struct frame *f = XFRAME (frame);
10869 f->already_hscrolled_p = 0;
10870 }
10871 }
10872
10873 retry:
10874 pause = 0;
10875 reconsider_clip_changes (w, current_buffer);
10876 last_escape_glyph_frame = NULL;
10877 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
10878
10879 /* If new fonts have been loaded that make a glyph matrix adjustment
10880 necessary, do it. */
10881 if (fonts_changed_p)
10882 {
10883 adjust_glyphs (NULL);
10884 ++windows_or_buffers_changed;
10885 fonts_changed_p = 0;
10886 }
10887
10888 /* If face_change_count is non-zero, init_iterator will free all
10889 realized faces, which includes the faces referenced from current
10890 matrices. So, we can't reuse current matrices in this case. */
10891 if (face_change_count)
10892 ++windows_or_buffers_changed;
10893
10894 if (! FRAME_WINDOW_P (sf)
10895 && previous_terminal_frame != sf)
10896 {
10897 /* Since frames on an ASCII terminal share the same display
10898 area, displaying a different frame means redisplay the whole
10899 thing. */
10900 windows_or_buffers_changed++;
10901 SET_FRAME_GARBAGED (sf);
10902 XSETFRAME (Vterminal_frame, sf);
10903 }
10904 previous_terminal_frame = sf;
10905
10906 /* Set the visible flags for all frames. Do this before checking
10907 for resized or garbaged frames; they want to know if their frames
10908 are visible. See the comment in frame.h for
10909 FRAME_SAMPLE_VISIBILITY. */
10910 {
10911 Lisp_Object tail, frame;
10912
10913 number_of_visible_frames = 0;
10914
10915 FOR_EACH_FRAME (tail, frame)
10916 {
10917 struct frame *f = XFRAME (frame);
10918
10919 FRAME_SAMPLE_VISIBILITY (f);
10920 if (FRAME_VISIBLE_P (f))
10921 ++number_of_visible_frames;
10922 clear_desired_matrices (f);
10923 }
10924 }
10925
10926 /* Notice any pending interrupt request to change frame size. */
10927 do_pending_window_change (1);
10928
10929 /* Clear frames marked as garbaged. */
10930 if (frame_garbaged)
10931 clear_garbaged_frames ();
10932
10933 /* Build menubar and tool-bar items. */
10934 if (NILP (Vmemory_full))
10935 prepare_menu_bars ();
10936
10937 if (windows_or_buffers_changed)
10938 update_mode_lines++;
10939
10940 /* Detect case that we need to write or remove a star in the mode line. */
10941 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
10942 {
10943 w->update_mode_line = Qt;
10944 if (buffer_shared > 1)
10945 update_mode_lines++;
10946 }
10947
10948 /* If %c is in the mode line, update it if needed. */
10949 if (!NILP (w->column_number_displayed)
10950 /* This alternative quickly identifies a common case
10951 where no change is needed. */
10952 && !(PT == XFASTINT (w->last_point)
10953 && XFASTINT (w->last_modified) >= MODIFF
10954 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
10955 && (XFASTINT (w->column_number_displayed)
10956 != (int) current_column ())) /* iftc */
10957 w->update_mode_line = Qt;
10958
10959 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
10960
10961 /* The variable buffer_shared is set in redisplay_window and
10962 indicates that we redisplay a buffer in different windows. See
10963 there. */
10964 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
10965 || cursor_type_changed);
10966
10967 /* If specs for an arrow have changed, do thorough redisplay
10968 to ensure we remove any arrow that should no longer exist. */
10969 if (overlay_arrows_changed_p ())
10970 consider_all_windows_p = windows_or_buffers_changed = 1;
10971
10972 /* Normally the message* functions will have already displayed and
10973 updated the echo area, but the frame may have been trashed, or
10974 the update may have been preempted, so display the echo area
10975 again here. Checking message_cleared_p captures the case that
10976 the echo area should be cleared. */
10977 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
10978 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
10979 || (message_cleared_p
10980 && minibuf_level == 0
10981 /* If the mini-window is currently selected, this means the
10982 echo-area doesn't show through. */
10983 && !MINI_WINDOW_P (XWINDOW (selected_window))))
10984 {
10985 int window_height_changed_p = echo_area_display (0);
10986 must_finish = 1;
10987
10988 /* If we don't display the current message, don't clear the
10989 message_cleared_p flag, because, if we did, we wouldn't clear
10990 the echo area in the next redisplay which doesn't preserve
10991 the echo area. */
10992 if (!display_last_displayed_message_p)
10993 message_cleared_p = 0;
10994
10995 if (fonts_changed_p)
10996 goto retry;
10997 else if (window_height_changed_p)
10998 {
10999 consider_all_windows_p = 1;
11000 ++update_mode_lines;
11001 ++windows_or_buffers_changed;
11002
11003 /* If window configuration was changed, frames may have been
11004 marked garbaged. Clear them or we will experience
11005 surprises wrt scrolling. */
11006 if (frame_garbaged)
11007 clear_garbaged_frames ();
11008 }
11009 }
11010 else if (EQ (selected_window, minibuf_window)
11011 && (current_buffer->clip_changed
11012 || XFASTINT (w->last_modified) < MODIFF
11013 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11014 && resize_mini_window (w, 0))
11015 {
11016 /* Resized active mini-window to fit the size of what it is
11017 showing if its contents might have changed. */
11018 must_finish = 1;
11019 consider_all_windows_p = 1;
11020 ++windows_or_buffers_changed;
11021 ++update_mode_lines;
11022
11023 /* If window configuration was changed, frames may have been
11024 marked garbaged. Clear them or we will experience
11025 surprises wrt scrolling. */
11026 if (frame_garbaged)
11027 clear_garbaged_frames ();
11028 }
11029
11030
11031 /* If showing the region, and mark has changed, we must redisplay
11032 the whole window. The assignment to this_line_start_pos prevents
11033 the optimization directly below this if-statement. */
11034 if (((!NILP (Vtransient_mark_mode)
11035 && !NILP (XBUFFER (w->buffer)->mark_active))
11036 != !NILP (w->region_showing))
11037 || (!NILP (w->region_showing)
11038 && !EQ (w->region_showing,
11039 Fmarker_position (XBUFFER (w->buffer)->mark))))
11040 CHARPOS (this_line_start_pos) = 0;
11041
11042 /* Optimize the case that only the line containing the cursor in the
11043 selected window has changed. Variables starting with this_ are
11044 set in display_line and record information about the line
11045 containing the cursor. */
11046 tlbufpos = this_line_start_pos;
11047 tlendpos = this_line_end_pos;
11048 if (!consider_all_windows_p
11049 && CHARPOS (tlbufpos) > 0
11050 && NILP (w->update_mode_line)
11051 && !current_buffer->clip_changed
11052 && !current_buffer->prevent_redisplay_optimizations_p
11053 && FRAME_VISIBLE_P (XFRAME (w->frame))
11054 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11055 /* Make sure recorded data applies to current buffer, etc. */
11056 && this_line_buffer == current_buffer
11057 && current_buffer == XBUFFER (w->buffer)
11058 && NILP (w->force_start)
11059 && NILP (w->optional_new_start)
11060 /* Point must be on the line that we have info recorded about. */
11061 && PT >= CHARPOS (tlbufpos)
11062 && PT <= Z - CHARPOS (tlendpos)
11063 /* All text outside that line, including its final newline,
11064 must be unchanged */
11065 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11066 CHARPOS (tlendpos)))
11067 {
11068 if (CHARPOS (tlbufpos) > BEGV
11069 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11070 && (CHARPOS (tlbufpos) == ZV
11071 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11072 /* Former continuation line has disappeared by becoming empty */
11073 goto cancel;
11074 else if (XFASTINT (w->last_modified) < MODIFF
11075 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11076 || MINI_WINDOW_P (w))
11077 {
11078 /* We have to handle the case of continuation around a
11079 wide-column character (See the comment in indent.c around
11080 line 885).
11081
11082 For instance, in the following case:
11083
11084 -------- Insert --------
11085 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11086 J_I_ ==> J_I_ `^^' are cursors.
11087 ^^ ^^
11088 -------- --------
11089
11090 As we have to redraw the line above, we should goto cancel. */
11091
11092 struct it it;
11093 int line_height_before = this_line_pixel_height;
11094
11095 /* Note that start_display will handle the case that the
11096 line starting at tlbufpos is a continuation lines. */
11097 start_display (&it, w, tlbufpos);
11098
11099 /* Implementation note: It this still necessary? */
11100 if (it.current_x != this_line_start_x)
11101 goto cancel;
11102
11103 TRACE ((stderr, "trying display optimization 1\n"));
11104 w->cursor.vpos = -1;
11105 overlay_arrow_seen = 0;
11106 it.vpos = this_line_vpos;
11107 it.current_y = this_line_y;
11108 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11109 display_line (&it);
11110
11111 /* If line contains point, is not continued,
11112 and ends at same distance from eob as before, we win */
11113 if (w->cursor.vpos >= 0
11114 /* Line is not continued, otherwise this_line_start_pos
11115 would have been set to 0 in display_line. */
11116 && CHARPOS (this_line_start_pos)
11117 /* Line ends as before. */
11118 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11119 /* Line has same height as before. Otherwise other lines
11120 would have to be shifted up or down. */
11121 && this_line_pixel_height == line_height_before)
11122 {
11123 /* If this is not the window's last line, we must adjust
11124 the charstarts of the lines below. */
11125 if (it.current_y < it.last_visible_y)
11126 {
11127 struct glyph_row *row
11128 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11129 int delta, delta_bytes;
11130
11131 if (Z - CHARPOS (tlendpos) == ZV)
11132 {
11133 /* This line ends at end of (accessible part of)
11134 buffer. There is no newline to count. */
11135 delta = (Z
11136 - CHARPOS (tlendpos)
11137 - MATRIX_ROW_START_CHARPOS (row));
11138 delta_bytes = (Z_BYTE
11139 - BYTEPOS (tlendpos)
11140 - MATRIX_ROW_START_BYTEPOS (row));
11141 }
11142 else
11143 {
11144 /* This line ends in a newline. Must take
11145 account of the newline and the rest of the
11146 text that follows. */
11147 delta = (Z
11148 - CHARPOS (tlendpos)
11149 - MATRIX_ROW_START_CHARPOS (row));
11150 delta_bytes = (Z_BYTE
11151 - BYTEPOS (tlendpos)
11152 - MATRIX_ROW_START_BYTEPOS (row));
11153 }
11154
11155 increment_matrix_positions (w->current_matrix,
11156 this_line_vpos + 1,
11157 w->current_matrix->nrows,
11158 delta, delta_bytes);
11159 }
11160
11161 /* If this row displays text now but previously didn't,
11162 or vice versa, w->window_end_vpos may have to be
11163 adjusted. */
11164 if ((it.glyph_row - 1)->displays_text_p)
11165 {
11166 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11167 XSETINT (w->window_end_vpos, this_line_vpos);
11168 }
11169 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11170 && this_line_vpos > 0)
11171 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11172 w->window_end_valid = Qnil;
11173
11174 /* Update hint: No need to try to scroll in update_window. */
11175 w->desired_matrix->no_scrolling_p = 1;
11176
11177 #if GLYPH_DEBUG
11178 *w->desired_matrix->method = 0;
11179 debug_method_add (w, "optimization 1");
11180 #endif
11181 #ifdef HAVE_WINDOW_SYSTEM
11182 update_window_fringes (w, 0);
11183 #endif
11184 goto update;
11185 }
11186 else
11187 goto cancel;
11188 }
11189 else if (/* Cursor position hasn't changed. */
11190 PT == XFASTINT (w->last_point)
11191 /* Make sure the cursor was last displayed
11192 in this window. Otherwise we have to reposition it. */
11193 && 0 <= w->cursor.vpos
11194 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11195 {
11196 if (!must_finish)
11197 {
11198 do_pending_window_change (1);
11199
11200 /* We used to always goto end_of_redisplay here, but this
11201 isn't enough if we have a blinking cursor. */
11202 if (w->cursor_off_p == w->last_cursor_off_p)
11203 goto end_of_redisplay;
11204 }
11205 goto update;
11206 }
11207 /* If highlighting the region, or if the cursor is in the echo area,
11208 then we can't just move the cursor. */
11209 else if (! (!NILP (Vtransient_mark_mode)
11210 && !NILP (current_buffer->mark_active))
11211 && (EQ (selected_window, current_buffer->last_selected_window)
11212 || highlight_nonselected_windows)
11213 && NILP (w->region_showing)
11214 && NILP (Vshow_trailing_whitespace)
11215 && !cursor_in_echo_area)
11216 {
11217 struct it it;
11218 struct glyph_row *row;
11219
11220 /* Skip from tlbufpos to PT and see where it is. Note that
11221 PT may be in invisible text. If so, we will end at the
11222 next visible position. */
11223 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11224 NULL, DEFAULT_FACE_ID);
11225 it.current_x = this_line_start_x;
11226 it.current_y = this_line_y;
11227 it.vpos = this_line_vpos;
11228
11229 /* The call to move_it_to stops in front of PT, but
11230 moves over before-strings. */
11231 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11232
11233 if (it.vpos == this_line_vpos
11234 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11235 row->enabled_p))
11236 {
11237 xassert (this_line_vpos == it.vpos);
11238 xassert (this_line_y == it.current_y);
11239 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11240 #if GLYPH_DEBUG
11241 *w->desired_matrix->method = 0;
11242 debug_method_add (w, "optimization 3");
11243 #endif
11244 goto update;
11245 }
11246 else
11247 goto cancel;
11248 }
11249
11250 cancel:
11251 /* Text changed drastically or point moved off of line. */
11252 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11253 }
11254
11255 CHARPOS (this_line_start_pos) = 0;
11256 consider_all_windows_p |= buffer_shared > 1;
11257 ++clear_face_cache_count;
11258 #ifdef HAVE_WINDOW_SYSTEM
11259 ++clear_image_cache_count;
11260 #endif
11261
11262 /* Build desired matrices, and update the display. If
11263 consider_all_windows_p is non-zero, do it for all windows on all
11264 frames. Otherwise do it for selected_window, only. */
11265
11266 if (consider_all_windows_p)
11267 {
11268 Lisp_Object tail, frame;
11269
11270 FOR_EACH_FRAME (tail, frame)
11271 XFRAME (frame)->updated_p = 0;
11272
11273 /* Recompute # windows showing selected buffer. This will be
11274 incremented each time such a window is displayed. */
11275 buffer_shared = 0;
11276
11277 FOR_EACH_FRAME (tail, frame)
11278 {
11279 struct frame *f = XFRAME (frame);
11280
11281 if (FRAME_WINDOW_P (f) || f == sf)
11282 {
11283 if (! EQ (frame, selected_frame))
11284 /* Select the frame, for the sake of frame-local
11285 variables. */
11286 select_frame_for_redisplay (frame);
11287
11288 /* Mark all the scroll bars to be removed; we'll redeem
11289 the ones we want when we redisplay their windows. */
11290 if (condemn_scroll_bars_hook)
11291 condemn_scroll_bars_hook (f);
11292
11293 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11294 redisplay_windows (FRAME_ROOT_WINDOW (f));
11295
11296 /* Any scroll bars which redisplay_windows should have
11297 nuked should now go away. */
11298 if (judge_scroll_bars_hook)
11299 judge_scroll_bars_hook (f);
11300
11301 /* If fonts changed, display again. */
11302 /* ??? rms: I suspect it is a mistake to jump all the way
11303 back to retry here. It should just retry this frame. */
11304 if (fonts_changed_p)
11305 goto retry;
11306
11307 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11308 {
11309 /* See if we have to hscroll. */
11310 if (!f->already_hscrolled_p)
11311 {
11312 f->already_hscrolled_p = 1;
11313 if (hscroll_windows (f->root_window))
11314 goto retry;
11315 }
11316
11317 /* Prevent various kinds of signals during display
11318 update. stdio is not robust about handling
11319 signals, which can cause an apparent I/O
11320 error. */
11321 if (interrupt_input)
11322 unrequest_sigio ();
11323 STOP_POLLING;
11324
11325 /* Update the display. */
11326 set_window_update_flags (XWINDOW (f->root_window), 1);
11327 pause |= update_frame (f, 0, 0);
11328 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
11329 if (pause)
11330 break;
11331 #endif
11332
11333 f->updated_p = 1;
11334 }
11335 }
11336 }
11337
11338 if (!pause)
11339 {
11340 /* Do the mark_window_display_accurate after all windows have
11341 been redisplayed because this call resets flags in buffers
11342 which are needed for proper redisplay. */
11343 FOR_EACH_FRAME (tail, frame)
11344 {
11345 struct frame *f = XFRAME (frame);
11346 if (f->updated_p)
11347 {
11348 mark_window_display_accurate (f->root_window, 1);
11349 if (frame_up_to_date_hook)
11350 frame_up_to_date_hook (f);
11351 }
11352 }
11353 }
11354 }
11355 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11356 {
11357 Lisp_Object mini_window;
11358 struct frame *mini_frame;
11359
11360 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
11361 /* Use list_of_error, not Qerror, so that
11362 we catch only errors and don't run the debugger. */
11363 internal_condition_case_1 (redisplay_window_1, selected_window,
11364 list_of_error,
11365 redisplay_window_error);
11366
11367 /* Compare desired and current matrices, perform output. */
11368
11369 update:
11370 /* If fonts changed, display again. */
11371 if (fonts_changed_p)
11372 goto retry;
11373
11374 /* Prevent various kinds of signals during display update.
11375 stdio is not robust about handling signals,
11376 which can cause an apparent I/O error. */
11377 if (interrupt_input)
11378 unrequest_sigio ();
11379 STOP_POLLING;
11380
11381 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11382 {
11383 if (hscroll_windows (selected_window))
11384 goto retry;
11385
11386 XWINDOW (selected_window)->must_be_updated_p = 1;
11387 pause = update_frame (sf, 0, 0);
11388 }
11389
11390 /* We may have called echo_area_display at the top of this
11391 function. If the echo area is on another frame, that may
11392 have put text on a frame other than the selected one, so the
11393 above call to update_frame would not have caught it. Catch
11394 it here. */
11395 mini_window = FRAME_MINIBUF_WINDOW (sf);
11396 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
11397
11398 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
11399 {
11400 XWINDOW (mini_window)->must_be_updated_p = 1;
11401 pause |= update_frame (mini_frame, 0, 0);
11402 if (!pause && hscroll_windows (mini_window))
11403 goto retry;
11404 }
11405 }
11406
11407 /* If display was paused because of pending input, make sure we do a
11408 thorough update the next time. */
11409 if (pause)
11410 {
11411 /* Prevent the optimization at the beginning of
11412 redisplay_internal that tries a single-line update of the
11413 line containing the cursor in the selected window. */
11414 CHARPOS (this_line_start_pos) = 0;
11415
11416 /* Let the overlay arrow be updated the next time. */
11417 update_overlay_arrows (0);
11418
11419 /* If we pause after scrolling, some rows in the current
11420 matrices of some windows are not valid. */
11421 if (!WINDOW_FULL_WIDTH_P (w)
11422 && !FRAME_WINDOW_P (XFRAME (w->frame)))
11423 update_mode_lines = 1;
11424 }
11425 else
11426 {
11427 if (!consider_all_windows_p)
11428 {
11429 /* This has already been done above if
11430 consider_all_windows_p is set. */
11431 mark_window_display_accurate_1 (w, 1);
11432
11433 /* Say overlay arrows are up to date. */
11434 update_overlay_arrows (1);
11435
11436 if (frame_up_to_date_hook != 0)
11437 frame_up_to_date_hook (sf);
11438 }
11439
11440 update_mode_lines = 0;
11441 windows_or_buffers_changed = 0;
11442 cursor_type_changed = 0;
11443 }
11444
11445 /* Start SIGIO interrupts coming again. Having them off during the
11446 code above makes it less likely one will discard output, but not
11447 impossible, since there might be stuff in the system buffer here.
11448 But it is much hairier to try to do anything about that. */
11449 if (interrupt_input)
11450 request_sigio ();
11451 RESUME_POLLING;
11452
11453 /* If a frame has become visible which was not before, redisplay
11454 again, so that we display it. Expose events for such a frame
11455 (which it gets when becoming visible) don't call the parts of
11456 redisplay constructing glyphs, so simply exposing a frame won't
11457 display anything in this case. So, we have to display these
11458 frames here explicitly. */
11459 if (!pause)
11460 {
11461 Lisp_Object tail, frame;
11462 int new_count = 0;
11463
11464 FOR_EACH_FRAME (tail, frame)
11465 {
11466 int this_is_visible = 0;
11467
11468 if (XFRAME (frame)->visible)
11469 this_is_visible = 1;
11470 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
11471 if (XFRAME (frame)->visible)
11472 this_is_visible = 1;
11473
11474 if (this_is_visible)
11475 new_count++;
11476 }
11477
11478 if (new_count != number_of_visible_frames)
11479 windows_or_buffers_changed++;
11480 }
11481
11482 /* Change frame size now if a change is pending. */
11483 do_pending_window_change (1);
11484
11485 /* If we just did a pending size change, or have additional
11486 visible frames, redisplay again. */
11487 if (windows_or_buffers_changed && !pause)
11488 goto retry;
11489
11490 /* Clear the face cache eventually. */
11491 if (consider_all_windows_p)
11492 {
11493 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
11494 {
11495 clear_face_cache (0);
11496 clear_face_cache_count = 0;
11497 }
11498 #ifdef HAVE_WINDOW_SYSTEM
11499 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
11500 {
11501 Lisp_Object tail, frame;
11502 FOR_EACH_FRAME (tail, frame)
11503 {
11504 struct frame *f = XFRAME (frame);
11505 if (FRAME_WINDOW_P (f))
11506 clear_image_cache (f, 0);
11507 }
11508 clear_image_cache_count = 0;
11509 }
11510 #endif /* HAVE_WINDOW_SYSTEM */
11511 }
11512
11513 end_of_redisplay:
11514 unbind_to (count, Qnil);
11515 RESUME_POLLING;
11516 }
11517
11518
11519 /* Redisplay, but leave alone any recent echo area message unless
11520 another message has been requested in its place.
11521
11522 This is useful in situations where you need to redisplay but no
11523 user action has occurred, making it inappropriate for the message
11524 area to be cleared. See tracking_off and
11525 wait_reading_process_output for examples of these situations.
11526
11527 FROM_WHERE is an integer saying from where this function was
11528 called. This is useful for debugging. */
11529
11530 void
11531 redisplay_preserve_echo_area (from_where)
11532 int from_where;
11533 {
11534 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
11535
11536 if (!NILP (echo_area_buffer[1]))
11537 {
11538 /* We have a previously displayed message, but no current
11539 message. Redisplay the previous message. */
11540 display_last_displayed_message_p = 1;
11541 redisplay_internal (1);
11542 display_last_displayed_message_p = 0;
11543 }
11544 else
11545 redisplay_internal (1);
11546
11547 if (rif != NULL && rif->flush_display_optional)
11548 rif->flush_display_optional (NULL);
11549 }
11550
11551
11552 /* Function registered with record_unwind_protect in
11553 redisplay_internal. Reset redisplaying_p to the value it had
11554 before redisplay_internal was called, and clear
11555 prevent_freeing_realized_faces_p. It also selects the previously
11556 selected frame. */
11557
11558 static Lisp_Object
11559 unwind_redisplay (val)
11560 Lisp_Object val;
11561 {
11562 Lisp_Object old_redisplaying_p, old_frame;
11563
11564 old_redisplaying_p = XCAR (val);
11565 redisplaying_p = XFASTINT (old_redisplaying_p);
11566 old_frame = XCDR (val);
11567 if (! EQ (old_frame, selected_frame))
11568 select_frame_for_redisplay (old_frame);
11569 return Qnil;
11570 }
11571
11572
11573 /* Mark the display of window W as accurate or inaccurate. If
11574 ACCURATE_P is non-zero mark display of W as accurate. If
11575 ACCURATE_P is zero, arrange for W to be redisplayed the next time
11576 redisplay_internal is called. */
11577
11578 static void
11579 mark_window_display_accurate_1 (w, accurate_p)
11580 struct window *w;
11581 int accurate_p;
11582 {
11583 if (BUFFERP (w->buffer))
11584 {
11585 struct buffer *b = XBUFFER (w->buffer);
11586
11587 w->last_modified
11588 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
11589 w->last_overlay_modified
11590 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
11591 w->last_had_star
11592 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
11593
11594 if (accurate_p)
11595 {
11596 b->clip_changed = 0;
11597 b->prevent_redisplay_optimizations_p = 0;
11598
11599 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
11600 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
11601 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
11602 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
11603
11604 w->current_matrix->buffer = b;
11605 w->current_matrix->begv = BUF_BEGV (b);
11606 w->current_matrix->zv = BUF_ZV (b);
11607
11608 w->last_cursor = w->cursor;
11609 w->last_cursor_off_p = w->cursor_off_p;
11610
11611 if (w == XWINDOW (selected_window))
11612 w->last_point = make_number (BUF_PT (b));
11613 else
11614 w->last_point = make_number (XMARKER (w->pointm)->charpos);
11615 }
11616 }
11617
11618 if (accurate_p)
11619 {
11620 w->window_end_valid = w->buffer;
11621 #if 0 /* This is incorrect with variable-height lines. */
11622 xassert (XINT (w->window_end_vpos)
11623 < (WINDOW_TOTAL_LINES (w)
11624 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
11625 #endif
11626 w->update_mode_line = Qnil;
11627 }
11628 }
11629
11630
11631 /* Mark the display of windows in the window tree rooted at WINDOW as
11632 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
11633 windows as accurate. If ACCURATE_P is zero, arrange for windows to
11634 be redisplayed the next time redisplay_internal is called. */
11635
11636 void
11637 mark_window_display_accurate (window, accurate_p)
11638 Lisp_Object window;
11639 int accurate_p;
11640 {
11641 struct window *w;
11642
11643 for (; !NILP (window); window = w->next)
11644 {
11645 w = XWINDOW (window);
11646 mark_window_display_accurate_1 (w, accurate_p);
11647
11648 if (!NILP (w->vchild))
11649 mark_window_display_accurate (w->vchild, accurate_p);
11650 if (!NILP (w->hchild))
11651 mark_window_display_accurate (w->hchild, accurate_p);
11652 }
11653
11654 if (accurate_p)
11655 {
11656 update_overlay_arrows (1);
11657 }
11658 else
11659 {
11660 /* Force a thorough redisplay the next time by setting
11661 last_arrow_position and last_arrow_string to t, which is
11662 unequal to any useful value of Voverlay_arrow_... */
11663 update_overlay_arrows (-1);
11664 }
11665 }
11666
11667
11668 /* Return value in display table DP (Lisp_Char_Table *) for character
11669 C. Since a display table doesn't have any parent, we don't have to
11670 follow parent. Do not call this function directly but use the
11671 macro DISP_CHAR_VECTOR. */
11672
11673 Lisp_Object
11674 disp_char_vector (dp, c)
11675 struct Lisp_Char_Table *dp;
11676 int c;
11677 {
11678 int code[4], i;
11679 Lisp_Object val;
11680
11681 if (SINGLE_BYTE_CHAR_P (c))
11682 return (dp->contents[c]);
11683
11684 SPLIT_CHAR (c, code[0], code[1], code[2]);
11685 if (code[1] < 32)
11686 code[1] = -1;
11687 else if (code[2] < 32)
11688 code[2] = -1;
11689
11690 /* Here, the possible range of code[0] (== charset ID) is
11691 128..max_charset. Since the top level char table contains data
11692 for multibyte characters after 256th element, we must increment
11693 code[0] by 128 to get a correct index. */
11694 code[0] += 128;
11695 code[3] = -1; /* anchor */
11696
11697 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
11698 {
11699 val = dp->contents[code[i]];
11700 if (!SUB_CHAR_TABLE_P (val))
11701 return (NILP (val) ? dp->defalt : val);
11702 }
11703
11704 /* Here, val is a sub char table. We return the default value of
11705 it. */
11706 return (dp->defalt);
11707 }
11708
11709
11710 \f
11711 /***********************************************************************
11712 Window Redisplay
11713 ***********************************************************************/
11714
11715 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
11716
11717 static void
11718 redisplay_windows (window)
11719 Lisp_Object window;
11720 {
11721 while (!NILP (window))
11722 {
11723 struct window *w = XWINDOW (window);
11724
11725 if (!NILP (w->hchild))
11726 redisplay_windows (w->hchild);
11727 else if (!NILP (w->vchild))
11728 redisplay_windows (w->vchild);
11729 else
11730 {
11731 displayed_buffer = XBUFFER (w->buffer);
11732 /* Use list_of_error, not Qerror, so that
11733 we catch only errors and don't run the debugger. */
11734 internal_condition_case_1 (redisplay_window_0, window,
11735 list_of_error,
11736 redisplay_window_error);
11737 }
11738
11739 window = w->next;
11740 }
11741 }
11742
11743 static Lisp_Object
11744 redisplay_window_error ()
11745 {
11746 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
11747 return Qnil;
11748 }
11749
11750 static Lisp_Object
11751 redisplay_window_0 (window)
11752 Lisp_Object window;
11753 {
11754 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11755 redisplay_window (window, 0);
11756 return Qnil;
11757 }
11758
11759 static Lisp_Object
11760 redisplay_window_1 (window)
11761 Lisp_Object window;
11762 {
11763 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11764 redisplay_window (window, 1);
11765 return Qnil;
11766 }
11767 \f
11768
11769 /* Increment GLYPH until it reaches END or CONDITION fails while
11770 adding (GLYPH)->pixel_width to X. */
11771
11772 #define SKIP_GLYPHS(glyph, end, x, condition) \
11773 do \
11774 { \
11775 (x) += (glyph)->pixel_width; \
11776 ++(glyph); \
11777 } \
11778 while ((glyph) < (end) && (condition))
11779
11780
11781 /* Set cursor position of W. PT is assumed to be displayed in ROW.
11782 DELTA is the number of bytes by which positions recorded in ROW
11783 differ from current buffer positions.
11784
11785 Return 0 if cursor is not on this row. 1 otherwise. */
11786
11787 int
11788 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
11789 struct window *w;
11790 struct glyph_row *row;
11791 struct glyph_matrix *matrix;
11792 int delta, delta_bytes, dy, dvpos;
11793 {
11794 struct glyph *glyph = row->glyphs[TEXT_AREA];
11795 struct glyph *end = glyph + row->used[TEXT_AREA];
11796 struct glyph *cursor = NULL;
11797 /* The first glyph that starts a sequence of glyphs from string. */
11798 struct glyph *string_start;
11799 /* The X coordinate of string_start. */
11800 int string_start_x;
11801 /* The last known character position. */
11802 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
11803 /* The last known character position before string_start. */
11804 int string_before_pos;
11805 int x = row->x;
11806 int cursor_x = x;
11807 int cursor_from_overlay_pos = 0;
11808 int pt_old = PT - delta;
11809
11810 /* Skip over glyphs not having an object at the start of the row.
11811 These are special glyphs like truncation marks on terminal
11812 frames. */
11813 if (row->displays_text_p)
11814 while (glyph < end
11815 && INTEGERP (glyph->object)
11816 && glyph->charpos < 0)
11817 {
11818 x += glyph->pixel_width;
11819 ++glyph;
11820 }
11821
11822 string_start = NULL;
11823 while (glyph < end
11824 && !INTEGERP (glyph->object)
11825 && (!BUFFERP (glyph->object)
11826 || (last_pos = glyph->charpos) < pt_old))
11827 {
11828 if (! STRINGP (glyph->object))
11829 {
11830 string_start = NULL;
11831 x += glyph->pixel_width;
11832 ++glyph;
11833 if (cursor_from_overlay_pos
11834 && last_pos >= cursor_from_overlay_pos)
11835 {
11836 cursor_from_overlay_pos = 0;
11837 cursor = 0;
11838 }
11839 }
11840 else
11841 {
11842 if (string_start == NULL)
11843 {
11844 string_before_pos = last_pos;
11845 string_start = glyph;
11846 string_start_x = x;
11847 }
11848 /* Skip all glyphs from string. */
11849 do
11850 {
11851 Lisp_Object cprop;
11852 int pos;
11853 if ((cursor == NULL || glyph > cursor)
11854 && (cprop = Fget_char_property (make_number ((glyph)->charpos),
11855 Qcursor, (glyph)->object),
11856 !NILP (cprop))
11857 && (pos = string_buffer_position (w, glyph->object,
11858 string_before_pos),
11859 (pos == 0 /* From overlay */
11860 || pos == pt_old)))
11861 {
11862 /* Estimate overlay buffer position from the buffer
11863 positions of the glyphs before and after the overlay.
11864 Add 1 to last_pos so that if point corresponds to the
11865 glyph right after the overlay, we still use a 'cursor'
11866 property found in that overlay. */
11867 cursor_from_overlay_pos = (pos ? 0 : last_pos
11868 + (INTEGERP (cprop) ? XINT (cprop) : 0));
11869 cursor = glyph;
11870 cursor_x = x;
11871 }
11872 x += glyph->pixel_width;
11873 ++glyph;
11874 }
11875 while (glyph < end && EQ (glyph->object, string_start->object));
11876 }
11877 }
11878
11879 if (cursor != NULL)
11880 {
11881 glyph = cursor;
11882 x = cursor_x;
11883 }
11884 else if (row->ends_in_ellipsis_p && glyph == end)
11885 {
11886 /* Scan back over the ellipsis glyphs, decrementing positions. */
11887 while (glyph > row->glyphs[TEXT_AREA]
11888 && (glyph - 1)->charpos == last_pos)
11889 glyph--, x -= glyph->pixel_width;
11890 /* That loop always goes one position too far,
11891 including the glyph before the ellipsis.
11892 So scan forward over that one. */
11893 x += glyph->pixel_width;
11894 glyph++;
11895 }
11896 else if (string_start
11897 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
11898 {
11899 /* We may have skipped over point because the previous glyphs
11900 are from string. As there's no easy way to know the
11901 character position of the current glyph, find the correct
11902 glyph on point by scanning from string_start again. */
11903 Lisp_Object limit;
11904 Lisp_Object string;
11905 struct glyph *stop = glyph;
11906 int pos;
11907
11908 limit = make_number (pt_old + 1);
11909 glyph = string_start;
11910 x = string_start_x;
11911 string = glyph->object;
11912 pos = string_buffer_position (w, string, string_before_pos);
11913 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11914 because we always put cursor after overlay strings. */
11915 while (pos == 0 && glyph < stop)
11916 {
11917 string = glyph->object;
11918 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
11919 if (glyph < stop)
11920 pos = string_buffer_position (w, glyph->object, string_before_pos);
11921 }
11922
11923 while (glyph < stop)
11924 {
11925 pos = XINT (Fnext_single_char_property_change
11926 (make_number (pos), Qdisplay, Qnil, limit));
11927 if (pos > pt_old)
11928 break;
11929 /* Skip glyphs from the same string. */
11930 string = glyph->object;
11931 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
11932 /* Skip glyphs from an overlay. */
11933 while (glyph < stop
11934 && ! string_buffer_position (w, glyph->object, pos))
11935 {
11936 string = glyph->object;
11937 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
11938 }
11939 }
11940
11941 /* If we reached the end of the line, and end was from a string,
11942 cursor is not on this line. */
11943 if (glyph == end && row->continued_p)
11944 return 0;
11945 }
11946
11947 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
11948 w->cursor.x = x;
11949 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
11950 w->cursor.y = row->y + dy;
11951
11952 if (w == XWINDOW (selected_window))
11953 {
11954 if (!row->continued_p
11955 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
11956 && row->x == 0)
11957 {
11958 this_line_buffer = XBUFFER (w->buffer);
11959
11960 CHARPOS (this_line_start_pos)
11961 = MATRIX_ROW_START_CHARPOS (row) + delta;
11962 BYTEPOS (this_line_start_pos)
11963 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
11964
11965 CHARPOS (this_line_end_pos)
11966 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
11967 BYTEPOS (this_line_end_pos)
11968 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
11969
11970 this_line_y = w->cursor.y;
11971 this_line_pixel_height = row->height;
11972 this_line_vpos = w->cursor.vpos;
11973 this_line_start_x = row->x;
11974 }
11975 else
11976 CHARPOS (this_line_start_pos) = 0;
11977 }
11978
11979 return 1;
11980 }
11981
11982
11983 /* Run window scroll functions, if any, for WINDOW with new window
11984 start STARTP. Sets the window start of WINDOW to that position.
11985
11986 We assume that the window's buffer is really current. */
11987
11988 static INLINE struct text_pos
11989 run_window_scroll_functions (window, startp)
11990 Lisp_Object window;
11991 struct text_pos startp;
11992 {
11993 struct window *w = XWINDOW (window);
11994 SET_MARKER_FROM_TEXT_POS (w->start, startp);
11995
11996 if (current_buffer != XBUFFER (w->buffer))
11997 abort ();
11998
11999 if (!NILP (Vwindow_scroll_functions))
12000 {
12001 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12002 make_number (CHARPOS (startp)));
12003 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12004 /* In case the hook functions switch buffers. */
12005 if (current_buffer != XBUFFER (w->buffer))
12006 set_buffer_internal_1 (XBUFFER (w->buffer));
12007 }
12008
12009 return startp;
12010 }
12011
12012
12013 /* Make sure the line containing the cursor is fully visible.
12014 A value of 1 means there is nothing to be done.
12015 (Either the line is fully visible, or it cannot be made so,
12016 or we cannot tell.)
12017
12018 If FORCE_P is non-zero, return 0 even if partial visible cursor row
12019 is higher than window.
12020
12021 A value of 0 means the caller should do scrolling
12022 as if point had gone off the screen. */
12023
12024 static int
12025 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
12026 struct window *w;
12027 int force_p;
12028 int current_matrix_p;
12029 {
12030 struct glyph_matrix *matrix;
12031 struct glyph_row *row;
12032 int window_height;
12033
12034 if (!make_cursor_line_fully_visible_p)
12035 return 1;
12036
12037 /* It's not always possible to find the cursor, e.g, when a window
12038 is full of overlay strings. Don't do anything in that case. */
12039 if (w->cursor.vpos < 0)
12040 return 1;
12041
12042 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
12043 row = MATRIX_ROW (matrix, w->cursor.vpos);
12044
12045 /* If the cursor row is not partially visible, there's nothing to do. */
12046 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
12047 return 1;
12048
12049 /* If the row the cursor is in is taller than the window's height,
12050 it's not clear what to do, so do nothing. */
12051 window_height = window_box_height (w);
12052 if (row->height >= window_height)
12053 {
12054 if (!force_p || MINI_WINDOW_P (w)
12055 || w->vscroll || w->cursor.vpos == 0)
12056 return 1;
12057 }
12058 return 0;
12059
12060 #if 0
12061 /* This code used to try to scroll the window just enough to make
12062 the line visible. It returned 0 to say that the caller should
12063 allocate larger glyph matrices. */
12064
12065 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
12066 {
12067 int dy = row->height - row->visible_height;
12068 w->vscroll = 0;
12069 w->cursor.y += dy;
12070 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12071 }
12072 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
12073 {
12074 int dy = - (row->height - row->visible_height);
12075 w->vscroll = dy;
12076 w->cursor.y += dy;
12077 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12078 }
12079
12080 /* When we change the cursor y-position of the selected window,
12081 change this_line_y as well so that the display optimization for
12082 the cursor line of the selected window in redisplay_internal uses
12083 the correct y-position. */
12084 if (w == XWINDOW (selected_window))
12085 this_line_y = w->cursor.y;
12086
12087 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
12088 redisplay with larger matrices. */
12089 if (matrix->nrows < required_matrix_height (w))
12090 {
12091 fonts_changed_p = 1;
12092 return 0;
12093 }
12094
12095 return 1;
12096 #endif /* 0 */
12097 }
12098
12099
12100 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
12101 non-zero means only WINDOW is redisplayed in redisplay_internal.
12102 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
12103 in redisplay_window to bring a partially visible line into view in
12104 the case that only the cursor has moved.
12105
12106 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
12107 last screen line's vertical height extends past the end of the screen.
12108
12109 Value is
12110
12111 1 if scrolling succeeded
12112
12113 0 if scrolling didn't find point.
12114
12115 -1 if new fonts have been loaded so that we must interrupt
12116 redisplay, adjust glyph matrices, and try again. */
12117
12118 enum
12119 {
12120 SCROLLING_SUCCESS,
12121 SCROLLING_FAILED,
12122 SCROLLING_NEED_LARGER_MATRICES
12123 };
12124
12125 static int
12126 try_scrolling (window, just_this_one_p, scroll_conservatively,
12127 scroll_step, temp_scroll_step, last_line_misfit)
12128 Lisp_Object window;
12129 int just_this_one_p;
12130 EMACS_INT scroll_conservatively, scroll_step;
12131 int temp_scroll_step;
12132 int last_line_misfit;
12133 {
12134 struct window *w = XWINDOW (window);
12135 struct frame *f = XFRAME (w->frame);
12136 struct text_pos scroll_margin_pos;
12137 struct text_pos pos;
12138 struct text_pos startp;
12139 struct it it;
12140 Lisp_Object window_end;
12141 int this_scroll_margin;
12142 int dy = 0;
12143 int scroll_max;
12144 int rc;
12145 int amount_to_scroll = 0;
12146 Lisp_Object aggressive;
12147 int height;
12148 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
12149
12150 #if GLYPH_DEBUG
12151 debug_method_add (w, "try_scrolling");
12152 #endif
12153
12154 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12155
12156 /* Compute scroll margin height in pixels. We scroll when point is
12157 within this distance from the top or bottom of the window. */
12158 if (scroll_margin > 0)
12159 {
12160 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12161 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12162 }
12163 else
12164 this_scroll_margin = 0;
12165
12166 /* Force scroll_conservatively to have a reasonable value so it doesn't
12167 cause an overflow while computing how much to scroll. */
12168 if (scroll_conservatively)
12169 scroll_conservatively = min (scroll_conservatively,
12170 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
12171
12172 /* Compute how much we should try to scroll maximally to bring point
12173 into view. */
12174 if (scroll_step || scroll_conservatively || temp_scroll_step)
12175 scroll_max = max (scroll_step,
12176 max (scroll_conservatively, temp_scroll_step));
12177 else if (NUMBERP (current_buffer->scroll_down_aggressively)
12178 || NUMBERP (current_buffer->scroll_up_aggressively))
12179 /* We're trying to scroll because of aggressive scrolling
12180 but no scroll_step is set. Choose an arbitrary one. Maybe
12181 there should be a variable for this. */
12182 scroll_max = 10;
12183 else
12184 scroll_max = 0;
12185 scroll_max *= FRAME_LINE_HEIGHT (f);
12186
12187 /* Decide whether we have to scroll down. Start at the window end
12188 and move this_scroll_margin up to find the position of the scroll
12189 margin. */
12190 window_end = Fwindow_end (window, Qt);
12191
12192 too_near_end:
12193
12194 CHARPOS (scroll_margin_pos) = XINT (window_end);
12195 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
12196
12197 if (this_scroll_margin || extra_scroll_margin_lines)
12198 {
12199 start_display (&it, w, scroll_margin_pos);
12200 if (this_scroll_margin)
12201 move_it_vertically_backward (&it, this_scroll_margin);
12202 if (extra_scroll_margin_lines)
12203 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
12204 scroll_margin_pos = it.current.pos;
12205 }
12206
12207 if (PT >= CHARPOS (scroll_margin_pos))
12208 {
12209 int y0;
12210
12211 /* Point is in the scroll margin at the bottom of the window, or
12212 below. Compute a new window start that makes point visible. */
12213
12214 /* Compute the distance from the scroll margin to PT.
12215 Give up if the distance is greater than scroll_max. */
12216 start_display (&it, w, scroll_margin_pos);
12217 y0 = it.current_y;
12218 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12219 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12220
12221 /* To make point visible, we have to move the window start
12222 down so that the line the cursor is in is visible, which
12223 means we have to add in the height of the cursor line. */
12224 dy = line_bottom_y (&it) - y0;
12225
12226 if (dy > scroll_max)
12227 return SCROLLING_FAILED;
12228
12229 /* Move the window start down. If scrolling conservatively,
12230 move it just enough down to make point visible. If
12231 scroll_step is set, move it down by scroll_step. */
12232 start_display (&it, w, startp);
12233
12234 if (scroll_conservatively)
12235 /* Set AMOUNT_TO_SCROLL to at least one line,
12236 and at most scroll_conservatively lines. */
12237 amount_to_scroll
12238 = min (max (dy, FRAME_LINE_HEIGHT (f)),
12239 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
12240 else if (scroll_step || temp_scroll_step)
12241 amount_to_scroll = scroll_max;
12242 else
12243 {
12244 aggressive = current_buffer->scroll_up_aggressively;
12245 height = WINDOW_BOX_TEXT_HEIGHT (w);
12246 if (NUMBERP (aggressive))
12247 {
12248 double float_amount = XFLOATINT (aggressive) * height;
12249 amount_to_scroll = float_amount;
12250 if (amount_to_scroll == 0 && float_amount > 0)
12251 amount_to_scroll = 1;
12252 }
12253 }
12254
12255 if (amount_to_scroll <= 0)
12256 return SCROLLING_FAILED;
12257
12258 /* If moving by amount_to_scroll leaves STARTP unchanged,
12259 move it down one screen line. */
12260
12261 move_it_vertically (&it, amount_to_scroll);
12262 if (CHARPOS (it.current.pos) == CHARPOS (startp))
12263 move_it_by_lines (&it, 1, 1);
12264 startp = it.current.pos;
12265 }
12266 else
12267 {
12268 /* See if point is inside the scroll margin at the top of the
12269 window. */
12270 scroll_margin_pos = startp;
12271 if (this_scroll_margin)
12272 {
12273 start_display (&it, w, startp);
12274 move_it_vertically (&it, this_scroll_margin);
12275 scroll_margin_pos = it.current.pos;
12276 }
12277
12278 if (PT < CHARPOS (scroll_margin_pos))
12279 {
12280 /* Point is in the scroll margin at the top of the window or
12281 above what is displayed in the window. */
12282 int y0;
12283
12284 /* Compute the vertical distance from PT to the scroll
12285 margin position. Give up if distance is greater than
12286 scroll_max. */
12287 SET_TEXT_POS (pos, PT, PT_BYTE);
12288 start_display (&it, w, pos);
12289 y0 = it.current_y;
12290 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
12291 it.last_visible_y, -1,
12292 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12293 dy = it.current_y - y0;
12294 if (dy > scroll_max)
12295 return SCROLLING_FAILED;
12296
12297 /* Compute new window start. */
12298 start_display (&it, w, startp);
12299
12300 if (scroll_conservatively)
12301 amount_to_scroll
12302 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
12303 else if (scroll_step || temp_scroll_step)
12304 amount_to_scroll = scroll_max;
12305 else
12306 {
12307 aggressive = current_buffer->scroll_down_aggressively;
12308 height = WINDOW_BOX_TEXT_HEIGHT (w);
12309 if (NUMBERP (aggressive))
12310 {
12311 double float_amount = XFLOATINT (aggressive) * height;
12312 amount_to_scroll = float_amount;
12313 if (amount_to_scroll == 0 && float_amount > 0)
12314 amount_to_scroll = 1;
12315 }
12316 }
12317
12318 if (amount_to_scroll <= 0)
12319 return SCROLLING_FAILED;
12320
12321 move_it_vertically_backward (&it, amount_to_scroll);
12322 startp = it.current.pos;
12323 }
12324 }
12325
12326 /* Run window scroll functions. */
12327 startp = run_window_scroll_functions (window, startp);
12328
12329 /* Display the window. Give up if new fonts are loaded, or if point
12330 doesn't appear. */
12331 if (!try_window (window, startp, 0))
12332 rc = SCROLLING_NEED_LARGER_MATRICES;
12333 else if (w->cursor.vpos < 0)
12334 {
12335 clear_glyph_matrix (w->desired_matrix);
12336 rc = SCROLLING_FAILED;
12337 }
12338 else
12339 {
12340 /* Maybe forget recorded base line for line number display. */
12341 if (!just_this_one_p
12342 || current_buffer->clip_changed
12343 || BEG_UNCHANGED < CHARPOS (startp))
12344 w->base_line_number = Qnil;
12345
12346 /* If cursor ends up on a partially visible line,
12347 treat that as being off the bottom of the screen. */
12348 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
12349 {
12350 clear_glyph_matrix (w->desired_matrix);
12351 ++extra_scroll_margin_lines;
12352 goto too_near_end;
12353 }
12354 rc = SCROLLING_SUCCESS;
12355 }
12356
12357 return rc;
12358 }
12359
12360
12361 /* Compute a suitable window start for window W if display of W starts
12362 on a continuation line. Value is non-zero if a new window start
12363 was computed.
12364
12365 The new window start will be computed, based on W's width, starting
12366 from the start of the continued line. It is the start of the
12367 screen line with the minimum distance from the old start W->start. */
12368
12369 static int
12370 compute_window_start_on_continuation_line (w)
12371 struct window *w;
12372 {
12373 struct text_pos pos, start_pos;
12374 int window_start_changed_p = 0;
12375
12376 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
12377
12378 /* If window start is on a continuation line... Window start may be
12379 < BEGV in case there's invisible text at the start of the
12380 buffer (M-x rmail, for example). */
12381 if (CHARPOS (start_pos) > BEGV
12382 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
12383 {
12384 struct it it;
12385 struct glyph_row *row;
12386
12387 /* Handle the case that the window start is out of range. */
12388 if (CHARPOS (start_pos) < BEGV)
12389 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
12390 else if (CHARPOS (start_pos) > ZV)
12391 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
12392
12393 /* Find the start of the continued line. This should be fast
12394 because scan_buffer is fast (newline cache). */
12395 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
12396 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
12397 row, DEFAULT_FACE_ID);
12398 reseat_at_previous_visible_line_start (&it);
12399
12400 /* If the line start is "too far" away from the window start,
12401 say it takes too much time to compute a new window start. */
12402 if (CHARPOS (start_pos) - IT_CHARPOS (it)
12403 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
12404 {
12405 int min_distance, distance;
12406
12407 /* Move forward by display lines to find the new window
12408 start. If window width was enlarged, the new start can
12409 be expected to be > the old start. If window width was
12410 decreased, the new window start will be < the old start.
12411 So, we're looking for the display line start with the
12412 minimum distance from the old window start. */
12413 pos = it.current.pos;
12414 min_distance = INFINITY;
12415 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
12416 distance < min_distance)
12417 {
12418 min_distance = distance;
12419 pos = it.current.pos;
12420 move_it_by_lines (&it, 1, 0);
12421 }
12422
12423 /* Set the window start there. */
12424 SET_MARKER_FROM_TEXT_POS (w->start, pos);
12425 window_start_changed_p = 1;
12426 }
12427 }
12428
12429 return window_start_changed_p;
12430 }
12431
12432
12433 /* Try cursor movement in case text has not changed in window WINDOW,
12434 with window start STARTP. Value is
12435
12436 CURSOR_MOVEMENT_SUCCESS if successful
12437
12438 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
12439
12440 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
12441 display. *SCROLL_STEP is set to 1, under certain circumstances, if
12442 we want to scroll as if scroll-step were set to 1. See the code.
12443
12444 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
12445 which case we have to abort this redisplay, and adjust matrices
12446 first. */
12447
12448 enum
12449 {
12450 CURSOR_MOVEMENT_SUCCESS,
12451 CURSOR_MOVEMENT_CANNOT_BE_USED,
12452 CURSOR_MOVEMENT_MUST_SCROLL,
12453 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
12454 };
12455
12456 static int
12457 try_cursor_movement (window, startp, scroll_step)
12458 Lisp_Object window;
12459 struct text_pos startp;
12460 int *scroll_step;
12461 {
12462 struct window *w = XWINDOW (window);
12463 struct frame *f = XFRAME (w->frame);
12464 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
12465
12466 #if GLYPH_DEBUG
12467 if (inhibit_try_cursor_movement)
12468 return rc;
12469 #endif
12470
12471 /* Handle case where text has not changed, only point, and it has
12472 not moved off the frame. */
12473 if (/* Point may be in this window. */
12474 PT >= CHARPOS (startp)
12475 /* Selective display hasn't changed. */
12476 && !current_buffer->clip_changed
12477 /* Function force-mode-line-update is used to force a thorough
12478 redisplay. It sets either windows_or_buffers_changed or
12479 update_mode_lines. So don't take a shortcut here for these
12480 cases. */
12481 && !update_mode_lines
12482 && !windows_or_buffers_changed
12483 && !cursor_type_changed
12484 /* Can't use this case if highlighting a region. When a
12485 region exists, cursor movement has to do more than just
12486 set the cursor. */
12487 && !(!NILP (Vtransient_mark_mode)
12488 && !NILP (current_buffer->mark_active))
12489 && NILP (w->region_showing)
12490 && NILP (Vshow_trailing_whitespace)
12491 /* Right after splitting windows, last_point may be nil. */
12492 && INTEGERP (w->last_point)
12493 /* This code is not used for mini-buffer for the sake of the case
12494 of redisplaying to replace an echo area message; since in
12495 that case the mini-buffer contents per se are usually
12496 unchanged. This code is of no real use in the mini-buffer
12497 since the handling of this_line_start_pos, etc., in redisplay
12498 handles the same cases. */
12499 && !EQ (window, minibuf_window)
12500 /* When splitting windows or for new windows, it happens that
12501 redisplay is called with a nil window_end_vpos or one being
12502 larger than the window. This should really be fixed in
12503 window.c. I don't have this on my list, now, so we do
12504 approximately the same as the old redisplay code. --gerd. */
12505 && INTEGERP (w->window_end_vpos)
12506 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
12507 && (FRAME_WINDOW_P (f)
12508 || !overlay_arrow_in_current_buffer_p ()))
12509 {
12510 int this_scroll_margin, top_scroll_margin;
12511 struct glyph_row *row = NULL;
12512
12513 #if GLYPH_DEBUG
12514 debug_method_add (w, "cursor movement");
12515 #endif
12516
12517 /* Scroll if point within this distance from the top or bottom
12518 of the window. This is a pixel value. */
12519 this_scroll_margin = max (0, scroll_margin);
12520 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12521 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12522
12523 top_scroll_margin = this_scroll_margin;
12524 if (WINDOW_WANTS_HEADER_LINE_P (w))
12525 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
12526
12527 /* Start with the row the cursor was displayed during the last
12528 not paused redisplay. Give up if that row is not valid. */
12529 if (w->last_cursor.vpos < 0
12530 || w->last_cursor.vpos >= w->current_matrix->nrows)
12531 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12532 else
12533 {
12534 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
12535 if (row->mode_line_p)
12536 ++row;
12537 if (!row->enabled_p)
12538 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12539 }
12540
12541 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
12542 {
12543 int scroll_p = 0;
12544 int last_y = window_text_bottom_y (w) - this_scroll_margin;
12545
12546 if (PT > XFASTINT (w->last_point))
12547 {
12548 /* Point has moved forward. */
12549 while (MATRIX_ROW_END_CHARPOS (row) < PT
12550 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
12551 {
12552 xassert (row->enabled_p);
12553 ++row;
12554 }
12555
12556 /* The end position of a row equals the start position
12557 of the next row. If PT is there, we would rather
12558 display it in the next line. */
12559 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12560 && MATRIX_ROW_END_CHARPOS (row) == PT
12561 && !cursor_row_p (w, row))
12562 ++row;
12563
12564 /* If within the scroll margin, scroll. Note that
12565 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
12566 the next line would be drawn, and that
12567 this_scroll_margin can be zero. */
12568 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
12569 || PT > MATRIX_ROW_END_CHARPOS (row)
12570 /* Line is completely visible last line in window
12571 and PT is to be set in the next line. */
12572 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
12573 && PT == MATRIX_ROW_END_CHARPOS (row)
12574 && !row->ends_at_zv_p
12575 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12576 scroll_p = 1;
12577 }
12578 else if (PT < XFASTINT (w->last_point))
12579 {
12580 /* Cursor has to be moved backward. Note that PT >=
12581 CHARPOS (startp) because of the outer if-statement. */
12582 while (!row->mode_line_p
12583 && (MATRIX_ROW_START_CHARPOS (row) > PT
12584 || (MATRIX_ROW_START_CHARPOS (row) == PT
12585 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
12586 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
12587 row > w->current_matrix->rows
12588 && (row-1)->ends_in_newline_from_string_p))))
12589 && (row->y > top_scroll_margin
12590 || CHARPOS (startp) == BEGV))
12591 {
12592 xassert (row->enabled_p);
12593 --row;
12594 }
12595
12596 /* Consider the following case: Window starts at BEGV,
12597 there is invisible, intangible text at BEGV, so that
12598 display starts at some point START > BEGV. It can
12599 happen that we are called with PT somewhere between
12600 BEGV and START. Try to handle that case. */
12601 if (row < w->current_matrix->rows
12602 || row->mode_line_p)
12603 {
12604 row = w->current_matrix->rows;
12605 if (row->mode_line_p)
12606 ++row;
12607 }
12608
12609 /* Due to newlines in overlay strings, we may have to
12610 skip forward over overlay strings. */
12611 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12612 && MATRIX_ROW_END_CHARPOS (row) == PT
12613 && !cursor_row_p (w, row))
12614 ++row;
12615
12616 /* If within the scroll margin, scroll. */
12617 if (row->y < top_scroll_margin
12618 && CHARPOS (startp) != BEGV)
12619 scroll_p = 1;
12620 }
12621 else
12622 {
12623 /* Cursor did not move. So don't scroll even if cursor line
12624 is partially visible, as it was so before. */
12625 rc = CURSOR_MOVEMENT_SUCCESS;
12626 }
12627
12628 if (PT < MATRIX_ROW_START_CHARPOS (row)
12629 || PT > MATRIX_ROW_END_CHARPOS (row))
12630 {
12631 /* if PT is not in the glyph row, give up. */
12632 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12633 }
12634 else if (rc != CURSOR_MOVEMENT_SUCCESS
12635 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
12636 && make_cursor_line_fully_visible_p)
12637 {
12638 if (PT == MATRIX_ROW_END_CHARPOS (row)
12639 && !row->ends_at_zv_p
12640 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
12641 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12642 else if (row->height > window_box_height (w))
12643 {
12644 /* If we end up in a partially visible line, let's
12645 make it fully visible, except when it's taller
12646 than the window, in which case we can't do much
12647 about it. */
12648 *scroll_step = 1;
12649 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12650 }
12651 else
12652 {
12653 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12654 if (!cursor_row_fully_visible_p (w, 0, 1))
12655 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12656 else
12657 rc = CURSOR_MOVEMENT_SUCCESS;
12658 }
12659 }
12660 else if (scroll_p)
12661 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12662 else
12663 {
12664 do
12665 {
12666 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
12667 {
12668 rc = CURSOR_MOVEMENT_SUCCESS;
12669 break;
12670 }
12671 ++row;
12672 }
12673 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12674 && MATRIX_ROW_START_CHARPOS (row) == PT
12675 && cursor_row_p (w, row));
12676 }
12677 }
12678 }
12679
12680 return rc;
12681 }
12682
12683 void
12684 set_vertical_scroll_bar (w)
12685 struct window *w;
12686 {
12687 int start, end, whole;
12688
12689 /* Calculate the start and end positions for the current window.
12690 At some point, it would be nice to choose between scrollbars
12691 which reflect the whole buffer size, with special markers
12692 indicating narrowing, and scrollbars which reflect only the
12693 visible region.
12694
12695 Note that mini-buffers sometimes aren't displaying any text. */
12696 if (!MINI_WINDOW_P (w)
12697 || (w == XWINDOW (minibuf_window)
12698 && NILP (echo_area_buffer[0])))
12699 {
12700 struct buffer *buf = XBUFFER (w->buffer);
12701 whole = BUF_ZV (buf) - BUF_BEGV (buf);
12702 start = marker_position (w->start) - BUF_BEGV (buf);
12703 /* I don't think this is guaranteed to be right. For the
12704 moment, we'll pretend it is. */
12705 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
12706
12707 if (end < start)
12708 end = start;
12709 if (whole < (end - start))
12710 whole = end - start;
12711 }
12712 else
12713 start = end = whole = 0;
12714
12715 /* Indicate what this scroll bar ought to be displaying now. */
12716 set_vertical_scroll_bar_hook (w, end - start, whole, start);
12717 }
12718
12719
12720 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
12721 selected_window is redisplayed.
12722
12723 We can return without actually redisplaying the window if
12724 fonts_changed_p is nonzero. In that case, redisplay_internal will
12725 retry. */
12726
12727 static void
12728 redisplay_window (window, just_this_one_p)
12729 Lisp_Object window;
12730 int just_this_one_p;
12731 {
12732 struct window *w = XWINDOW (window);
12733 struct frame *f = XFRAME (w->frame);
12734 struct buffer *buffer = XBUFFER (w->buffer);
12735 struct buffer *old = current_buffer;
12736 struct text_pos lpoint, opoint, startp;
12737 int update_mode_line;
12738 int tem;
12739 struct it it;
12740 /* Record it now because it's overwritten. */
12741 int current_matrix_up_to_date_p = 0;
12742 int used_current_matrix_p = 0;
12743 /* This is less strict than current_matrix_up_to_date_p.
12744 It indictes that the buffer contents and narrowing are unchanged. */
12745 int buffer_unchanged_p = 0;
12746 int temp_scroll_step = 0;
12747 int count = SPECPDL_INDEX ();
12748 int rc;
12749 int centering_position = -1;
12750 int last_line_misfit = 0;
12751
12752 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12753 opoint = lpoint;
12754
12755 /* W must be a leaf window here. */
12756 xassert (!NILP (w->buffer));
12757 #if GLYPH_DEBUG
12758 *w->desired_matrix->method = 0;
12759 #endif
12760
12761 specbind (Qinhibit_point_motion_hooks, Qt);
12762
12763 reconsider_clip_changes (w, buffer);
12764
12765 /* Has the mode line to be updated? */
12766 update_mode_line = (!NILP (w->update_mode_line)
12767 || update_mode_lines
12768 || buffer->clip_changed
12769 || buffer->prevent_redisplay_optimizations_p);
12770
12771 if (MINI_WINDOW_P (w))
12772 {
12773 if (w == XWINDOW (echo_area_window)
12774 && !NILP (echo_area_buffer[0]))
12775 {
12776 if (update_mode_line)
12777 /* We may have to update a tty frame's menu bar or a
12778 tool-bar. Example `M-x C-h C-h C-g'. */
12779 goto finish_menu_bars;
12780 else
12781 /* We've already displayed the echo area glyphs in this window. */
12782 goto finish_scroll_bars;
12783 }
12784 else if ((w != XWINDOW (minibuf_window)
12785 || minibuf_level == 0)
12786 /* When buffer is nonempty, redisplay window normally. */
12787 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
12788 /* Quail displays non-mini buffers in minibuffer window.
12789 In that case, redisplay the window normally. */
12790 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
12791 {
12792 /* W is a mini-buffer window, but it's not active, so clear
12793 it. */
12794 int yb = window_text_bottom_y (w);
12795 struct glyph_row *row;
12796 int y;
12797
12798 for (y = 0, row = w->desired_matrix->rows;
12799 y < yb;
12800 y += row->height, ++row)
12801 blank_row (w, row, y);
12802 goto finish_scroll_bars;
12803 }
12804
12805 clear_glyph_matrix (w->desired_matrix);
12806 }
12807
12808 /* Otherwise set up data on this window; select its buffer and point
12809 value. */
12810 /* Really select the buffer, for the sake of buffer-local
12811 variables. */
12812 set_buffer_internal_1 (XBUFFER (w->buffer));
12813 SET_TEXT_POS (opoint, PT, PT_BYTE);
12814
12815 current_matrix_up_to_date_p
12816 = (!NILP (w->window_end_valid)
12817 && !current_buffer->clip_changed
12818 && !current_buffer->prevent_redisplay_optimizations_p
12819 && XFASTINT (w->last_modified) >= MODIFF
12820 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12821
12822 buffer_unchanged_p
12823 = (!NILP (w->window_end_valid)
12824 && !current_buffer->clip_changed
12825 && XFASTINT (w->last_modified) >= MODIFF
12826 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12827
12828 /* When windows_or_buffers_changed is non-zero, we can't rely on
12829 the window end being valid, so set it to nil there. */
12830 if (windows_or_buffers_changed)
12831 {
12832 /* If window starts on a continuation line, maybe adjust the
12833 window start in case the window's width changed. */
12834 if (XMARKER (w->start)->buffer == current_buffer)
12835 compute_window_start_on_continuation_line (w);
12836
12837 w->window_end_valid = Qnil;
12838 }
12839
12840 /* Some sanity checks. */
12841 CHECK_WINDOW_END (w);
12842 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
12843 abort ();
12844 if (BYTEPOS (opoint) < CHARPOS (opoint))
12845 abort ();
12846
12847 /* If %c is in mode line, update it if needed. */
12848 if (!NILP (w->column_number_displayed)
12849 /* This alternative quickly identifies a common case
12850 where no change is needed. */
12851 && !(PT == XFASTINT (w->last_point)
12852 && XFASTINT (w->last_modified) >= MODIFF
12853 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
12854 && (XFASTINT (w->column_number_displayed)
12855 != (int) current_column ())) /* iftc */
12856 update_mode_line = 1;
12857
12858 /* Count number of windows showing the selected buffer. An indirect
12859 buffer counts as its base buffer. */
12860 if (!just_this_one_p)
12861 {
12862 struct buffer *current_base, *window_base;
12863 current_base = current_buffer;
12864 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
12865 if (current_base->base_buffer)
12866 current_base = current_base->base_buffer;
12867 if (window_base->base_buffer)
12868 window_base = window_base->base_buffer;
12869 if (current_base == window_base)
12870 buffer_shared++;
12871 }
12872
12873 /* Point refers normally to the selected window. For any other
12874 window, set up appropriate value. */
12875 if (!EQ (window, selected_window))
12876 {
12877 int new_pt = XMARKER (w->pointm)->charpos;
12878 int new_pt_byte = marker_byte_position (w->pointm);
12879 if (new_pt < BEGV)
12880 {
12881 new_pt = BEGV;
12882 new_pt_byte = BEGV_BYTE;
12883 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
12884 }
12885 else if (new_pt > (ZV - 1))
12886 {
12887 new_pt = ZV;
12888 new_pt_byte = ZV_BYTE;
12889 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
12890 }
12891
12892 /* We don't use SET_PT so that the point-motion hooks don't run. */
12893 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
12894 }
12895
12896 /* If any of the character widths specified in the display table
12897 have changed, invalidate the width run cache. It's true that
12898 this may be a bit late to catch such changes, but the rest of
12899 redisplay goes (non-fatally) haywire when the display table is
12900 changed, so why should we worry about doing any better? */
12901 if (current_buffer->width_run_cache)
12902 {
12903 struct Lisp_Char_Table *disptab = buffer_display_table ();
12904
12905 if (! disptab_matches_widthtab (disptab,
12906 XVECTOR (current_buffer->width_table)))
12907 {
12908 invalidate_region_cache (current_buffer,
12909 current_buffer->width_run_cache,
12910 BEG, Z);
12911 recompute_width_table (current_buffer, disptab);
12912 }
12913 }
12914
12915 /* If window-start is screwed up, choose a new one. */
12916 if (XMARKER (w->start)->buffer != current_buffer)
12917 goto recenter;
12918
12919 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12920
12921 /* If someone specified a new starting point but did not insist,
12922 check whether it can be used. */
12923 if (!NILP (w->optional_new_start)
12924 && CHARPOS (startp) >= BEGV
12925 && CHARPOS (startp) <= ZV)
12926 {
12927 w->optional_new_start = Qnil;
12928 start_display (&it, w, startp);
12929 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12930 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12931 if (IT_CHARPOS (it) == PT)
12932 w->force_start = Qt;
12933 /* IT may overshoot PT if text at PT is invisible. */
12934 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
12935 w->force_start = Qt;
12936 }
12937
12938 /* Handle case where place to start displaying has been specified,
12939 unless the specified location is outside the accessible range. */
12940 if (!NILP (w->force_start)
12941 || w->frozen_window_start_p)
12942 {
12943 /* We set this later on if we have to adjust point. */
12944 int new_vpos = -1;
12945 int val;
12946
12947 w->force_start = Qnil;
12948 w->vscroll = 0;
12949 w->window_end_valid = Qnil;
12950
12951 /* Forget any recorded base line for line number display. */
12952 if (!buffer_unchanged_p)
12953 w->base_line_number = Qnil;
12954
12955 /* Redisplay the mode line. Select the buffer properly for that.
12956 Also, run the hook window-scroll-functions
12957 because we have scrolled. */
12958 /* Note, we do this after clearing force_start because
12959 if there's an error, it is better to forget about force_start
12960 than to get into an infinite loop calling the hook functions
12961 and having them get more errors. */
12962 if (!update_mode_line
12963 || ! NILP (Vwindow_scroll_functions))
12964 {
12965 update_mode_line = 1;
12966 w->update_mode_line = Qt;
12967 startp = run_window_scroll_functions (window, startp);
12968 }
12969
12970 w->last_modified = make_number (0);
12971 w->last_overlay_modified = make_number (0);
12972 if (CHARPOS (startp) < BEGV)
12973 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
12974 else if (CHARPOS (startp) > ZV)
12975 SET_TEXT_POS (startp, ZV, ZV_BYTE);
12976
12977 /* Redisplay, then check if cursor has been set during the
12978 redisplay. Give up if new fonts were loaded. */
12979 val = try_window (window, startp, 1);
12980 if (!val)
12981 {
12982 w->force_start = Qt;
12983 clear_glyph_matrix (w->desired_matrix);
12984 goto need_larger_matrices;
12985 }
12986 /* Point was outside the scroll margins. */
12987 if (val < 0)
12988 new_vpos = window_box_height (w) / 2;
12989
12990 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
12991 {
12992 /* If point does not appear, try to move point so it does
12993 appear. The desired matrix has been built above, so we
12994 can use it here. */
12995 new_vpos = window_box_height (w) / 2;
12996 }
12997
12998 if (!cursor_row_fully_visible_p (w, 0, 0))
12999 {
13000 /* Point does appear, but on a line partly visible at end of window.
13001 Move it back to a fully-visible line. */
13002 new_vpos = window_box_height (w);
13003 }
13004
13005 /* If we need to move point for either of the above reasons,
13006 now actually do it. */
13007 if (new_vpos >= 0)
13008 {
13009 struct glyph_row *row;
13010
13011 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
13012 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
13013 ++row;
13014
13015 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
13016 MATRIX_ROW_START_BYTEPOS (row));
13017
13018 if (w != XWINDOW (selected_window))
13019 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
13020 else if (current_buffer == old)
13021 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13022
13023 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
13024
13025 /* If we are highlighting the region, then we just changed
13026 the region, so redisplay to show it. */
13027 if (!NILP (Vtransient_mark_mode)
13028 && !NILP (current_buffer->mark_active))
13029 {
13030 clear_glyph_matrix (w->desired_matrix);
13031 if (!try_window (window, startp, 0))
13032 goto need_larger_matrices;
13033 }
13034 }
13035
13036 #if GLYPH_DEBUG
13037 debug_method_add (w, "forced window start");
13038 #endif
13039 goto done;
13040 }
13041
13042 /* Handle case where text has not changed, only point, and it has
13043 not moved off the frame, and we are not retrying after hscroll.
13044 (current_matrix_up_to_date_p is nonzero when retrying.) */
13045 if (current_matrix_up_to_date_p
13046 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
13047 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
13048 {
13049 switch (rc)
13050 {
13051 case CURSOR_MOVEMENT_SUCCESS:
13052 used_current_matrix_p = 1;
13053 goto done;
13054
13055 #if 0 /* try_cursor_movement never returns this value. */
13056 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
13057 goto need_larger_matrices;
13058 #endif
13059
13060 case CURSOR_MOVEMENT_MUST_SCROLL:
13061 goto try_to_scroll;
13062
13063 default:
13064 abort ();
13065 }
13066 }
13067 /* If current starting point was originally the beginning of a line
13068 but no longer is, find a new starting point. */
13069 else if (!NILP (w->start_at_line_beg)
13070 && !(CHARPOS (startp) <= BEGV
13071 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
13072 {
13073 #if GLYPH_DEBUG
13074 debug_method_add (w, "recenter 1");
13075 #endif
13076 goto recenter;
13077 }
13078
13079 /* Try scrolling with try_window_id. Value is > 0 if update has
13080 been done, it is -1 if we know that the same window start will
13081 not work. It is 0 if unsuccessful for some other reason. */
13082 else if ((tem = try_window_id (w)) != 0)
13083 {
13084 #if GLYPH_DEBUG
13085 debug_method_add (w, "try_window_id %d", tem);
13086 #endif
13087
13088 if (fonts_changed_p)
13089 goto need_larger_matrices;
13090 if (tem > 0)
13091 goto done;
13092
13093 /* Otherwise try_window_id has returned -1 which means that we
13094 don't want the alternative below this comment to execute. */
13095 }
13096 else if (CHARPOS (startp) >= BEGV
13097 && CHARPOS (startp) <= ZV
13098 && PT >= CHARPOS (startp)
13099 && (CHARPOS (startp) < ZV
13100 /* Avoid starting at end of buffer. */
13101 || CHARPOS (startp) == BEGV
13102 || (XFASTINT (w->last_modified) >= MODIFF
13103 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
13104 {
13105
13106 /* If first window line is a continuation line, and window start
13107 is inside the modified region, but the first change is before
13108 current window start, we must select a new window start.*/
13109 if (NILP (w->start_at_line_beg)
13110 && CHARPOS (startp) > BEGV)
13111 {
13112 /* Make sure beg_unchanged and end_unchanged are up to date.
13113 Do it only if buffer has really changed. This may or may
13114 not have been done by try_window_id (see which) already. */
13115 if (MODIFF > SAVE_MODIFF
13116 /* This seems to happen sometimes after saving a buffer. */
13117 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13118 {
13119 if (GPT - BEG < BEG_UNCHANGED)
13120 BEG_UNCHANGED = GPT - BEG;
13121 if (Z - GPT < END_UNCHANGED)
13122 END_UNCHANGED = Z - GPT;
13123 }
13124
13125 if (CHARPOS (startp) > BEG + BEG_UNCHANGED
13126 && CHARPOS (startp) <= Z - END_UNCHANGED)
13127 {
13128 /* There doesn't seems to be a simple way to find a new
13129 window start that is near the old window start, so
13130 we just recenter. */
13131 goto recenter;
13132 }
13133 }
13134
13135 #if GLYPH_DEBUG
13136 debug_method_add (w, "same window start");
13137 #endif
13138
13139 /* Try to redisplay starting at same place as before.
13140 If point has not moved off frame, accept the results. */
13141 if (!current_matrix_up_to_date_p
13142 /* Don't use try_window_reusing_current_matrix in this case
13143 because a window scroll function can have changed the
13144 buffer. */
13145 || !NILP (Vwindow_scroll_functions)
13146 || MINI_WINDOW_P (w)
13147 || !(used_current_matrix_p
13148 = try_window_reusing_current_matrix (w)))
13149 {
13150 IF_DEBUG (debug_method_add (w, "1"));
13151 if (try_window (window, startp, 1) < 0)
13152 /* -1 means we need to scroll.
13153 0 means we need new matrices, but fonts_changed_p
13154 is set in that case, so we will detect it below. */
13155 goto try_to_scroll;
13156 }
13157
13158 if (fonts_changed_p)
13159 goto need_larger_matrices;
13160
13161 if (w->cursor.vpos >= 0)
13162 {
13163 if (!just_this_one_p
13164 || current_buffer->clip_changed
13165 || BEG_UNCHANGED < CHARPOS (startp))
13166 /* Forget any recorded base line for line number display. */
13167 w->base_line_number = Qnil;
13168
13169 if (!cursor_row_fully_visible_p (w, 1, 0))
13170 {
13171 clear_glyph_matrix (w->desired_matrix);
13172 last_line_misfit = 1;
13173 }
13174 /* Drop through and scroll. */
13175 else
13176 goto done;
13177 }
13178 else
13179 clear_glyph_matrix (w->desired_matrix);
13180 }
13181
13182 try_to_scroll:
13183
13184 w->last_modified = make_number (0);
13185 w->last_overlay_modified = make_number (0);
13186
13187 /* Redisplay the mode line. Select the buffer properly for that. */
13188 if (!update_mode_line)
13189 {
13190 update_mode_line = 1;
13191 w->update_mode_line = Qt;
13192 }
13193
13194 /* Try to scroll by specified few lines. */
13195 if ((scroll_conservatively
13196 || scroll_step
13197 || temp_scroll_step
13198 || NUMBERP (current_buffer->scroll_up_aggressively)
13199 || NUMBERP (current_buffer->scroll_down_aggressively))
13200 && !current_buffer->clip_changed
13201 && CHARPOS (startp) >= BEGV
13202 && CHARPOS (startp) <= ZV)
13203 {
13204 /* The function returns -1 if new fonts were loaded, 1 if
13205 successful, 0 if not successful. */
13206 int rc = try_scrolling (window, just_this_one_p,
13207 scroll_conservatively,
13208 scroll_step,
13209 temp_scroll_step, last_line_misfit);
13210 switch (rc)
13211 {
13212 case SCROLLING_SUCCESS:
13213 goto done;
13214
13215 case SCROLLING_NEED_LARGER_MATRICES:
13216 goto need_larger_matrices;
13217
13218 case SCROLLING_FAILED:
13219 break;
13220
13221 default:
13222 abort ();
13223 }
13224 }
13225
13226 /* Finally, just choose place to start which centers point */
13227
13228 recenter:
13229 if (centering_position < 0)
13230 centering_position = window_box_height (w) / 2;
13231
13232 #if GLYPH_DEBUG
13233 debug_method_add (w, "recenter");
13234 #endif
13235
13236 /* w->vscroll = 0; */
13237
13238 /* Forget any previously recorded base line for line number display. */
13239 if (!buffer_unchanged_p)
13240 w->base_line_number = Qnil;
13241
13242 /* Move backward half the height of the window. */
13243 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13244 it.current_y = it.last_visible_y;
13245 move_it_vertically_backward (&it, centering_position);
13246 xassert (IT_CHARPOS (it) >= BEGV);
13247
13248 /* The function move_it_vertically_backward may move over more
13249 than the specified y-distance. If it->w is small, e.g. a
13250 mini-buffer window, we may end up in front of the window's
13251 display area. Start displaying at the start of the line
13252 containing PT in this case. */
13253 if (it.current_y <= 0)
13254 {
13255 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13256 move_it_vertically_backward (&it, 0);
13257 #if 0
13258 /* I think this assert is bogus if buffer contains
13259 invisible text or images. KFS. */
13260 xassert (IT_CHARPOS (it) <= PT);
13261 #endif
13262 it.current_y = 0;
13263 }
13264
13265 it.current_x = it.hpos = 0;
13266
13267 /* Set startp here explicitly in case that helps avoid an infinite loop
13268 in case the window-scroll-functions functions get errors. */
13269 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
13270
13271 /* Run scroll hooks. */
13272 startp = run_window_scroll_functions (window, it.current.pos);
13273
13274 /* Redisplay the window. */
13275 if (!current_matrix_up_to_date_p
13276 || windows_or_buffers_changed
13277 || cursor_type_changed
13278 /* Don't use try_window_reusing_current_matrix in this case
13279 because it can have changed the buffer. */
13280 || !NILP (Vwindow_scroll_functions)
13281 || !just_this_one_p
13282 || MINI_WINDOW_P (w)
13283 || !(used_current_matrix_p
13284 = try_window_reusing_current_matrix (w)))
13285 try_window (window, startp, 0);
13286
13287 /* If new fonts have been loaded (due to fontsets), give up. We
13288 have to start a new redisplay since we need to re-adjust glyph
13289 matrices. */
13290 if (fonts_changed_p)
13291 goto need_larger_matrices;
13292
13293 /* If cursor did not appear assume that the middle of the window is
13294 in the first line of the window. Do it again with the next line.
13295 (Imagine a window of height 100, displaying two lines of height
13296 60. Moving back 50 from it->last_visible_y will end in the first
13297 line.) */
13298 if (w->cursor.vpos < 0)
13299 {
13300 if (!NILP (w->window_end_valid)
13301 && PT >= Z - XFASTINT (w->window_end_pos))
13302 {
13303 clear_glyph_matrix (w->desired_matrix);
13304 move_it_by_lines (&it, 1, 0);
13305 try_window (window, it.current.pos, 0);
13306 }
13307 else if (PT < IT_CHARPOS (it))
13308 {
13309 clear_glyph_matrix (w->desired_matrix);
13310 move_it_by_lines (&it, -1, 0);
13311 try_window (window, it.current.pos, 0);
13312 }
13313 else
13314 {
13315 /* Not much we can do about it. */
13316 }
13317 }
13318
13319 /* Consider the following case: Window starts at BEGV, there is
13320 invisible, intangible text at BEGV, so that display starts at
13321 some point START > BEGV. It can happen that we are called with
13322 PT somewhere between BEGV and START. Try to handle that case. */
13323 if (w->cursor.vpos < 0)
13324 {
13325 struct glyph_row *row = w->current_matrix->rows;
13326 if (row->mode_line_p)
13327 ++row;
13328 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13329 }
13330
13331 if (!cursor_row_fully_visible_p (w, 0, 0))
13332 {
13333 /* If vscroll is enabled, disable it and try again. */
13334 if (w->vscroll)
13335 {
13336 w->vscroll = 0;
13337 clear_glyph_matrix (w->desired_matrix);
13338 goto recenter;
13339 }
13340
13341 /* If centering point failed to make the whole line visible,
13342 put point at the top instead. That has to make the whole line
13343 visible, if it can be done. */
13344 if (centering_position == 0)
13345 goto done;
13346
13347 clear_glyph_matrix (w->desired_matrix);
13348 centering_position = 0;
13349 goto recenter;
13350 }
13351
13352 done:
13353
13354 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13355 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
13356 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
13357 ? Qt : Qnil);
13358
13359 /* Display the mode line, if we must. */
13360 if ((update_mode_line
13361 /* If window not full width, must redo its mode line
13362 if (a) the window to its side is being redone and
13363 (b) we do a frame-based redisplay. This is a consequence
13364 of how inverted lines are drawn in frame-based redisplay. */
13365 || (!just_this_one_p
13366 && !FRAME_WINDOW_P (f)
13367 && !WINDOW_FULL_WIDTH_P (w))
13368 /* Line number to display. */
13369 || INTEGERP (w->base_line_pos)
13370 /* Column number is displayed and different from the one displayed. */
13371 || (!NILP (w->column_number_displayed)
13372 && (XFASTINT (w->column_number_displayed)
13373 != (int) current_column ()))) /* iftc */
13374 /* This means that the window has a mode line. */
13375 && (WINDOW_WANTS_MODELINE_P (w)
13376 || WINDOW_WANTS_HEADER_LINE_P (w)))
13377 {
13378 display_mode_lines (w);
13379
13380 /* If mode line height has changed, arrange for a thorough
13381 immediate redisplay using the correct mode line height. */
13382 if (WINDOW_WANTS_MODELINE_P (w)
13383 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
13384 {
13385 fonts_changed_p = 1;
13386 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
13387 = DESIRED_MODE_LINE_HEIGHT (w);
13388 }
13389
13390 /* If top line height has changed, arrange for a thorough
13391 immediate redisplay using the correct mode line height. */
13392 if (WINDOW_WANTS_HEADER_LINE_P (w)
13393 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
13394 {
13395 fonts_changed_p = 1;
13396 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
13397 = DESIRED_HEADER_LINE_HEIGHT (w);
13398 }
13399
13400 if (fonts_changed_p)
13401 goto need_larger_matrices;
13402 }
13403
13404 if (!line_number_displayed
13405 && !BUFFERP (w->base_line_pos))
13406 {
13407 w->base_line_pos = Qnil;
13408 w->base_line_number = Qnil;
13409 }
13410
13411 finish_menu_bars:
13412
13413 /* When we reach a frame's selected window, redo the frame's menu bar. */
13414 if (update_mode_line
13415 && EQ (FRAME_SELECTED_WINDOW (f), window))
13416 {
13417 int redisplay_menu_p = 0;
13418 int redisplay_tool_bar_p = 0;
13419
13420 if (FRAME_WINDOW_P (f))
13421 {
13422 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
13423 || defined (USE_GTK)
13424 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
13425 #else
13426 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13427 #endif
13428 }
13429 else
13430 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13431
13432 if (redisplay_menu_p)
13433 display_menu_bar (w);
13434
13435 #ifdef HAVE_WINDOW_SYSTEM
13436 #ifdef USE_GTK
13437 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
13438 #else
13439 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
13440 && (FRAME_TOOL_BAR_LINES (f) > 0
13441 || auto_resize_tool_bars_p);
13442
13443 #endif
13444
13445 if (redisplay_tool_bar_p)
13446 redisplay_tool_bar (f);
13447 #endif
13448 }
13449
13450 #ifdef HAVE_WINDOW_SYSTEM
13451 if (FRAME_WINDOW_P (f)
13452 && update_window_fringes (w, (just_this_one_p
13453 || (!used_current_matrix_p && !overlay_arrow_seen)
13454 || w->pseudo_window_p)))
13455 {
13456 update_begin (f);
13457 BLOCK_INPUT;
13458 if (draw_window_fringes (w, 1))
13459 x_draw_vertical_border (w);
13460 UNBLOCK_INPUT;
13461 update_end (f);
13462 }
13463 #endif /* HAVE_WINDOW_SYSTEM */
13464
13465 /* We go to this label, with fonts_changed_p nonzero,
13466 if it is necessary to try again using larger glyph matrices.
13467 We have to redeem the scroll bar even in this case,
13468 because the loop in redisplay_internal expects that. */
13469 need_larger_matrices:
13470 ;
13471 finish_scroll_bars:
13472
13473 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
13474 {
13475 /* Set the thumb's position and size. */
13476 set_vertical_scroll_bar (w);
13477
13478 /* Note that we actually used the scroll bar attached to this
13479 window, so it shouldn't be deleted at the end of redisplay. */
13480 redeem_scroll_bar_hook (w);
13481 }
13482
13483 /* Restore current_buffer and value of point in it. */
13484 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
13485 set_buffer_internal_1 (old);
13486 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
13487
13488 unbind_to (count, Qnil);
13489 }
13490
13491
13492 /* Build the complete desired matrix of WINDOW with a window start
13493 buffer position POS.
13494
13495 Value is 1 if successful. It is zero if fonts were loaded during
13496 redisplay which makes re-adjusting glyph matrices necessary, and -1
13497 if point would appear in the scroll margins.
13498 (We check that only if CHECK_MARGINS is nonzero. */
13499
13500 int
13501 try_window (window, pos, check_margins)
13502 Lisp_Object window;
13503 struct text_pos pos;
13504 int check_margins;
13505 {
13506 struct window *w = XWINDOW (window);
13507 struct it it;
13508 struct glyph_row *last_text_row = NULL;
13509
13510 /* Make POS the new window start. */
13511 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
13512
13513 /* Mark cursor position as unknown. No overlay arrow seen. */
13514 w->cursor.vpos = -1;
13515 overlay_arrow_seen = 0;
13516
13517 /* Initialize iterator and info to start at POS. */
13518 start_display (&it, w, pos);
13519
13520 /* Display all lines of W. */
13521 while (it.current_y < it.last_visible_y)
13522 {
13523 if (display_line (&it))
13524 last_text_row = it.glyph_row - 1;
13525 if (fonts_changed_p)
13526 return 0;
13527 }
13528
13529 /* Don't let the cursor end in the scroll margins. */
13530 if (check_margins
13531 && !MINI_WINDOW_P (w))
13532 {
13533 int this_scroll_margin;
13534
13535 this_scroll_margin = max (0, scroll_margin);
13536 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13537 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13538
13539 if ((w->cursor.y >= 0 /* not vscrolled */
13540 && w->cursor.y < this_scroll_margin
13541 && CHARPOS (pos) > BEGV
13542 && IT_CHARPOS (it) < ZV)
13543 /* rms: considering make_cursor_line_fully_visible_p here
13544 seems to give wrong results. We don't want to recenter
13545 when the last line is partly visible, we want to allow
13546 that case to be handled in the usual way. */
13547 || (w->cursor.y + 1) > it.last_visible_y)
13548 {
13549 w->cursor.vpos = -1;
13550 clear_glyph_matrix (w->desired_matrix);
13551 return -1;
13552 }
13553 }
13554
13555 /* If bottom moved off end of frame, change mode line percentage. */
13556 if (XFASTINT (w->window_end_pos) <= 0
13557 && Z != IT_CHARPOS (it))
13558 w->update_mode_line = Qt;
13559
13560 /* Set window_end_pos to the offset of the last character displayed
13561 on the window from the end of current_buffer. Set
13562 window_end_vpos to its row number. */
13563 if (last_text_row)
13564 {
13565 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
13566 w->window_end_bytepos
13567 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13568 w->window_end_pos
13569 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13570 w->window_end_vpos
13571 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13572 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
13573 ->displays_text_p);
13574 }
13575 else
13576 {
13577 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13578 w->window_end_pos = make_number (Z - ZV);
13579 w->window_end_vpos = make_number (0);
13580 }
13581
13582 /* But that is not valid info until redisplay finishes. */
13583 w->window_end_valid = Qnil;
13584 return 1;
13585 }
13586
13587
13588 \f
13589 /************************************************************************
13590 Window redisplay reusing current matrix when buffer has not changed
13591 ************************************************************************/
13592
13593 /* Try redisplay of window W showing an unchanged buffer with a
13594 different window start than the last time it was displayed by
13595 reusing its current matrix. Value is non-zero if successful.
13596 W->start is the new window start. */
13597
13598 static int
13599 try_window_reusing_current_matrix (w)
13600 struct window *w;
13601 {
13602 struct frame *f = XFRAME (w->frame);
13603 struct glyph_row *row, *bottom_row;
13604 struct it it;
13605 struct run run;
13606 struct text_pos start, new_start;
13607 int nrows_scrolled, i;
13608 struct glyph_row *last_text_row;
13609 struct glyph_row *last_reused_text_row;
13610 struct glyph_row *start_row;
13611 int start_vpos, min_y, max_y;
13612
13613 #if GLYPH_DEBUG
13614 if (inhibit_try_window_reusing)
13615 return 0;
13616 #endif
13617
13618 if (/* This function doesn't handle terminal frames. */
13619 !FRAME_WINDOW_P (f)
13620 /* Don't try to reuse the display if windows have been split
13621 or such. */
13622 || windows_or_buffers_changed
13623 || cursor_type_changed)
13624 return 0;
13625
13626 /* Can't do this if region may have changed. */
13627 if ((!NILP (Vtransient_mark_mode)
13628 && !NILP (current_buffer->mark_active))
13629 || !NILP (w->region_showing)
13630 || !NILP (Vshow_trailing_whitespace))
13631 return 0;
13632
13633 /* If top-line visibility has changed, give up. */
13634 if (WINDOW_WANTS_HEADER_LINE_P (w)
13635 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
13636 return 0;
13637
13638 /* Give up if old or new display is scrolled vertically. We could
13639 make this function handle this, but right now it doesn't. */
13640 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13641 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
13642 return 0;
13643
13644 /* The variable new_start now holds the new window start. The old
13645 start `start' can be determined from the current matrix. */
13646 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
13647 start = start_row->start.pos;
13648 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13649
13650 /* Clear the desired matrix for the display below. */
13651 clear_glyph_matrix (w->desired_matrix);
13652
13653 if (CHARPOS (new_start) <= CHARPOS (start))
13654 {
13655 int first_row_y;
13656
13657 /* Don't use this method if the display starts with an ellipsis
13658 displayed for invisible text. It's not easy to handle that case
13659 below, and it's certainly not worth the effort since this is
13660 not a frequent case. */
13661 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
13662 return 0;
13663
13664 IF_DEBUG (debug_method_add (w, "twu1"));
13665
13666 /* Display up to a row that can be reused. The variable
13667 last_text_row is set to the last row displayed that displays
13668 text. Note that it.vpos == 0 if or if not there is a
13669 header-line; it's not the same as the MATRIX_ROW_VPOS! */
13670 start_display (&it, w, new_start);
13671 first_row_y = it.current_y;
13672 w->cursor.vpos = -1;
13673 last_text_row = last_reused_text_row = NULL;
13674
13675 while (it.current_y < it.last_visible_y
13676 && !fonts_changed_p)
13677 {
13678 /* If we have reached into the characters in the START row,
13679 that means the line boundaries have changed. So we
13680 can't start copying with the row START. Maybe it will
13681 work to start copying with the following row. */
13682 while (IT_CHARPOS (it) > CHARPOS (start))
13683 {
13684 /* Advance to the next row as the "start". */
13685 start_row++;
13686 start = start_row->start.pos;
13687 /* If there are no more rows to try, or just one, give up. */
13688 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
13689 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
13690 || CHARPOS (start) == ZV)
13691 {
13692 clear_glyph_matrix (w->desired_matrix);
13693 return 0;
13694 }
13695
13696 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13697 }
13698 /* If we have reached alignment,
13699 we can copy the rest of the rows. */
13700 if (IT_CHARPOS (it) == CHARPOS (start))
13701 break;
13702
13703 if (display_line (&it))
13704 last_text_row = it.glyph_row - 1;
13705 }
13706
13707 /* A value of current_y < last_visible_y means that we stopped
13708 at the previous window start, which in turn means that we
13709 have at least one reusable row. */
13710 if (it.current_y < it.last_visible_y)
13711 {
13712 /* IT.vpos always starts from 0; it counts text lines. */
13713 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
13714
13715 /* Find PT if not already found in the lines displayed. */
13716 if (w->cursor.vpos < 0)
13717 {
13718 int dy = it.current_y - start_row->y;
13719
13720 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13721 row = row_containing_pos (w, PT, row, NULL, dy);
13722 if (row)
13723 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
13724 dy, nrows_scrolled);
13725 else
13726 {
13727 clear_glyph_matrix (w->desired_matrix);
13728 return 0;
13729 }
13730 }
13731
13732 /* Scroll the display. Do it before the current matrix is
13733 changed. The problem here is that update has not yet
13734 run, i.e. part of the current matrix is not up to date.
13735 scroll_run_hook will clear the cursor, and use the
13736 current matrix to get the height of the row the cursor is
13737 in. */
13738 run.current_y = start_row->y;
13739 run.desired_y = it.current_y;
13740 run.height = it.last_visible_y - it.current_y;
13741
13742 if (run.height > 0 && run.current_y != run.desired_y)
13743 {
13744 update_begin (f);
13745 rif->update_window_begin_hook (w);
13746 rif->clear_window_mouse_face (w);
13747 rif->scroll_run_hook (w, &run);
13748 rif->update_window_end_hook (w, 0, 0);
13749 update_end (f);
13750 }
13751
13752 /* Shift current matrix down by nrows_scrolled lines. */
13753 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13754 rotate_matrix (w->current_matrix,
13755 start_vpos,
13756 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13757 nrows_scrolled);
13758
13759 /* Disable lines that must be updated. */
13760 for (i = 0; i < it.vpos; ++i)
13761 (start_row + i)->enabled_p = 0;
13762
13763 /* Re-compute Y positions. */
13764 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13765 max_y = it.last_visible_y;
13766 for (row = start_row + nrows_scrolled;
13767 row < bottom_row;
13768 ++row)
13769 {
13770 row->y = it.current_y;
13771 row->visible_height = row->height;
13772
13773 if (row->y < min_y)
13774 row->visible_height -= min_y - row->y;
13775 if (row->y + row->height > max_y)
13776 row->visible_height -= row->y + row->height - max_y;
13777 row->redraw_fringe_bitmaps_p = 1;
13778
13779 it.current_y += row->height;
13780
13781 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13782 last_reused_text_row = row;
13783 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
13784 break;
13785 }
13786
13787 /* Disable lines in the current matrix which are now
13788 below the window. */
13789 for (++row; row < bottom_row; ++row)
13790 row->enabled_p = row->mode_line_p = 0;
13791 }
13792
13793 /* Update window_end_pos etc.; last_reused_text_row is the last
13794 reused row from the current matrix containing text, if any.
13795 The value of last_text_row is the last displayed line
13796 containing text. */
13797 if (last_reused_text_row)
13798 {
13799 w->window_end_bytepos
13800 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
13801 w->window_end_pos
13802 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
13803 w->window_end_vpos
13804 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
13805 w->current_matrix));
13806 }
13807 else if (last_text_row)
13808 {
13809 w->window_end_bytepos
13810 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13811 w->window_end_pos
13812 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13813 w->window_end_vpos
13814 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13815 }
13816 else
13817 {
13818 /* This window must be completely empty. */
13819 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13820 w->window_end_pos = make_number (Z - ZV);
13821 w->window_end_vpos = make_number (0);
13822 }
13823 w->window_end_valid = Qnil;
13824
13825 /* Update hint: don't try scrolling again in update_window. */
13826 w->desired_matrix->no_scrolling_p = 1;
13827
13828 #if GLYPH_DEBUG
13829 debug_method_add (w, "try_window_reusing_current_matrix 1");
13830 #endif
13831 return 1;
13832 }
13833 else if (CHARPOS (new_start) > CHARPOS (start))
13834 {
13835 struct glyph_row *pt_row, *row;
13836 struct glyph_row *first_reusable_row;
13837 struct glyph_row *first_row_to_display;
13838 int dy;
13839 int yb = window_text_bottom_y (w);
13840
13841 /* Find the row starting at new_start, if there is one. Don't
13842 reuse a partially visible line at the end. */
13843 first_reusable_row = start_row;
13844 while (first_reusable_row->enabled_p
13845 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
13846 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13847 < CHARPOS (new_start)))
13848 ++first_reusable_row;
13849
13850 /* Give up if there is no row to reuse. */
13851 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
13852 || !first_reusable_row->enabled_p
13853 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13854 != CHARPOS (new_start)))
13855 return 0;
13856
13857 /* We can reuse fully visible rows beginning with
13858 first_reusable_row to the end of the window. Set
13859 first_row_to_display to the first row that cannot be reused.
13860 Set pt_row to the row containing point, if there is any. */
13861 pt_row = NULL;
13862 for (first_row_to_display = first_reusable_row;
13863 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
13864 ++first_row_to_display)
13865 {
13866 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
13867 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
13868 pt_row = first_row_to_display;
13869 }
13870
13871 /* Start displaying at the start of first_row_to_display. */
13872 xassert (first_row_to_display->y < yb);
13873 init_to_row_start (&it, w, first_row_to_display);
13874
13875 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
13876 - start_vpos);
13877 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
13878 - nrows_scrolled);
13879 it.current_y = (first_row_to_display->y - first_reusable_row->y
13880 + WINDOW_HEADER_LINE_HEIGHT (w));
13881
13882 /* Display lines beginning with first_row_to_display in the
13883 desired matrix. Set last_text_row to the last row displayed
13884 that displays text. */
13885 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
13886 if (pt_row == NULL)
13887 w->cursor.vpos = -1;
13888 last_text_row = NULL;
13889 while (it.current_y < it.last_visible_y && !fonts_changed_p)
13890 if (display_line (&it))
13891 last_text_row = it.glyph_row - 1;
13892
13893 /* Give up If point isn't in a row displayed or reused. */
13894 if (w->cursor.vpos < 0)
13895 {
13896 clear_glyph_matrix (w->desired_matrix);
13897 return 0;
13898 }
13899
13900 /* If point is in a reused row, adjust y and vpos of the cursor
13901 position. */
13902 if (pt_row)
13903 {
13904 w->cursor.vpos -= nrows_scrolled;
13905 w->cursor.y -= first_reusable_row->y - start_row->y;
13906 }
13907
13908 /* Scroll the display. */
13909 run.current_y = first_reusable_row->y;
13910 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
13911 run.height = it.last_visible_y - run.current_y;
13912 dy = run.current_y - run.desired_y;
13913
13914 if (run.height)
13915 {
13916 update_begin (f);
13917 rif->update_window_begin_hook (w);
13918 rif->clear_window_mouse_face (w);
13919 rif->scroll_run_hook (w, &run);
13920 rif->update_window_end_hook (w, 0, 0);
13921 update_end (f);
13922 }
13923
13924 /* Adjust Y positions of reused rows. */
13925 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13926 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13927 max_y = it.last_visible_y;
13928 for (row = first_reusable_row; row < first_row_to_display; ++row)
13929 {
13930 row->y -= dy;
13931 row->visible_height = row->height;
13932 if (row->y < min_y)
13933 row->visible_height -= min_y - row->y;
13934 if (row->y + row->height > max_y)
13935 row->visible_height -= row->y + row->height - max_y;
13936 row->redraw_fringe_bitmaps_p = 1;
13937 }
13938
13939 /* Scroll the current matrix. */
13940 xassert (nrows_scrolled > 0);
13941 rotate_matrix (w->current_matrix,
13942 start_vpos,
13943 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13944 -nrows_scrolled);
13945
13946 /* Disable rows not reused. */
13947 for (row -= nrows_scrolled; row < bottom_row; ++row)
13948 row->enabled_p = 0;
13949
13950 /* Point may have moved to a different line, so we cannot assume that
13951 the previous cursor position is valid; locate the correct row. */
13952 if (pt_row)
13953 {
13954 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
13955 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
13956 row++)
13957 {
13958 w->cursor.vpos++;
13959 w->cursor.y = row->y;
13960 }
13961 if (row < bottom_row)
13962 {
13963 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
13964 while (glyph->charpos < PT)
13965 {
13966 w->cursor.hpos++;
13967 w->cursor.x += glyph->pixel_width;
13968 glyph++;
13969 }
13970 }
13971 }
13972
13973 /* Adjust window end. A null value of last_text_row means that
13974 the window end is in reused rows which in turn means that
13975 only its vpos can have changed. */
13976 if (last_text_row)
13977 {
13978 w->window_end_bytepos
13979 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13980 w->window_end_pos
13981 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13982 w->window_end_vpos
13983 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13984 }
13985 else
13986 {
13987 w->window_end_vpos
13988 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
13989 }
13990
13991 w->window_end_valid = Qnil;
13992 w->desired_matrix->no_scrolling_p = 1;
13993
13994 #if GLYPH_DEBUG
13995 debug_method_add (w, "try_window_reusing_current_matrix 2");
13996 #endif
13997 return 1;
13998 }
13999
14000 return 0;
14001 }
14002
14003
14004 \f
14005 /************************************************************************
14006 Window redisplay reusing current matrix when buffer has changed
14007 ************************************************************************/
14008
14009 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
14010 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
14011 int *, int *));
14012 static struct glyph_row *
14013 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
14014 struct glyph_row *));
14015
14016
14017 /* Return the last row in MATRIX displaying text. If row START is
14018 non-null, start searching with that row. IT gives the dimensions
14019 of the display. Value is null if matrix is empty; otherwise it is
14020 a pointer to the row found. */
14021
14022 static struct glyph_row *
14023 find_last_row_displaying_text (matrix, it, start)
14024 struct glyph_matrix *matrix;
14025 struct it *it;
14026 struct glyph_row *start;
14027 {
14028 struct glyph_row *row, *row_found;
14029
14030 /* Set row_found to the last row in IT->w's current matrix
14031 displaying text. The loop looks funny but think of partially
14032 visible lines. */
14033 row_found = NULL;
14034 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
14035 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14036 {
14037 xassert (row->enabled_p);
14038 row_found = row;
14039 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
14040 break;
14041 ++row;
14042 }
14043
14044 return row_found;
14045 }
14046
14047
14048 /* Return the last row in the current matrix of W that is not affected
14049 by changes at the start of current_buffer that occurred since W's
14050 current matrix was built. Value is null if no such row exists.
14051
14052 BEG_UNCHANGED us the number of characters unchanged at the start of
14053 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
14054 first changed character in current_buffer. Characters at positions <
14055 BEG + BEG_UNCHANGED are at the same buffer positions as they were
14056 when the current matrix was built. */
14057
14058 static struct glyph_row *
14059 find_last_unchanged_at_beg_row (w)
14060 struct window *w;
14061 {
14062 int first_changed_pos = BEG + BEG_UNCHANGED;
14063 struct glyph_row *row;
14064 struct glyph_row *row_found = NULL;
14065 int yb = window_text_bottom_y (w);
14066
14067 /* Find the last row displaying unchanged text. */
14068 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14069 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14070 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
14071 {
14072 if (/* If row ends before first_changed_pos, it is unchanged,
14073 except in some case. */
14074 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
14075 /* When row ends in ZV and we write at ZV it is not
14076 unchanged. */
14077 && !row->ends_at_zv_p
14078 /* When first_changed_pos is the end of a continued line,
14079 row is not unchanged because it may be no longer
14080 continued. */
14081 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
14082 && (row->continued_p
14083 || row->exact_window_width_line_p)))
14084 row_found = row;
14085
14086 /* Stop if last visible row. */
14087 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
14088 break;
14089
14090 ++row;
14091 }
14092
14093 return row_found;
14094 }
14095
14096
14097 /* Find the first glyph row in the current matrix of W that is not
14098 affected by changes at the end of current_buffer since the
14099 time W's current matrix was built.
14100
14101 Return in *DELTA the number of chars by which buffer positions in
14102 unchanged text at the end of current_buffer must be adjusted.
14103
14104 Return in *DELTA_BYTES the corresponding number of bytes.
14105
14106 Value is null if no such row exists, i.e. all rows are affected by
14107 changes. */
14108
14109 static struct glyph_row *
14110 find_first_unchanged_at_end_row (w, delta, delta_bytes)
14111 struct window *w;
14112 int *delta, *delta_bytes;
14113 {
14114 struct glyph_row *row;
14115 struct glyph_row *row_found = NULL;
14116
14117 *delta = *delta_bytes = 0;
14118
14119 /* Display must not have been paused, otherwise the current matrix
14120 is not up to date. */
14121 if (NILP (w->window_end_valid))
14122 abort ();
14123
14124 /* A value of window_end_pos >= END_UNCHANGED means that the window
14125 end is in the range of changed text. If so, there is no
14126 unchanged row at the end of W's current matrix. */
14127 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
14128 return NULL;
14129
14130 /* Set row to the last row in W's current matrix displaying text. */
14131 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14132
14133 /* If matrix is entirely empty, no unchanged row exists. */
14134 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14135 {
14136 /* The value of row is the last glyph row in the matrix having a
14137 meaningful buffer position in it. The end position of row
14138 corresponds to window_end_pos. This allows us to translate
14139 buffer positions in the current matrix to current buffer
14140 positions for characters not in changed text. */
14141 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14142 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14143 int last_unchanged_pos, last_unchanged_pos_old;
14144 struct glyph_row *first_text_row
14145 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14146
14147 *delta = Z - Z_old;
14148 *delta_bytes = Z_BYTE - Z_BYTE_old;
14149
14150 /* Set last_unchanged_pos to the buffer position of the last
14151 character in the buffer that has not been changed. Z is the
14152 index + 1 of the last character in current_buffer, i.e. by
14153 subtracting END_UNCHANGED we get the index of the last
14154 unchanged character, and we have to add BEG to get its buffer
14155 position. */
14156 last_unchanged_pos = Z - END_UNCHANGED + BEG;
14157 last_unchanged_pos_old = last_unchanged_pos - *delta;
14158
14159 /* Search backward from ROW for a row displaying a line that
14160 starts at a minimum position >= last_unchanged_pos_old. */
14161 for (; row > first_text_row; --row)
14162 {
14163 /* This used to abort, but it can happen.
14164 It is ok to just stop the search instead here. KFS. */
14165 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
14166 break;
14167
14168 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
14169 row_found = row;
14170 }
14171 }
14172
14173 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
14174 abort ();
14175
14176 return row_found;
14177 }
14178
14179
14180 /* Make sure that glyph rows in the current matrix of window W
14181 reference the same glyph memory as corresponding rows in the
14182 frame's frame matrix. This function is called after scrolling W's
14183 current matrix on a terminal frame in try_window_id and
14184 try_window_reusing_current_matrix. */
14185
14186 static void
14187 sync_frame_with_window_matrix_rows (w)
14188 struct window *w;
14189 {
14190 struct frame *f = XFRAME (w->frame);
14191 struct glyph_row *window_row, *window_row_end, *frame_row;
14192
14193 /* Preconditions: W must be a leaf window and full-width. Its frame
14194 must have a frame matrix. */
14195 xassert (NILP (w->hchild) && NILP (w->vchild));
14196 xassert (WINDOW_FULL_WIDTH_P (w));
14197 xassert (!FRAME_WINDOW_P (f));
14198
14199 /* If W is a full-width window, glyph pointers in W's current matrix
14200 have, by definition, to be the same as glyph pointers in the
14201 corresponding frame matrix. Note that frame matrices have no
14202 marginal areas (see build_frame_matrix). */
14203 window_row = w->current_matrix->rows;
14204 window_row_end = window_row + w->current_matrix->nrows;
14205 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
14206 while (window_row < window_row_end)
14207 {
14208 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
14209 struct glyph *end = window_row->glyphs[LAST_AREA];
14210
14211 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
14212 frame_row->glyphs[TEXT_AREA] = start;
14213 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
14214 frame_row->glyphs[LAST_AREA] = end;
14215
14216 /* Disable frame rows whose corresponding window rows have
14217 been disabled in try_window_id. */
14218 if (!window_row->enabled_p)
14219 frame_row->enabled_p = 0;
14220
14221 ++window_row, ++frame_row;
14222 }
14223 }
14224
14225
14226 /* Find the glyph row in window W containing CHARPOS. Consider all
14227 rows between START and END (not inclusive). END null means search
14228 all rows to the end of the display area of W. Value is the row
14229 containing CHARPOS or null. */
14230
14231 struct glyph_row *
14232 row_containing_pos (w, charpos, start, end, dy)
14233 struct window *w;
14234 int charpos;
14235 struct glyph_row *start, *end;
14236 int dy;
14237 {
14238 struct glyph_row *row = start;
14239 int last_y;
14240
14241 /* If we happen to start on a header-line, skip that. */
14242 if (row->mode_line_p)
14243 ++row;
14244
14245 if ((end && row >= end) || !row->enabled_p)
14246 return NULL;
14247
14248 last_y = window_text_bottom_y (w) - dy;
14249
14250 while (1)
14251 {
14252 /* Give up if we have gone too far. */
14253 if (end && row >= end)
14254 return NULL;
14255 /* This formerly returned if they were equal.
14256 I think that both quantities are of a "last plus one" type;
14257 if so, when they are equal, the row is within the screen. -- rms. */
14258 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
14259 return NULL;
14260
14261 /* If it is in this row, return this row. */
14262 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
14263 || (MATRIX_ROW_END_CHARPOS (row) == charpos
14264 /* The end position of a row equals the start
14265 position of the next row. If CHARPOS is there, we
14266 would rather display it in the next line, except
14267 when this line ends in ZV. */
14268 && !row->ends_at_zv_p
14269 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14270 && charpos >= MATRIX_ROW_START_CHARPOS (row))
14271 return row;
14272 ++row;
14273 }
14274 }
14275
14276
14277 /* Try to redisplay window W by reusing its existing display. W's
14278 current matrix must be up to date when this function is called,
14279 i.e. window_end_valid must not be nil.
14280
14281 Value is
14282
14283 1 if display has been updated
14284 0 if otherwise unsuccessful
14285 -1 if redisplay with same window start is known not to succeed
14286
14287 The following steps are performed:
14288
14289 1. Find the last row in the current matrix of W that is not
14290 affected by changes at the start of current_buffer. If no such row
14291 is found, give up.
14292
14293 2. Find the first row in W's current matrix that is not affected by
14294 changes at the end of current_buffer. Maybe there is no such row.
14295
14296 3. Display lines beginning with the row + 1 found in step 1 to the
14297 row found in step 2 or, if step 2 didn't find a row, to the end of
14298 the window.
14299
14300 4. If cursor is not known to appear on the window, give up.
14301
14302 5. If display stopped at the row found in step 2, scroll the
14303 display and current matrix as needed.
14304
14305 6. Maybe display some lines at the end of W, if we must. This can
14306 happen under various circumstances, like a partially visible line
14307 becoming fully visible, or because newly displayed lines are displayed
14308 in smaller font sizes.
14309
14310 7. Update W's window end information. */
14311
14312 static int
14313 try_window_id (w)
14314 struct window *w;
14315 {
14316 struct frame *f = XFRAME (w->frame);
14317 struct glyph_matrix *current_matrix = w->current_matrix;
14318 struct glyph_matrix *desired_matrix = w->desired_matrix;
14319 struct glyph_row *last_unchanged_at_beg_row;
14320 struct glyph_row *first_unchanged_at_end_row;
14321 struct glyph_row *row;
14322 struct glyph_row *bottom_row;
14323 int bottom_vpos;
14324 struct it it;
14325 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
14326 struct text_pos start_pos;
14327 struct run run;
14328 int first_unchanged_at_end_vpos = 0;
14329 struct glyph_row *last_text_row, *last_text_row_at_end;
14330 struct text_pos start;
14331 int first_changed_charpos, last_changed_charpos;
14332
14333 #if GLYPH_DEBUG
14334 if (inhibit_try_window_id)
14335 return 0;
14336 #endif
14337
14338 /* This is handy for debugging. */
14339 #if 0
14340 #define GIVE_UP(X) \
14341 do { \
14342 fprintf (stderr, "try_window_id give up %d\n", (X)); \
14343 return 0; \
14344 } while (0)
14345 #else
14346 #define GIVE_UP(X) return 0
14347 #endif
14348
14349 SET_TEXT_POS_FROM_MARKER (start, w->start);
14350
14351 /* Don't use this for mini-windows because these can show
14352 messages and mini-buffers, and we don't handle that here. */
14353 if (MINI_WINDOW_P (w))
14354 GIVE_UP (1);
14355
14356 /* This flag is used to prevent redisplay optimizations. */
14357 if (windows_or_buffers_changed || cursor_type_changed)
14358 GIVE_UP (2);
14359
14360 /* Verify that narrowing has not changed.
14361 Also verify that we were not told to prevent redisplay optimizations.
14362 It would be nice to further
14363 reduce the number of cases where this prevents try_window_id. */
14364 if (current_buffer->clip_changed
14365 || current_buffer->prevent_redisplay_optimizations_p)
14366 GIVE_UP (3);
14367
14368 /* Window must either use window-based redisplay or be full width. */
14369 if (!FRAME_WINDOW_P (f)
14370 && (!line_ins_del_ok
14371 || !WINDOW_FULL_WIDTH_P (w)))
14372 GIVE_UP (4);
14373
14374 /* Give up if point is not known NOT to appear in W. */
14375 if (PT < CHARPOS (start))
14376 GIVE_UP (5);
14377
14378 /* Another way to prevent redisplay optimizations. */
14379 if (XFASTINT (w->last_modified) == 0)
14380 GIVE_UP (6);
14381
14382 /* Verify that window is not hscrolled. */
14383 if (XFASTINT (w->hscroll) != 0)
14384 GIVE_UP (7);
14385
14386 /* Verify that display wasn't paused. */
14387 if (NILP (w->window_end_valid))
14388 GIVE_UP (8);
14389
14390 /* Can't use this if highlighting a region because a cursor movement
14391 will do more than just set the cursor. */
14392 if (!NILP (Vtransient_mark_mode)
14393 && !NILP (current_buffer->mark_active))
14394 GIVE_UP (9);
14395
14396 /* Likewise if highlighting trailing whitespace. */
14397 if (!NILP (Vshow_trailing_whitespace))
14398 GIVE_UP (11);
14399
14400 /* Likewise if showing a region. */
14401 if (!NILP (w->region_showing))
14402 GIVE_UP (10);
14403
14404 /* Can use this if overlay arrow position and or string have changed. */
14405 if (overlay_arrows_changed_p ())
14406 GIVE_UP (12);
14407
14408
14409 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
14410 only if buffer has really changed. The reason is that the gap is
14411 initially at Z for freshly visited files. The code below would
14412 set end_unchanged to 0 in that case. */
14413 if (MODIFF > SAVE_MODIFF
14414 /* This seems to happen sometimes after saving a buffer. */
14415 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
14416 {
14417 if (GPT - BEG < BEG_UNCHANGED)
14418 BEG_UNCHANGED = GPT - BEG;
14419 if (Z - GPT < END_UNCHANGED)
14420 END_UNCHANGED = Z - GPT;
14421 }
14422
14423 /* The position of the first and last character that has been changed. */
14424 first_changed_charpos = BEG + BEG_UNCHANGED;
14425 last_changed_charpos = Z - END_UNCHANGED;
14426
14427 /* If window starts after a line end, and the last change is in
14428 front of that newline, then changes don't affect the display.
14429 This case happens with stealth-fontification. Note that although
14430 the display is unchanged, glyph positions in the matrix have to
14431 be adjusted, of course. */
14432 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14433 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14434 && ((last_changed_charpos < CHARPOS (start)
14435 && CHARPOS (start) == BEGV)
14436 || (last_changed_charpos < CHARPOS (start) - 1
14437 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
14438 {
14439 int Z_old, delta, Z_BYTE_old, delta_bytes;
14440 struct glyph_row *r0;
14441
14442 /* Compute how many chars/bytes have been added to or removed
14443 from the buffer. */
14444 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14445 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14446 delta = Z - Z_old;
14447 delta_bytes = Z_BYTE - Z_BYTE_old;
14448
14449 /* Give up if PT is not in the window. Note that it already has
14450 been checked at the start of try_window_id that PT is not in
14451 front of the window start. */
14452 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
14453 GIVE_UP (13);
14454
14455 /* If window start is unchanged, we can reuse the whole matrix
14456 as is, after adjusting glyph positions. No need to compute
14457 the window end again, since its offset from Z hasn't changed. */
14458 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14459 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
14460 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
14461 /* PT must not be in a partially visible line. */
14462 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
14463 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14464 {
14465 /* Adjust positions in the glyph matrix. */
14466 if (delta || delta_bytes)
14467 {
14468 struct glyph_row *r1
14469 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14470 increment_matrix_positions (w->current_matrix,
14471 MATRIX_ROW_VPOS (r0, current_matrix),
14472 MATRIX_ROW_VPOS (r1, current_matrix),
14473 delta, delta_bytes);
14474 }
14475
14476 /* Set the cursor. */
14477 row = row_containing_pos (w, PT, r0, NULL, 0);
14478 if (row)
14479 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14480 else
14481 abort ();
14482 return 1;
14483 }
14484 }
14485
14486 /* Handle the case that changes are all below what is displayed in
14487 the window, and that PT is in the window. This shortcut cannot
14488 be taken if ZV is visible in the window, and text has been added
14489 there that is visible in the window. */
14490 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
14491 /* ZV is not visible in the window, or there are no
14492 changes at ZV, actually. */
14493 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
14494 || first_changed_charpos == last_changed_charpos))
14495 {
14496 struct glyph_row *r0;
14497
14498 /* Give up if PT is not in the window. Note that it already has
14499 been checked at the start of try_window_id that PT is not in
14500 front of the window start. */
14501 if (PT >= MATRIX_ROW_END_CHARPOS (row))
14502 GIVE_UP (14);
14503
14504 /* If window start is unchanged, we can reuse the whole matrix
14505 as is, without changing glyph positions since no text has
14506 been added/removed in front of the window end. */
14507 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14508 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
14509 /* PT must not be in a partially visible line. */
14510 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
14511 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14512 {
14513 /* We have to compute the window end anew since text
14514 can have been added/removed after it. */
14515 w->window_end_pos
14516 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14517 w->window_end_bytepos
14518 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14519
14520 /* Set the cursor. */
14521 row = row_containing_pos (w, PT, r0, NULL, 0);
14522 if (row)
14523 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14524 else
14525 abort ();
14526 return 2;
14527 }
14528 }
14529
14530 /* Give up if window start is in the changed area.
14531
14532 The condition used to read
14533
14534 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
14535
14536 but why that was tested escapes me at the moment. */
14537 if (CHARPOS (start) >= first_changed_charpos
14538 && CHARPOS (start) <= last_changed_charpos)
14539 GIVE_UP (15);
14540
14541 /* Check that window start agrees with the start of the first glyph
14542 row in its current matrix. Check this after we know the window
14543 start is not in changed text, otherwise positions would not be
14544 comparable. */
14545 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
14546 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
14547 GIVE_UP (16);
14548
14549 /* Give up if the window ends in strings. Overlay strings
14550 at the end are difficult to handle, so don't try. */
14551 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
14552 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
14553 GIVE_UP (20);
14554
14555 /* Compute the position at which we have to start displaying new
14556 lines. Some of the lines at the top of the window might be
14557 reusable because they are not displaying changed text. Find the
14558 last row in W's current matrix not affected by changes at the
14559 start of current_buffer. Value is null if changes start in the
14560 first line of window. */
14561 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
14562 if (last_unchanged_at_beg_row)
14563 {
14564 /* Avoid starting to display in the moddle of a character, a TAB
14565 for instance. This is easier than to set up the iterator
14566 exactly, and it's not a frequent case, so the additional
14567 effort wouldn't really pay off. */
14568 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
14569 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
14570 && last_unchanged_at_beg_row > w->current_matrix->rows)
14571 --last_unchanged_at_beg_row;
14572
14573 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
14574 GIVE_UP (17);
14575
14576 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
14577 GIVE_UP (18);
14578 start_pos = it.current.pos;
14579
14580 /* Start displaying new lines in the desired matrix at the same
14581 vpos we would use in the current matrix, i.e. below
14582 last_unchanged_at_beg_row. */
14583 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
14584 current_matrix);
14585 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14586 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
14587
14588 xassert (it.hpos == 0 && it.current_x == 0);
14589 }
14590 else
14591 {
14592 /* There are no reusable lines at the start of the window.
14593 Start displaying in the first text line. */
14594 start_display (&it, w, start);
14595 it.vpos = it.first_vpos;
14596 start_pos = it.current.pos;
14597 }
14598
14599 /* Find the first row that is not affected by changes at the end of
14600 the buffer. Value will be null if there is no unchanged row, in
14601 which case we must redisplay to the end of the window. delta
14602 will be set to the value by which buffer positions beginning with
14603 first_unchanged_at_end_row have to be adjusted due to text
14604 changes. */
14605 first_unchanged_at_end_row
14606 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
14607 IF_DEBUG (debug_delta = delta);
14608 IF_DEBUG (debug_delta_bytes = delta_bytes);
14609
14610 /* Set stop_pos to the buffer position up to which we will have to
14611 display new lines. If first_unchanged_at_end_row != NULL, this
14612 is the buffer position of the start of the line displayed in that
14613 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
14614 that we don't stop at a buffer position. */
14615 stop_pos = 0;
14616 if (first_unchanged_at_end_row)
14617 {
14618 xassert (last_unchanged_at_beg_row == NULL
14619 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
14620
14621 /* If this is a continuation line, move forward to the next one
14622 that isn't. Changes in lines above affect this line.
14623 Caution: this may move first_unchanged_at_end_row to a row
14624 not displaying text. */
14625 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
14626 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14627 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14628 < it.last_visible_y))
14629 ++first_unchanged_at_end_row;
14630
14631 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14632 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14633 >= it.last_visible_y))
14634 first_unchanged_at_end_row = NULL;
14635 else
14636 {
14637 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
14638 + delta);
14639 first_unchanged_at_end_vpos
14640 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
14641 xassert (stop_pos >= Z - END_UNCHANGED);
14642 }
14643 }
14644 else if (last_unchanged_at_beg_row == NULL)
14645 GIVE_UP (19);
14646
14647
14648 #if GLYPH_DEBUG
14649
14650 /* Either there is no unchanged row at the end, or the one we have
14651 now displays text. This is a necessary condition for the window
14652 end pos calculation at the end of this function. */
14653 xassert (first_unchanged_at_end_row == NULL
14654 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
14655
14656 debug_last_unchanged_at_beg_vpos
14657 = (last_unchanged_at_beg_row
14658 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
14659 : -1);
14660 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
14661
14662 #endif /* GLYPH_DEBUG != 0 */
14663
14664
14665 /* Display new lines. Set last_text_row to the last new line
14666 displayed which has text on it, i.e. might end up as being the
14667 line where the window_end_vpos is. */
14668 w->cursor.vpos = -1;
14669 last_text_row = NULL;
14670 overlay_arrow_seen = 0;
14671 while (it.current_y < it.last_visible_y
14672 && !fonts_changed_p
14673 && (first_unchanged_at_end_row == NULL
14674 || IT_CHARPOS (it) < stop_pos))
14675 {
14676 if (display_line (&it))
14677 last_text_row = it.glyph_row - 1;
14678 }
14679
14680 if (fonts_changed_p)
14681 return -1;
14682
14683
14684 /* Compute differences in buffer positions, y-positions etc. for
14685 lines reused at the bottom of the window. Compute what we can
14686 scroll. */
14687 if (first_unchanged_at_end_row
14688 /* No lines reused because we displayed everything up to the
14689 bottom of the window. */
14690 && it.current_y < it.last_visible_y)
14691 {
14692 dvpos = (it.vpos
14693 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
14694 current_matrix));
14695 dy = it.current_y - first_unchanged_at_end_row->y;
14696 run.current_y = first_unchanged_at_end_row->y;
14697 run.desired_y = run.current_y + dy;
14698 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
14699 }
14700 else
14701 {
14702 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
14703 first_unchanged_at_end_row = NULL;
14704 }
14705 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
14706
14707
14708 /* Find the cursor if not already found. We have to decide whether
14709 PT will appear on this window (it sometimes doesn't, but this is
14710 not a very frequent case.) This decision has to be made before
14711 the current matrix is altered. A value of cursor.vpos < 0 means
14712 that PT is either in one of the lines beginning at
14713 first_unchanged_at_end_row or below the window. Don't care for
14714 lines that might be displayed later at the window end; as
14715 mentioned, this is not a frequent case. */
14716 if (w->cursor.vpos < 0)
14717 {
14718 /* Cursor in unchanged rows at the top? */
14719 if (PT < CHARPOS (start_pos)
14720 && last_unchanged_at_beg_row)
14721 {
14722 row = row_containing_pos (w, PT,
14723 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
14724 last_unchanged_at_beg_row + 1, 0);
14725 if (row)
14726 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14727 }
14728
14729 /* Start from first_unchanged_at_end_row looking for PT. */
14730 else if (first_unchanged_at_end_row)
14731 {
14732 row = row_containing_pos (w, PT - delta,
14733 first_unchanged_at_end_row, NULL, 0);
14734 if (row)
14735 set_cursor_from_row (w, row, w->current_matrix, delta,
14736 delta_bytes, dy, dvpos);
14737 }
14738
14739 /* Give up if cursor was not found. */
14740 if (w->cursor.vpos < 0)
14741 {
14742 clear_glyph_matrix (w->desired_matrix);
14743 return -1;
14744 }
14745 }
14746
14747 /* Don't let the cursor end in the scroll margins. */
14748 {
14749 int this_scroll_margin, cursor_height;
14750
14751 this_scroll_margin = max (0, scroll_margin);
14752 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14753 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
14754 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
14755
14756 if ((w->cursor.y < this_scroll_margin
14757 && CHARPOS (start) > BEGV)
14758 /* Old redisplay didn't take scroll margin into account at the bottom,
14759 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
14760 || (w->cursor.y + (make_cursor_line_fully_visible_p
14761 ? cursor_height + this_scroll_margin
14762 : 1)) > it.last_visible_y)
14763 {
14764 w->cursor.vpos = -1;
14765 clear_glyph_matrix (w->desired_matrix);
14766 return -1;
14767 }
14768 }
14769
14770 /* Scroll the display. Do it before changing the current matrix so
14771 that xterm.c doesn't get confused about where the cursor glyph is
14772 found. */
14773 if (dy && run.height)
14774 {
14775 update_begin (f);
14776
14777 if (FRAME_WINDOW_P (f))
14778 {
14779 rif->update_window_begin_hook (w);
14780 rif->clear_window_mouse_face (w);
14781 rif->scroll_run_hook (w, &run);
14782 rif->update_window_end_hook (w, 0, 0);
14783 }
14784 else
14785 {
14786 /* Terminal frame. In this case, dvpos gives the number of
14787 lines to scroll by; dvpos < 0 means scroll up. */
14788 int first_unchanged_at_end_vpos
14789 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
14790 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
14791 int end = (WINDOW_TOP_EDGE_LINE (w)
14792 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
14793 + window_internal_height (w));
14794
14795 /* Perform the operation on the screen. */
14796 if (dvpos > 0)
14797 {
14798 /* Scroll last_unchanged_at_beg_row to the end of the
14799 window down dvpos lines. */
14800 set_terminal_window (end);
14801
14802 /* On dumb terminals delete dvpos lines at the end
14803 before inserting dvpos empty lines. */
14804 if (!scroll_region_ok)
14805 ins_del_lines (end - dvpos, -dvpos);
14806
14807 /* Insert dvpos empty lines in front of
14808 last_unchanged_at_beg_row. */
14809 ins_del_lines (from, dvpos);
14810 }
14811 else if (dvpos < 0)
14812 {
14813 /* Scroll up last_unchanged_at_beg_vpos to the end of
14814 the window to last_unchanged_at_beg_vpos - |dvpos|. */
14815 set_terminal_window (end);
14816
14817 /* Delete dvpos lines in front of
14818 last_unchanged_at_beg_vpos. ins_del_lines will set
14819 the cursor to the given vpos and emit |dvpos| delete
14820 line sequences. */
14821 ins_del_lines (from + dvpos, dvpos);
14822
14823 /* On a dumb terminal insert dvpos empty lines at the
14824 end. */
14825 if (!scroll_region_ok)
14826 ins_del_lines (end + dvpos, -dvpos);
14827 }
14828
14829 set_terminal_window (0);
14830 }
14831
14832 update_end (f);
14833 }
14834
14835 /* Shift reused rows of the current matrix to the right position.
14836 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
14837 text. */
14838 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14839 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
14840 if (dvpos < 0)
14841 {
14842 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
14843 bottom_vpos, dvpos);
14844 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
14845 bottom_vpos, 0);
14846 }
14847 else if (dvpos > 0)
14848 {
14849 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
14850 bottom_vpos, dvpos);
14851 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
14852 first_unchanged_at_end_vpos + dvpos, 0);
14853 }
14854
14855 /* For frame-based redisplay, make sure that current frame and window
14856 matrix are in sync with respect to glyph memory. */
14857 if (!FRAME_WINDOW_P (f))
14858 sync_frame_with_window_matrix_rows (w);
14859
14860 /* Adjust buffer positions in reused rows. */
14861 if (delta)
14862 increment_matrix_positions (current_matrix,
14863 first_unchanged_at_end_vpos + dvpos,
14864 bottom_vpos, delta, delta_bytes);
14865
14866 /* Adjust Y positions. */
14867 if (dy)
14868 shift_glyph_matrix (w, current_matrix,
14869 first_unchanged_at_end_vpos + dvpos,
14870 bottom_vpos, dy);
14871
14872 if (first_unchanged_at_end_row)
14873 {
14874 first_unchanged_at_end_row += dvpos;
14875 if (first_unchanged_at_end_row->y >= it.last_visible_y
14876 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
14877 first_unchanged_at_end_row = NULL;
14878 }
14879
14880 /* If scrolling up, there may be some lines to display at the end of
14881 the window. */
14882 last_text_row_at_end = NULL;
14883 if (dy < 0)
14884 {
14885 /* Scrolling up can leave for example a partially visible line
14886 at the end of the window to be redisplayed. */
14887 /* Set last_row to the glyph row in the current matrix where the
14888 window end line is found. It has been moved up or down in
14889 the matrix by dvpos. */
14890 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
14891 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
14892
14893 /* If last_row is the window end line, it should display text. */
14894 xassert (last_row->displays_text_p);
14895
14896 /* If window end line was partially visible before, begin
14897 displaying at that line. Otherwise begin displaying with the
14898 line following it. */
14899 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
14900 {
14901 init_to_row_start (&it, w, last_row);
14902 it.vpos = last_vpos;
14903 it.current_y = last_row->y;
14904 }
14905 else
14906 {
14907 init_to_row_end (&it, w, last_row);
14908 it.vpos = 1 + last_vpos;
14909 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
14910 ++last_row;
14911 }
14912
14913 /* We may start in a continuation line. If so, we have to
14914 get the right continuation_lines_width and current_x. */
14915 it.continuation_lines_width = last_row->continuation_lines_width;
14916 it.hpos = it.current_x = 0;
14917
14918 /* Display the rest of the lines at the window end. */
14919 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14920 while (it.current_y < it.last_visible_y
14921 && !fonts_changed_p)
14922 {
14923 /* Is it always sure that the display agrees with lines in
14924 the current matrix? I don't think so, so we mark rows
14925 displayed invalid in the current matrix by setting their
14926 enabled_p flag to zero. */
14927 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
14928 if (display_line (&it))
14929 last_text_row_at_end = it.glyph_row - 1;
14930 }
14931 }
14932
14933 /* Update window_end_pos and window_end_vpos. */
14934 if (first_unchanged_at_end_row
14935 && !last_text_row_at_end)
14936 {
14937 /* Window end line if one of the preserved rows from the current
14938 matrix. Set row to the last row displaying text in current
14939 matrix starting at first_unchanged_at_end_row, after
14940 scrolling. */
14941 xassert (first_unchanged_at_end_row->displays_text_p);
14942 row = find_last_row_displaying_text (w->current_matrix, &it,
14943 first_unchanged_at_end_row);
14944 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
14945
14946 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14947 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14948 w->window_end_vpos
14949 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
14950 xassert (w->window_end_bytepos >= 0);
14951 IF_DEBUG (debug_method_add (w, "A"));
14952 }
14953 else if (last_text_row_at_end)
14954 {
14955 w->window_end_pos
14956 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
14957 w->window_end_bytepos
14958 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
14959 w->window_end_vpos
14960 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
14961 xassert (w->window_end_bytepos >= 0);
14962 IF_DEBUG (debug_method_add (w, "B"));
14963 }
14964 else if (last_text_row)
14965 {
14966 /* We have displayed either to the end of the window or at the
14967 end of the window, i.e. the last row with text is to be found
14968 in the desired matrix. */
14969 w->window_end_pos
14970 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14971 w->window_end_bytepos
14972 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14973 w->window_end_vpos
14974 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
14975 xassert (w->window_end_bytepos >= 0);
14976 }
14977 else if (first_unchanged_at_end_row == NULL
14978 && last_text_row == NULL
14979 && last_text_row_at_end == NULL)
14980 {
14981 /* Displayed to end of window, but no line containing text was
14982 displayed. Lines were deleted at the end of the window. */
14983 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
14984 int vpos = XFASTINT (w->window_end_vpos);
14985 struct glyph_row *current_row = current_matrix->rows + vpos;
14986 struct glyph_row *desired_row = desired_matrix->rows + vpos;
14987
14988 for (row = NULL;
14989 row == NULL && vpos >= first_vpos;
14990 --vpos, --current_row, --desired_row)
14991 {
14992 if (desired_row->enabled_p)
14993 {
14994 if (desired_row->displays_text_p)
14995 row = desired_row;
14996 }
14997 else if (current_row->displays_text_p)
14998 row = current_row;
14999 }
15000
15001 xassert (row != NULL);
15002 w->window_end_vpos = make_number (vpos + 1);
15003 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15004 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15005 xassert (w->window_end_bytepos >= 0);
15006 IF_DEBUG (debug_method_add (w, "C"));
15007 }
15008 else
15009 abort ();
15010
15011 #if 0 /* This leads to problems, for instance when the cursor is
15012 at ZV, and the cursor line displays no text. */
15013 /* Disable rows below what's displayed in the window. This makes
15014 debugging easier. */
15015 enable_glyph_matrix_rows (current_matrix,
15016 XFASTINT (w->window_end_vpos) + 1,
15017 bottom_vpos, 0);
15018 #endif
15019
15020 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
15021 debug_end_vpos = XFASTINT (w->window_end_vpos));
15022
15023 /* Record that display has not been completed. */
15024 w->window_end_valid = Qnil;
15025 w->desired_matrix->no_scrolling_p = 1;
15026 return 3;
15027
15028 #undef GIVE_UP
15029 }
15030
15031
15032 \f
15033 /***********************************************************************
15034 More debugging support
15035 ***********************************************************************/
15036
15037 #if GLYPH_DEBUG
15038
15039 void dump_glyph_row P_ ((struct glyph_row *, int, int));
15040 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
15041 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
15042
15043
15044 /* Dump the contents of glyph matrix MATRIX on stderr.
15045
15046 GLYPHS 0 means don't show glyph contents.
15047 GLYPHS 1 means show glyphs in short form
15048 GLYPHS > 1 means show glyphs in long form. */
15049
15050 void
15051 dump_glyph_matrix (matrix, glyphs)
15052 struct glyph_matrix *matrix;
15053 int glyphs;
15054 {
15055 int i;
15056 for (i = 0; i < matrix->nrows; ++i)
15057 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
15058 }
15059
15060
15061 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
15062 the glyph row and area where the glyph comes from. */
15063
15064 void
15065 dump_glyph (row, glyph, area)
15066 struct glyph_row *row;
15067 struct glyph *glyph;
15068 int area;
15069 {
15070 if (glyph->type == CHAR_GLYPH)
15071 {
15072 fprintf (stderr,
15073 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15074 glyph - row->glyphs[TEXT_AREA],
15075 'C',
15076 glyph->charpos,
15077 (BUFFERP (glyph->object)
15078 ? 'B'
15079 : (STRINGP (glyph->object)
15080 ? 'S'
15081 : '-')),
15082 glyph->pixel_width,
15083 glyph->u.ch,
15084 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
15085 ? glyph->u.ch
15086 : '.'),
15087 glyph->face_id,
15088 glyph->left_box_line_p,
15089 glyph->right_box_line_p);
15090 }
15091 else if (glyph->type == STRETCH_GLYPH)
15092 {
15093 fprintf (stderr,
15094 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15095 glyph - row->glyphs[TEXT_AREA],
15096 'S',
15097 glyph->charpos,
15098 (BUFFERP (glyph->object)
15099 ? 'B'
15100 : (STRINGP (glyph->object)
15101 ? 'S'
15102 : '-')),
15103 glyph->pixel_width,
15104 0,
15105 '.',
15106 glyph->face_id,
15107 glyph->left_box_line_p,
15108 glyph->right_box_line_p);
15109 }
15110 else if (glyph->type == IMAGE_GLYPH)
15111 {
15112 fprintf (stderr,
15113 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15114 glyph - row->glyphs[TEXT_AREA],
15115 'I',
15116 glyph->charpos,
15117 (BUFFERP (glyph->object)
15118 ? 'B'
15119 : (STRINGP (glyph->object)
15120 ? 'S'
15121 : '-')),
15122 glyph->pixel_width,
15123 glyph->u.img_id,
15124 '.',
15125 glyph->face_id,
15126 glyph->left_box_line_p,
15127 glyph->right_box_line_p);
15128 }
15129 else if (glyph->type == COMPOSITE_GLYPH)
15130 {
15131 fprintf (stderr,
15132 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15133 glyph - row->glyphs[TEXT_AREA],
15134 '+',
15135 glyph->charpos,
15136 (BUFFERP (glyph->object)
15137 ? 'B'
15138 : (STRINGP (glyph->object)
15139 ? 'S'
15140 : '-')),
15141 glyph->pixel_width,
15142 glyph->u.cmp_id,
15143 '.',
15144 glyph->face_id,
15145 glyph->left_box_line_p,
15146 glyph->right_box_line_p);
15147 }
15148 }
15149
15150
15151 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
15152 GLYPHS 0 means don't show glyph contents.
15153 GLYPHS 1 means show glyphs in short form
15154 GLYPHS > 1 means show glyphs in long form. */
15155
15156 void
15157 dump_glyph_row (row, vpos, glyphs)
15158 struct glyph_row *row;
15159 int vpos, glyphs;
15160 {
15161 if (glyphs != 1)
15162 {
15163 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
15164 fprintf (stderr, "======================================================================\n");
15165
15166 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
15167 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
15168 vpos,
15169 MATRIX_ROW_START_CHARPOS (row),
15170 MATRIX_ROW_END_CHARPOS (row),
15171 row->used[TEXT_AREA],
15172 row->contains_overlapping_glyphs_p,
15173 row->enabled_p,
15174 row->truncated_on_left_p,
15175 row->truncated_on_right_p,
15176 row->continued_p,
15177 MATRIX_ROW_CONTINUATION_LINE_P (row),
15178 row->displays_text_p,
15179 row->ends_at_zv_p,
15180 row->fill_line_p,
15181 row->ends_in_middle_of_char_p,
15182 row->starts_in_middle_of_char_p,
15183 row->mouse_face_p,
15184 row->x,
15185 row->y,
15186 row->pixel_width,
15187 row->height,
15188 row->visible_height,
15189 row->ascent,
15190 row->phys_ascent);
15191 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
15192 row->end.overlay_string_index,
15193 row->continuation_lines_width);
15194 fprintf (stderr, "%9d %5d\n",
15195 CHARPOS (row->start.string_pos),
15196 CHARPOS (row->end.string_pos));
15197 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
15198 row->end.dpvec_index);
15199 }
15200
15201 if (glyphs > 1)
15202 {
15203 int area;
15204
15205 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15206 {
15207 struct glyph *glyph = row->glyphs[area];
15208 struct glyph *glyph_end = glyph + row->used[area];
15209
15210 /* Glyph for a line end in text. */
15211 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
15212 ++glyph_end;
15213
15214 if (glyph < glyph_end)
15215 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
15216
15217 for (; glyph < glyph_end; ++glyph)
15218 dump_glyph (row, glyph, area);
15219 }
15220 }
15221 else if (glyphs == 1)
15222 {
15223 int area;
15224
15225 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15226 {
15227 char *s = (char *) alloca (row->used[area] + 1);
15228 int i;
15229
15230 for (i = 0; i < row->used[area]; ++i)
15231 {
15232 struct glyph *glyph = row->glyphs[area] + i;
15233 if (glyph->type == CHAR_GLYPH
15234 && glyph->u.ch < 0x80
15235 && glyph->u.ch >= ' ')
15236 s[i] = glyph->u.ch;
15237 else
15238 s[i] = '.';
15239 }
15240
15241 s[i] = '\0';
15242 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
15243 }
15244 }
15245 }
15246
15247
15248 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
15249 Sdump_glyph_matrix, 0, 1, "p",
15250 doc: /* Dump the current matrix of the selected window to stderr.
15251 Shows contents of glyph row structures. With non-nil
15252 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
15253 glyphs in short form, otherwise show glyphs in long form. */)
15254 (glyphs)
15255 Lisp_Object glyphs;
15256 {
15257 struct window *w = XWINDOW (selected_window);
15258 struct buffer *buffer = XBUFFER (w->buffer);
15259
15260 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
15261 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
15262 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
15263 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
15264 fprintf (stderr, "=============================================\n");
15265 dump_glyph_matrix (w->current_matrix,
15266 NILP (glyphs) ? 0 : XINT (glyphs));
15267 return Qnil;
15268 }
15269
15270
15271 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
15272 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
15273 ()
15274 {
15275 struct frame *f = XFRAME (selected_frame);
15276 dump_glyph_matrix (f->current_matrix, 1);
15277 return Qnil;
15278 }
15279
15280
15281 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
15282 doc: /* Dump glyph row ROW to stderr.
15283 GLYPH 0 means don't dump glyphs.
15284 GLYPH 1 means dump glyphs in short form.
15285 GLYPH > 1 or omitted means dump glyphs in long form. */)
15286 (row, glyphs)
15287 Lisp_Object row, glyphs;
15288 {
15289 struct glyph_matrix *matrix;
15290 int vpos;
15291
15292 CHECK_NUMBER (row);
15293 matrix = XWINDOW (selected_window)->current_matrix;
15294 vpos = XINT (row);
15295 if (vpos >= 0 && vpos < matrix->nrows)
15296 dump_glyph_row (MATRIX_ROW (matrix, vpos),
15297 vpos,
15298 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15299 return Qnil;
15300 }
15301
15302
15303 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
15304 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
15305 GLYPH 0 means don't dump glyphs.
15306 GLYPH 1 means dump glyphs in short form.
15307 GLYPH > 1 or omitted means dump glyphs in long form. */)
15308 (row, glyphs)
15309 Lisp_Object row, glyphs;
15310 {
15311 struct frame *sf = SELECTED_FRAME ();
15312 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
15313 int vpos;
15314
15315 CHECK_NUMBER (row);
15316 vpos = XINT (row);
15317 if (vpos >= 0 && vpos < m->nrows)
15318 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
15319 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15320 return Qnil;
15321 }
15322
15323
15324 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
15325 doc: /* Toggle tracing of redisplay.
15326 With ARG, turn tracing on if and only if ARG is positive. */)
15327 (arg)
15328 Lisp_Object arg;
15329 {
15330 if (NILP (arg))
15331 trace_redisplay_p = !trace_redisplay_p;
15332 else
15333 {
15334 arg = Fprefix_numeric_value (arg);
15335 trace_redisplay_p = XINT (arg) > 0;
15336 }
15337
15338 return Qnil;
15339 }
15340
15341
15342 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
15343 doc: /* Like `format', but print result to stderr.
15344 usage: (trace-to-stderr STRING &rest OBJECTS) */)
15345 (nargs, args)
15346 int nargs;
15347 Lisp_Object *args;
15348 {
15349 Lisp_Object s = Fformat (nargs, args);
15350 fprintf (stderr, "%s", SDATA (s));
15351 return Qnil;
15352 }
15353
15354 #endif /* GLYPH_DEBUG */
15355
15356
15357 \f
15358 /***********************************************************************
15359 Building Desired Matrix Rows
15360 ***********************************************************************/
15361
15362 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
15363 Used for non-window-redisplay windows, and for windows w/o left fringe. */
15364
15365 static struct glyph_row *
15366 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
15367 struct window *w;
15368 Lisp_Object overlay_arrow_string;
15369 {
15370 struct frame *f = XFRAME (WINDOW_FRAME (w));
15371 struct buffer *buffer = XBUFFER (w->buffer);
15372 struct buffer *old = current_buffer;
15373 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
15374 int arrow_len = SCHARS (overlay_arrow_string);
15375 const unsigned char *arrow_end = arrow_string + arrow_len;
15376 const unsigned char *p;
15377 struct it it;
15378 int multibyte_p;
15379 int n_glyphs_before;
15380
15381 set_buffer_temp (buffer);
15382 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
15383 it.glyph_row->used[TEXT_AREA] = 0;
15384 SET_TEXT_POS (it.position, 0, 0);
15385
15386 multibyte_p = !NILP (buffer->enable_multibyte_characters);
15387 p = arrow_string;
15388 while (p < arrow_end)
15389 {
15390 Lisp_Object face, ilisp;
15391
15392 /* Get the next character. */
15393 if (multibyte_p)
15394 it.c = string_char_and_length (p, arrow_len, &it.len);
15395 else
15396 it.c = *p, it.len = 1;
15397 p += it.len;
15398
15399 /* Get its face. */
15400 ilisp = make_number (p - arrow_string);
15401 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
15402 it.face_id = compute_char_face (f, it.c, face);
15403
15404 /* Compute its width, get its glyphs. */
15405 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
15406 SET_TEXT_POS (it.position, -1, -1);
15407 PRODUCE_GLYPHS (&it);
15408
15409 /* If this character doesn't fit any more in the line, we have
15410 to remove some glyphs. */
15411 if (it.current_x > it.last_visible_x)
15412 {
15413 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
15414 break;
15415 }
15416 }
15417
15418 set_buffer_temp (old);
15419 return it.glyph_row;
15420 }
15421
15422
15423 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
15424 glyphs are only inserted for terminal frames since we can't really
15425 win with truncation glyphs when partially visible glyphs are
15426 involved. Which glyphs to insert is determined by
15427 produce_special_glyphs. */
15428
15429 static void
15430 insert_left_trunc_glyphs (it)
15431 struct it *it;
15432 {
15433 struct it truncate_it;
15434 struct glyph *from, *end, *to, *toend;
15435
15436 xassert (!FRAME_WINDOW_P (it->f));
15437
15438 /* Get the truncation glyphs. */
15439 truncate_it = *it;
15440 truncate_it.current_x = 0;
15441 truncate_it.face_id = DEFAULT_FACE_ID;
15442 truncate_it.glyph_row = &scratch_glyph_row;
15443 truncate_it.glyph_row->used[TEXT_AREA] = 0;
15444 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
15445 truncate_it.object = make_number (0);
15446 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
15447
15448 /* Overwrite glyphs from IT with truncation glyphs. */
15449 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15450 end = from + truncate_it.glyph_row->used[TEXT_AREA];
15451 to = it->glyph_row->glyphs[TEXT_AREA];
15452 toend = to + it->glyph_row->used[TEXT_AREA];
15453
15454 while (from < end)
15455 *to++ = *from++;
15456
15457 /* There may be padding glyphs left over. Overwrite them too. */
15458 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
15459 {
15460 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15461 while (from < end)
15462 *to++ = *from++;
15463 }
15464
15465 if (to > toend)
15466 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
15467 }
15468
15469
15470 /* Compute the pixel height and width of IT->glyph_row.
15471
15472 Most of the time, ascent and height of a display line will be equal
15473 to the max_ascent and max_height values of the display iterator
15474 structure. This is not the case if
15475
15476 1. We hit ZV without displaying anything. In this case, max_ascent
15477 and max_height will be zero.
15478
15479 2. We have some glyphs that don't contribute to the line height.
15480 (The glyph row flag contributes_to_line_height_p is for future
15481 pixmap extensions).
15482
15483 The first case is easily covered by using default values because in
15484 these cases, the line height does not really matter, except that it
15485 must not be zero. */
15486
15487 static void
15488 compute_line_metrics (it)
15489 struct it *it;
15490 {
15491 struct glyph_row *row = it->glyph_row;
15492 int area, i;
15493
15494 if (FRAME_WINDOW_P (it->f))
15495 {
15496 int i, min_y, max_y;
15497
15498 /* The line may consist of one space only, that was added to
15499 place the cursor on it. If so, the row's height hasn't been
15500 computed yet. */
15501 if (row->height == 0)
15502 {
15503 if (it->max_ascent + it->max_descent == 0)
15504 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
15505 row->ascent = it->max_ascent;
15506 row->height = it->max_ascent + it->max_descent;
15507 row->phys_ascent = it->max_phys_ascent;
15508 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15509 row->extra_line_spacing = it->max_extra_line_spacing;
15510 }
15511
15512 /* Compute the width of this line. */
15513 row->pixel_width = row->x;
15514 for (i = 0; i < row->used[TEXT_AREA]; ++i)
15515 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
15516
15517 xassert (row->pixel_width >= 0);
15518 xassert (row->ascent >= 0 && row->height > 0);
15519
15520 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
15521 || MATRIX_ROW_OVERLAPS_PRED_P (row));
15522
15523 /* If first line's physical ascent is larger than its logical
15524 ascent, use the physical ascent, and make the row taller.
15525 This makes accented characters fully visible. */
15526 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
15527 && row->phys_ascent > row->ascent)
15528 {
15529 row->height += row->phys_ascent - row->ascent;
15530 row->ascent = row->phys_ascent;
15531 }
15532
15533 /* Compute how much of the line is visible. */
15534 row->visible_height = row->height;
15535
15536 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
15537 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
15538
15539 if (row->y < min_y)
15540 row->visible_height -= min_y - row->y;
15541 if (row->y + row->height > max_y)
15542 row->visible_height -= row->y + row->height - max_y;
15543 }
15544 else
15545 {
15546 row->pixel_width = row->used[TEXT_AREA];
15547 if (row->continued_p)
15548 row->pixel_width -= it->continuation_pixel_width;
15549 else if (row->truncated_on_right_p)
15550 row->pixel_width -= it->truncation_pixel_width;
15551 row->ascent = row->phys_ascent = 0;
15552 row->height = row->phys_height = row->visible_height = 1;
15553 row->extra_line_spacing = 0;
15554 }
15555
15556 /* Compute a hash code for this row. */
15557 row->hash = 0;
15558 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15559 for (i = 0; i < row->used[area]; ++i)
15560 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
15561 + row->glyphs[area][i].u.val
15562 + row->glyphs[area][i].face_id
15563 + row->glyphs[area][i].padding_p
15564 + (row->glyphs[area][i].type << 2));
15565
15566 it->max_ascent = it->max_descent = 0;
15567 it->max_phys_ascent = it->max_phys_descent = 0;
15568 }
15569
15570
15571 /* Append one space to the glyph row of iterator IT if doing a
15572 window-based redisplay. The space has the same face as
15573 IT->face_id. Value is non-zero if a space was added.
15574
15575 This function is called to make sure that there is always one glyph
15576 at the end of a glyph row that the cursor can be set on under
15577 window-systems. (If there weren't such a glyph we would not know
15578 how wide and tall a box cursor should be displayed).
15579
15580 At the same time this space let's a nicely handle clearing to the
15581 end of the line if the row ends in italic text. */
15582
15583 static int
15584 append_space_for_newline (it, default_face_p)
15585 struct it *it;
15586 int default_face_p;
15587 {
15588 if (FRAME_WINDOW_P (it->f))
15589 {
15590 int n = it->glyph_row->used[TEXT_AREA];
15591
15592 if (it->glyph_row->glyphs[TEXT_AREA] + n
15593 < it->glyph_row->glyphs[1 + TEXT_AREA])
15594 {
15595 /* Save some values that must not be changed.
15596 Must save IT->c and IT->len because otherwise
15597 ITERATOR_AT_END_P wouldn't work anymore after
15598 append_space_for_newline has been called. */
15599 enum display_element_type saved_what = it->what;
15600 int saved_c = it->c, saved_len = it->len;
15601 int saved_x = it->current_x;
15602 int saved_face_id = it->face_id;
15603 struct text_pos saved_pos;
15604 Lisp_Object saved_object;
15605 struct face *face;
15606
15607 saved_object = it->object;
15608 saved_pos = it->position;
15609
15610 it->what = IT_CHARACTER;
15611 bzero (&it->position, sizeof it->position);
15612 it->object = make_number (0);
15613 it->c = ' ';
15614 it->len = 1;
15615
15616 if (default_face_p)
15617 it->face_id = DEFAULT_FACE_ID;
15618 else if (it->face_before_selective_p)
15619 it->face_id = it->saved_face_id;
15620 face = FACE_FROM_ID (it->f, it->face_id);
15621 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
15622
15623 PRODUCE_GLYPHS (it);
15624
15625 it->override_ascent = -1;
15626 it->constrain_row_ascent_descent_p = 0;
15627 it->current_x = saved_x;
15628 it->object = saved_object;
15629 it->position = saved_pos;
15630 it->what = saved_what;
15631 it->face_id = saved_face_id;
15632 it->len = saved_len;
15633 it->c = saved_c;
15634 return 1;
15635 }
15636 }
15637
15638 return 0;
15639 }
15640
15641
15642 /* Extend the face of the last glyph in the text area of IT->glyph_row
15643 to the end of the display line. Called from display_line.
15644 If the glyph row is empty, add a space glyph to it so that we
15645 know the face to draw. Set the glyph row flag fill_line_p. */
15646
15647 static void
15648 extend_face_to_end_of_line (it)
15649 struct it *it;
15650 {
15651 struct face *face;
15652 struct frame *f = it->f;
15653
15654 /* If line is already filled, do nothing. */
15655 if (it->current_x >= it->last_visible_x)
15656 return;
15657
15658 /* Face extension extends the background and box of IT->face_id
15659 to the end of the line. If the background equals the background
15660 of the frame, we don't have to do anything. */
15661 if (it->face_before_selective_p)
15662 face = FACE_FROM_ID (it->f, it->saved_face_id);
15663 else
15664 face = FACE_FROM_ID (f, it->face_id);
15665
15666 if (FRAME_WINDOW_P (f)
15667 && it->glyph_row->displays_text_p
15668 && face->box == FACE_NO_BOX
15669 && face->background == FRAME_BACKGROUND_PIXEL (f)
15670 && !face->stipple)
15671 return;
15672
15673 /* Set the glyph row flag indicating that the face of the last glyph
15674 in the text area has to be drawn to the end of the text area. */
15675 it->glyph_row->fill_line_p = 1;
15676
15677 /* If current character of IT is not ASCII, make sure we have the
15678 ASCII face. This will be automatically undone the next time
15679 get_next_display_element returns a multibyte character. Note
15680 that the character will always be single byte in unibyte text. */
15681 if (!SINGLE_BYTE_CHAR_P (it->c))
15682 {
15683 it->face_id = FACE_FOR_CHAR (f, face, 0);
15684 }
15685
15686 if (FRAME_WINDOW_P (f))
15687 {
15688 /* If the row is empty, add a space with the current face of IT,
15689 so that we know which face to draw. */
15690 if (it->glyph_row->used[TEXT_AREA] == 0)
15691 {
15692 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
15693 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
15694 it->glyph_row->used[TEXT_AREA] = 1;
15695 }
15696 }
15697 else
15698 {
15699 /* Save some values that must not be changed. */
15700 int saved_x = it->current_x;
15701 struct text_pos saved_pos;
15702 Lisp_Object saved_object;
15703 enum display_element_type saved_what = it->what;
15704 int saved_face_id = it->face_id;
15705
15706 saved_object = it->object;
15707 saved_pos = it->position;
15708
15709 it->what = IT_CHARACTER;
15710 bzero (&it->position, sizeof it->position);
15711 it->object = make_number (0);
15712 it->c = ' ';
15713 it->len = 1;
15714 it->face_id = face->id;
15715
15716 PRODUCE_GLYPHS (it);
15717
15718 while (it->current_x <= it->last_visible_x)
15719 PRODUCE_GLYPHS (it);
15720
15721 /* Don't count these blanks really. It would let us insert a left
15722 truncation glyph below and make us set the cursor on them, maybe. */
15723 it->current_x = saved_x;
15724 it->object = saved_object;
15725 it->position = saved_pos;
15726 it->what = saved_what;
15727 it->face_id = saved_face_id;
15728 }
15729 }
15730
15731
15732 /* Value is non-zero if text starting at CHARPOS in current_buffer is
15733 trailing whitespace. */
15734
15735 static int
15736 trailing_whitespace_p (charpos)
15737 int charpos;
15738 {
15739 int bytepos = CHAR_TO_BYTE (charpos);
15740 int c = 0;
15741
15742 while (bytepos < ZV_BYTE
15743 && (c = FETCH_CHAR (bytepos),
15744 c == ' ' || c == '\t'))
15745 ++bytepos;
15746
15747 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
15748 {
15749 if (bytepos != PT_BYTE)
15750 return 1;
15751 }
15752 return 0;
15753 }
15754
15755
15756 /* Highlight trailing whitespace, if any, in ROW. */
15757
15758 void
15759 highlight_trailing_whitespace (f, row)
15760 struct frame *f;
15761 struct glyph_row *row;
15762 {
15763 int used = row->used[TEXT_AREA];
15764
15765 if (used)
15766 {
15767 struct glyph *start = row->glyphs[TEXT_AREA];
15768 struct glyph *glyph = start + used - 1;
15769
15770 /* Skip over glyphs inserted to display the cursor at the
15771 end of a line, for extending the face of the last glyph
15772 to the end of the line on terminals, and for truncation
15773 and continuation glyphs. */
15774 while (glyph >= start
15775 && glyph->type == CHAR_GLYPH
15776 && INTEGERP (glyph->object))
15777 --glyph;
15778
15779 /* If last glyph is a space or stretch, and it's trailing
15780 whitespace, set the face of all trailing whitespace glyphs in
15781 IT->glyph_row to `trailing-whitespace'. */
15782 if (glyph >= start
15783 && BUFFERP (glyph->object)
15784 && (glyph->type == STRETCH_GLYPH
15785 || (glyph->type == CHAR_GLYPH
15786 && glyph->u.ch == ' '))
15787 && trailing_whitespace_p (glyph->charpos))
15788 {
15789 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
15790 if (face_id < 0)
15791 return;
15792
15793 while (glyph >= start
15794 && BUFFERP (glyph->object)
15795 && (glyph->type == STRETCH_GLYPH
15796 || (glyph->type == CHAR_GLYPH
15797 && glyph->u.ch == ' ')))
15798 (glyph--)->face_id = face_id;
15799 }
15800 }
15801 }
15802
15803
15804 /* Value is non-zero if glyph row ROW in window W should be
15805 used to hold the cursor. */
15806
15807 static int
15808 cursor_row_p (w, row)
15809 struct window *w;
15810 struct glyph_row *row;
15811 {
15812 int cursor_row_p = 1;
15813
15814 if (PT == MATRIX_ROW_END_CHARPOS (row))
15815 {
15816 /* If the row ends with a newline from a string, we don't want
15817 the cursor there, but we still want it at the start of the
15818 string if the string starts in this row.
15819 If the row is continued it doesn't end in a newline. */
15820 if (CHARPOS (row->end.string_pos) >= 0)
15821 cursor_row_p = (row->continued_p
15822 || PT >= MATRIX_ROW_START_CHARPOS (row));
15823 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15824 {
15825 /* If the row ends in middle of a real character,
15826 and the line is continued, we want the cursor here.
15827 That's because MATRIX_ROW_END_CHARPOS would equal
15828 PT if PT is before the character. */
15829 if (!row->ends_in_ellipsis_p)
15830 cursor_row_p = row->continued_p;
15831 else
15832 /* If the row ends in an ellipsis, then
15833 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
15834 We want that position to be displayed after the ellipsis. */
15835 cursor_row_p = 0;
15836 }
15837 /* If the row ends at ZV, display the cursor at the end of that
15838 row instead of at the start of the row below. */
15839 else if (row->ends_at_zv_p)
15840 cursor_row_p = 1;
15841 else
15842 cursor_row_p = 0;
15843 }
15844
15845 return cursor_row_p;
15846 }
15847
15848
15849 /* Construct the glyph row IT->glyph_row in the desired matrix of
15850 IT->w from text at the current position of IT. See dispextern.h
15851 for an overview of struct it. Value is non-zero if
15852 IT->glyph_row displays text, as opposed to a line displaying ZV
15853 only. */
15854
15855 static int
15856 display_line (it)
15857 struct it *it;
15858 {
15859 struct glyph_row *row = it->glyph_row;
15860 Lisp_Object overlay_arrow_string;
15861
15862 /* We always start displaying at hpos zero even if hscrolled. */
15863 xassert (it->hpos == 0 && it->current_x == 0);
15864
15865 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
15866 >= it->w->desired_matrix->nrows)
15867 {
15868 it->w->nrows_scale_factor++;
15869 fonts_changed_p = 1;
15870 return 0;
15871 }
15872
15873 /* Is IT->w showing the region? */
15874 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
15875
15876 /* Clear the result glyph row and enable it. */
15877 prepare_desired_row (row);
15878
15879 row->y = it->current_y;
15880 row->start = it->start;
15881 row->continuation_lines_width = it->continuation_lines_width;
15882 row->displays_text_p = 1;
15883 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
15884 it->starts_in_middle_of_char_p = 0;
15885
15886 /* Arrange the overlays nicely for our purposes. Usually, we call
15887 display_line on only one line at a time, in which case this
15888 can't really hurt too much, or we call it on lines which appear
15889 one after another in the buffer, in which case all calls to
15890 recenter_overlay_lists but the first will be pretty cheap. */
15891 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
15892
15893 /* Move over display elements that are not visible because we are
15894 hscrolled. This may stop at an x-position < IT->first_visible_x
15895 if the first glyph is partially visible or if we hit a line end. */
15896 if (it->current_x < it->first_visible_x)
15897 {
15898 move_it_in_display_line_to (it, ZV, it->first_visible_x,
15899 MOVE_TO_POS | MOVE_TO_X);
15900 }
15901
15902 /* Get the initial row height. This is either the height of the
15903 text hscrolled, if there is any, or zero. */
15904 row->ascent = it->max_ascent;
15905 row->height = it->max_ascent + it->max_descent;
15906 row->phys_ascent = it->max_phys_ascent;
15907 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15908 row->extra_line_spacing = it->max_extra_line_spacing;
15909
15910 /* Loop generating characters. The loop is left with IT on the next
15911 character to display. */
15912 while (1)
15913 {
15914 int n_glyphs_before, hpos_before, x_before;
15915 int x, i, nglyphs;
15916 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
15917
15918 /* Retrieve the next thing to display. Value is zero if end of
15919 buffer reached. */
15920 if (!get_next_display_element (it))
15921 {
15922 /* Maybe add a space at the end of this line that is used to
15923 display the cursor there under X. Set the charpos of the
15924 first glyph of blank lines not corresponding to any text
15925 to -1. */
15926 #ifdef HAVE_WINDOW_SYSTEM
15927 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15928 row->exact_window_width_line_p = 1;
15929 else
15930 #endif /* HAVE_WINDOW_SYSTEM */
15931 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
15932 || row->used[TEXT_AREA] == 0)
15933 {
15934 row->glyphs[TEXT_AREA]->charpos = -1;
15935 row->displays_text_p = 0;
15936
15937 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
15938 && (!MINI_WINDOW_P (it->w)
15939 || (minibuf_level && EQ (it->window, minibuf_window))))
15940 row->indicate_empty_line_p = 1;
15941 }
15942
15943 it->continuation_lines_width = 0;
15944 row->ends_at_zv_p = 1;
15945 break;
15946 }
15947
15948 /* Now, get the metrics of what we want to display. This also
15949 generates glyphs in `row' (which is IT->glyph_row). */
15950 n_glyphs_before = row->used[TEXT_AREA];
15951 x = it->current_x;
15952
15953 /* Remember the line height so far in case the next element doesn't
15954 fit on the line. */
15955 if (!it->truncate_lines_p)
15956 {
15957 ascent = it->max_ascent;
15958 descent = it->max_descent;
15959 phys_ascent = it->max_phys_ascent;
15960 phys_descent = it->max_phys_descent;
15961 }
15962
15963 PRODUCE_GLYPHS (it);
15964
15965 /* If this display element was in marginal areas, continue with
15966 the next one. */
15967 if (it->area != TEXT_AREA)
15968 {
15969 row->ascent = max (row->ascent, it->max_ascent);
15970 row->height = max (row->height, it->max_ascent + it->max_descent);
15971 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15972 row->phys_height = max (row->phys_height,
15973 it->max_phys_ascent + it->max_phys_descent);
15974 row->extra_line_spacing = max (row->extra_line_spacing,
15975 it->max_extra_line_spacing);
15976 set_iterator_to_next (it, 1);
15977 continue;
15978 }
15979
15980 /* Does the display element fit on the line? If we truncate
15981 lines, we should draw past the right edge of the window. If
15982 we don't truncate, we want to stop so that we can display the
15983 continuation glyph before the right margin. If lines are
15984 continued, there are two possible strategies for characters
15985 resulting in more than 1 glyph (e.g. tabs): Display as many
15986 glyphs as possible in this line and leave the rest for the
15987 continuation line, or display the whole element in the next
15988 line. Original redisplay did the former, so we do it also. */
15989 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
15990 hpos_before = it->hpos;
15991 x_before = x;
15992
15993 if (/* Not a newline. */
15994 nglyphs > 0
15995 /* Glyphs produced fit entirely in the line. */
15996 && it->current_x < it->last_visible_x)
15997 {
15998 it->hpos += nglyphs;
15999 row->ascent = max (row->ascent, it->max_ascent);
16000 row->height = max (row->height, it->max_ascent + it->max_descent);
16001 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16002 row->phys_height = max (row->phys_height,
16003 it->max_phys_ascent + it->max_phys_descent);
16004 row->extra_line_spacing = max (row->extra_line_spacing,
16005 it->max_extra_line_spacing);
16006 if (it->current_x - it->pixel_width < it->first_visible_x)
16007 row->x = x - it->first_visible_x;
16008 }
16009 else
16010 {
16011 int new_x;
16012 struct glyph *glyph;
16013
16014 for (i = 0; i < nglyphs; ++i, x = new_x)
16015 {
16016 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16017 new_x = x + glyph->pixel_width;
16018
16019 if (/* Lines are continued. */
16020 !it->truncate_lines_p
16021 && (/* Glyph doesn't fit on the line. */
16022 new_x > it->last_visible_x
16023 /* Or it fits exactly on a window system frame. */
16024 || (new_x == it->last_visible_x
16025 && FRAME_WINDOW_P (it->f))))
16026 {
16027 /* End of a continued line. */
16028
16029 if (it->hpos == 0
16030 || (new_x == it->last_visible_x
16031 && FRAME_WINDOW_P (it->f)))
16032 {
16033 /* Current glyph is the only one on the line or
16034 fits exactly on the line. We must continue
16035 the line because we can't draw the cursor
16036 after the glyph. */
16037 row->continued_p = 1;
16038 it->current_x = new_x;
16039 it->continuation_lines_width += new_x;
16040 ++it->hpos;
16041 if (i == nglyphs - 1)
16042 {
16043 set_iterator_to_next (it, 1);
16044 #ifdef HAVE_WINDOW_SYSTEM
16045 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16046 {
16047 if (!get_next_display_element (it))
16048 {
16049 row->exact_window_width_line_p = 1;
16050 it->continuation_lines_width = 0;
16051 row->continued_p = 0;
16052 row->ends_at_zv_p = 1;
16053 }
16054 else if (ITERATOR_AT_END_OF_LINE_P (it))
16055 {
16056 row->continued_p = 0;
16057 row->exact_window_width_line_p = 1;
16058 }
16059 }
16060 #endif /* HAVE_WINDOW_SYSTEM */
16061 }
16062 }
16063 else if (CHAR_GLYPH_PADDING_P (*glyph)
16064 && !FRAME_WINDOW_P (it->f))
16065 {
16066 /* A padding glyph that doesn't fit on this line.
16067 This means the whole character doesn't fit
16068 on the line. */
16069 row->used[TEXT_AREA] = n_glyphs_before;
16070
16071 /* Fill the rest of the row with continuation
16072 glyphs like in 20.x. */
16073 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
16074 < row->glyphs[1 + TEXT_AREA])
16075 produce_special_glyphs (it, IT_CONTINUATION);
16076
16077 row->continued_p = 1;
16078 it->current_x = x_before;
16079 it->continuation_lines_width += x_before;
16080
16081 /* Restore the height to what it was before the
16082 element not fitting on the line. */
16083 it->max_ascent = ascent;
16084 it->max_descent = descent;
16085 it->max_phys_ascent = phys_ascent;
16086 it->max_phys_descent = phys_descent;
16087 }
16088 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
16089 {
16090 /* A TAB that extends past the right edge of the
16091 window. This produces a single glyph on
16092 window system frames. We leave the glyph in
16093 this row and let it fill the row, but don't
16094 consume the TAB. */
16095 it->continuation_lines_width += it->last_visible_x;
16096 row->ends_in_middle_of_char_p = 1;
16097 row->continued_p = 1;
16098 glyph->pixel_width = it->last_visible_x - x;
16099 it->starts_in_middle_of_char_p = 1;
16100 }
16101 else
16102 {
16103 /* Something other than a TAB that draws past
16104 the right edge of the window. Restore
16105 positions to values before the element. */
16106 row->used[TEXT_AREA] = n_glyphs_before + i;
16107
16108 /* Display continuation glyphs. */
16109 if (!FRAME_WINDOW_P (it->f))
16110 produce_special_glyphs (it, IT_CONTINUATION);
16111 row->continued_p = 1;
16112
16113 it->current_x = x_before;
16114 it->continuation_lines_width += x;
16115 extend_face_to_end_of_line (it);
16116
16117 if (nglyphs > 1 && i > 0)
16118 {
16119 row->ends_in_middle_of_char_p = 1;
16120 it->starts_in_middle_of_char_p = 1;
16121 }
16122
16123 /* Restore the height to what it was before the
16124 element not fitting on the line. */
16125 it->max_ascent = ascent;
16126 it->max_descent = descent;
16127 it->max_phys_ascent = phys_ascent;
16128 it->max_phys_descent = phys_descent;
16129 }
16130
16131 break;
16132 }
16133 else if (new_x > it->first_visible_x)
16134 {
16135 /* Increment number of glyphs actually displayed. */
16136 ++it->hpos;
16137
16138 if (x < it->first_visible_x)
16139 /* Glyph is partially visible, i.e. row starts at
16140 negative X position. */
16141 row->x = x - it->first_visible_x;
16142 }
16143 else
16144 {
16145 /* Glyph is completely off the left margin of the
16146 window. This should not happen because of the
16147 move_it_in_display_line at the start of this
16148 function, unless the text display area of the
16149 window is empty. */
16150 xassert (it->first_visible_x <= it->last_visible_x);
16151 }
16152 }
16153
16154 row->ascent = max (row->ascent, it->max_ascent);
16155 row->height = max (row->height, it->max_ascent + it->max_descent);
16156 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16157 row->phys_height = max (row->phys_height,
16158 it->max_phys_ascent + it->max_phys_descent);
16159 row->extra_line_spacing = max (row->extra_line_spacing,
16160 it->max_extra_line_spacing);
16161
16162 /* End of this display line if row is continued. */
16163 if (row->continued_p || row->ends_at_zv_p)
16164 break;
16165 }
16166
16167 at_end_of_line:
16168 /* Is this a line end? If yes, we're also done, after making
16169 sure that a non-default face is extended up to the right
16170 margin of the window. */
16171 if (ITERATOR_AT_END_OF_LINE_P (it))
16172 {
16173 int used_before = row->used[TEXT_AREA];
16174
16175 row->ends_in_newline_from_string_p = STRINGP (it->object);
16176
16177 #ifdef HAVE_WINDOW_SYSTEM
16178 /* Add a space at the end of the line that is used to
16179 display the cursor there. */
16180 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16181 append_space_for_newline (it, 0);
16182 #endif /* HAVE_WINDOW_SYSTEM */
16183
16184 /* Extend the face to the end of the line. */
16185 extend_face_to_end_of_line (it);
16186
16187 /* Make sure we have the position. */
16188 if (used_before == 0)
16189 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
16190
16191 /* Consume the line end. This skips over invisible lines. */
16192 set_iterator_to_next (it, 1);
16193 it->continuation_lines_width = 0;
16194 break;
16195 }
16196
16197 /* Proceed with next display element. Note that this skips
16198 over lines invisible because of selective display. */
16199 set_iterator_to_next (it, 1);
16200
16201 /* If we truncate lines, we are done when the last displayed
16202 glyphs reach past the right margin of the window. */
16203 if (it->truncate_lines_p
16204 && (FRAME_WINDOW_P (it->f)
16205 ? (it->current_x >= it->last_visible_x)
16206 : (it->current_x > it->last_visible_x)))
16207 {
16208 /* Maybe add truncation glyphs. */
16209 if (!FRAME_WINDOW_P (it->f))
16210 {
16211 int i, n;
16212
16213 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16214 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16215 break;
16216
16217 for (n = row->used[TEXT_AREA]; i < n; ++i)
16218 {
16219 row->used[TEXT_AREA] = i;
16220 produce_special_glyphs (it, IT_TRUNCATION);
16221 }
16222 }
16223 #ifdef HAVE_WINDOW_SYSTEM
16224 else
16225 {
16226 /* Don't truncate if we can overflow newline into fringe. */
16227 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16228 {
16229 if (!get_next_display_element (it))
16230 {
16231 it->continuation_lines_width = 0;
16232 row->ends_at_zv_p = 1;
16233 row->exact_window_width_line_p = 1;
16234 break;
16235 }
16236 if (ITERATOR_AT_END_OF_LINE_P (it))
16237 {
16238 row->exact_window_width_line_p = 1;
16239 goto at_end_of_line;
16240 }
16241 }
16242 }
16243 #endif /* HAVE_WINDOW_SYSTEM */
16244
16245 row->truncated_on_right_p = 1;
16246 it->continuation_lines_width = 0;
16247 reseat_at_next_visible_line_start (it, 0);
16248 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
16249 it->hpos = hpos_before;
16250 it->current_x = x_before;
16251 break;
16252 }
16253 }
16254
16255 /* If line is not empty and hscrolled, maybe insert truncation glyphs
16256 at the left window margin. */
16257 if (it->first_visible_x
16258 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
16259 {
16260 if (!FRAME_WINDOW_P (it->f))
16261 insert_left_trunc_glyphs (it);
16262 row->truncated_on_left_p = 1;
16263 }
16264
16265 /* If the start of this line is the overlay arrow-position, then
16266 mark this glyph row as the one containing the overlay arrow.
16267 This is clearly a mess with variable size fonts. It would be
16268 better to let it be displayed like cursors under X. */
16269 if ((row->displays_text_p || !overlay_arrow_seen)
16270 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
16271 !NILP (overlay_arrow_string)))
16272 {
16273 /* Overlay arrow in window redisplay is a fringe bitmap. */
16274 if (STRINGP (overlay_arrow_string))
16275 {
16276 struct glyph_row *arrow_row
16277 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
16278 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
16279 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
16280 struct glyph *p = row->glyphs[TEXT_AREA];
16281 struct glyph *p2, *end;
16282
16283 /* Copy the arrow glyphs. */
16284 while (glyph < arrow_end)
16285 *p++ = *glyph++;
16286
16287 /* Throw away padding glyphs. */
16288 p2 = p;
16289 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16290 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
16291 ++p2;
16292 if (p2 > p)
16293 {
16294 while (p2 < end)
16295 *p++ = *p2++;
16296 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
16297 }
16298 }
16299 else
16300 {
16301 xassert (INTEGERP (overlay_arrow_string));
16302 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
16303 }
16304 overlay_arrow_seen = 1;
16305 }
16306
16307 /* Compute pixel dimensions of this line. */
16308 compute_line_metrics (it);
16309
16310 /* Remember the position at which this line ends. */
16311 row->end = it->current;
16312
16313 /* Record whether this row ends inside an ellipsis. */
16314 row->ends_in_ellipsis_p
16315 = (it->method == GET_FROM_DISPLAY_VECTOR
16316 && it->ellipsis_p);
16317
16318 /* Save fringe bitmaps in this row. */
16319 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
16320 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
16321 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
16322 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
16323
16324 it->left_user_fringe_bitmap = 0;
16325 it->left_user_fringe_face_id = 0;
16326 it->right_user_fringe_bitmap = 0;
16327 it->right_user_fringe_face_id = 0;
16328
16329 /* Maybe set the cursor. */
16330 if (it->w->cursor.vpos < 0
16331 && PT >= MATRIX_ROW_START_CHARPOS (row)
16332 && PT <= MATRIX_ROW_END_CHARPOS (row)
16333 && cursor_row_p (it->w, row))
16334 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
16335
16336 /* Highlight trailing whitespace. */
16337 if (!NILP (Vshow_trailing_whitespace))
16338 highlight_trailing_whitespace (it->f, it->glyph_row);
16339
16340 /* Prepare for the next line. This line starts horizontally at (X
16341 HPOS) = (0 0). Vertical positions are incremented. As a
16342 convenience for the caller, IT->glyph_row is set to the next
16343 row to be used. */
16344 it->current_x = it->hpos = 0;
16345 it->current_y += row->height;
16346 ++it->vpos;
16347 ++it->glyph_row;
16348 it->start = it->current;
16349 return row->displays_text_p;
16350 }
16351
16352
16353 \f
16354 /***********************************************************************
16355 Menu Bar
16356 ***********************************************************************/
16357
16358 /* Redisplay the menu bar in the frame for window W.
16359
16360 The menu bar of X frames that don't have X toolkit support is
16361 displayed in a special window W->frame->menu_bar_window.
16362
16363 The menu bar of terminal frames is treated specially as far as
16364 glyph matrices are concerned. Menu bar lines are not part of
16365 windows, so the update is done directly on the frame matrix rows
16366 for the menu bar. */
16367
16368 static void
16369 display_menu_bar (w)
16370 struct window *w;
16371 {
16372 struct frame *f = XFRAME (WINDOW_FRAME (w));
16373 struct it it;
16374 Lisp_Object items;
16375 int i;
16376
16377 /* Don't do all this for graphical frames. */
16378 #ifdef HAVE_NTGUI
16379 if (!NILP (Vwindow_system))
16380 return;
16381 #endif
16382 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
16383 if (FRAME_X_P (f))
16384 return;
16385 #endif
16386 #ifdef MAC_OS
16387 if (FRAME_MAC_P (f))
16388 return;
16389 #endif
16390
16391 #ifdef USE_X_TOOLKIT
16392 xassert (!FRAME_WINDOW_P (f));
16393 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
16394 it.first_visible_x = 0;
16395 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16396 #else /* not USE_X_TOOLKIT */
16397 if (FRAME_WINDOW_P (f))
16398 {
16399 /* Menu bar lines are displayed in the desired matrix of the
16400 dummy window menu_bar_window. */
16401 struct window *menu_w;
16402 xassert (WINDOWP (f->menu_bar_window));
16403 menu_w = XWINDOW (f->menu_bar_window);
16404 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
16405 MENU_FACE_ID);
16406 it.first_visible_x = 0;
16407 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16408 }
16409 else
16410 {
16411 /* This is a TTY frame, i.e. character hpos/vpos are used as
16412 pixel x/y. */
16413 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
16414 MENU_FACE_ID);
16415 it.first_visible_x = 0;
16416 it.last_visible_x = FRAME_COLS (f);
16417 }
16418 #endif /* not USE_X_TOOLKIT */
16419
16420 if (! mode_line_inverse_video)
16421 /* Force the menu-bar to be displayed in the default face. */
16422 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16423
16424 /* Clear all rows of the menu bar. */
16425 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
16426 {
16427 struct glyph_row *row = it.glyph_row + i;
16428 clear_glyph_row (row);
16429 row->enabled_p = 1;
16430 row->full_width_p = 1;
16431 }
16432
16433 /* Display all items of the menu bar. */
16434 items = FRAME_MENU_BAR_ITEMS (it.f);
16435 for (i = 0; i < XVECTOR (items)->size; i += 4)
16436 {
16437 Lisp_Object string;
16438
16439 /* Stop at nil string. */
16440 string = AREF (items, i + 1);
16441 if (NILP (string))
16442 break;
16443
16444 /* Remember where item was displayed. */
16445 AREF (items, i + 3) = make_number (it.hpos);
16446
16447 /* Display the item, pad with one space. */
16448 if (it.current_x < it.last_visible_x)
16449 display_string (NULL, string, Qnil, 0, 0, &it,
16450 SCHARS (string) + 1, 0, 0, -1);
16451 }
16452
16453 /* Fill out the line with spaces. */
16454 if (it.current_x < it.last_visible_x)
16455 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
16456
16457 /* Compute the total height of the lines. */
16458 compute_line_metrics (&it);
16459 }
16460
16461
16462 \f
16463 /***********************************************************************
16464 Mode Line
16465 ***********************************************************************/
16466
16467 /* Redisplay mode lines in the window tree whose root is WINDOW. If
16468 FORCE is non-zero, redisplay mode lines unconditionally.
16469 Otherwise, redisplay only mode lines that are garbaged. Value is
16470 the number of windows whose mode lines were redisplayed. */
16471
16472 static int
16473 redisplay_mode_lines (window, force)
16474 Lisp_Object window;
16475 int force;
16476 {
16477 int nwindows = 0;
16478
16479 while (!NILP (window))
16480 {
16481 struct window *w = XWINDOW (window);
16482
16483 if (WINDOWP (w->hchild))
16484 nwindows += redisplay_mode_lines (w->hchild, force);
16485 else if (WINDOWP (w->vchild))
16486 nwindows += redisplay_mode_lines (w->vchild, force);
16487 else if (force
16488 || FRAME_GARBAGED_P (XFRAME (w->frame))
16489 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
16490 {
16491 struct text_pos lpoint;
16492 struct buffer *old = current_buffer;
16493
16494 /* Set the window's buffer for the mode line display. */
16495 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16496 set_buffer_internal_1 (XBUFFER (w->buffer));
16497
16498 /* Point refers normally to the selected window. For any
16499 other window, set up appropriate value. */
16500 if (!EQ (window, selected_window))
16501 {
16502 struct text_pos pt;
16503
16504 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
16505 if (CHARPOS (pt) < BEGV)
16506 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16507 else if (CHARPOS (pt) > (ZV - 1))
16508 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
16509 else
16510 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
16511 }
16512
16513 /* Display mode lines. */
16514 clear_glyph_matrix (w->desired_matrix);
16515 if (display_mode_lines (w))
16516 {
16517 ++nwindows;
16518 w->must_be_updated_p = 1;
16519 }
16520
16521 /* Restore old settings. */
16522 set_buffer_internal_1 (old);
16523 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16524 }
16525
16526 window = w->next;
16527 }
16528
16529 return nwindows;
16530 }
16531
16532
16533 /* Display the mode and/or top line of window W. Value is the number
16534 of mode lines displayed. */
16535
16536 static int
16537 display_mode_lines (w)
16538 struct window *w;
16539 {
16540 Lisp_Object old_selected_window, old_selected_frame;
16541 int n = 0;
16542
16543 old_selected_frame = selected_frame;
16544 selected_frame = w->frame;
16545 old_selected_window = selected_window;
16546 XSETWINDOW (selected_window, w);
16547
16548 /* These will be set while the mode line specs are processed. */
16549 line_number_displayed = 0;
16550 w->column_number_displayed = Qnil;
16551
16552 if (WINDOW_WANTS_MODELINE_P (w))
16553 {
16554 struct window *sel_w = XWINDOW (old_selected_window);
16555
16556 /* Select mode line face based on the real selected window. */
16557 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
16558 current_buffer->mode_line_format);
16559 ++n;
16560 }
16561
16562 if (WINDOW_WANTS_HEADER_LINE_P (w))
16563 {
16564 display_mode_line (w, HEADER_LINE_FACE_ID,
16565 current_buffer->header_line_format);
16566 ++n;
16567 }
16568
16569 selected_frame = old_selected_frame;
16570 selected_window = old_selected_window;
16571 return n;
16572 }
16573
16574
16575 /* Display mode or top line of window W. FACE_ID specifies which line
16576 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
16577 FORMAT is the mode line format to display. Value is the pixel
16578 height of the mode line displayed. */
16579
16580 static int
16581 display_mode_line (w, face_id, format)
16582 struct window *w;
16583 enum face_id face_id;
16584 Lisp_Object format;
16585 {
16586 struct it it;
16587 struct face *face;
16588 int count = SPECPDL_INDEX ();
16589
16590 init_iterator (&it, w, -1, -1, NULL, face_id);
16591 prepare_desired_row (it.glyph_row);
16592
16593 it.glyph_row->mode_line_p = 1;
16594
16595 if (! mode_line_inverse_video)
16596 /* Force the mode-line to be displayed in the default face. */
16597 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16598
16599 record_unwind_protect (unwind_format_mode_line,
16600 format_mode_line_unwind_data (NULL, 0));
16601
16602 mode_line_target = MODE_LINE_DISPLAY;
16603
16604 /* Temporarily make frame's keyboard the current kboard so that
16605 kboard-local variables in the mode_line_format will get the right
16606 values. */
16607 push_frame_kboard (it.f);
16608 record_unwind_save_match_data ();
16609 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16610 pop_frame_kboard ();
16611
16612 unbind_to (count, Qnil);
16613
16614 /* Fill up with spaces. */
16615 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
16616
16617 compute_line_metrics (&it);
16618 it.glyph_row->full_width_p = 1;
16619 it.glyph_row->continued_p = 0;
16620 it.glyph_row->truncated_on_left_p = 0;
16621 it.glyph_row->truncated_on_right_p = 0;
16622
16623 /* Make a 3D mode-line have a shadow at its right end. */
16624 face = FACE_FROM_ID (it.f, face_id);
16625 extend_face_to_end_of_line (&it);
16626 if (face->box != FACE_NO_BOX)
16627 {
16628 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
16629 + it.glyph_row->used[TEXT_AREA] - 1);
16630 last->right_box_line_p = 1;
16631 }
16632
16633 return it.glyph_row->height;
16634 }
16635
16636 /* Move element ELT in LIST to the front of LIST.
16637 Return the updated list. */
16638
16639 static Lisp_Object
16640 move_elt_to_front (elt, list)
16641 Lisp_Object elt, list;
16642 {
16643 register Lisp_Object tail, prev;
16644 register Lisp_Object tem;
16645
16646 tail = list;
16647 prev = Qnil;
16648 while (CONSP (tail))
16649 {
16650 tem = XCAR (tail);
16651
16652 if (EQ (elt, tem))
16653 {
16654 /* Splice out the link TAIL. */
16655 if (NILP (prev))
16656 list = XCDR (tail);
16657 else
16658 Fsetcdr (prev, XCDR (tail));
16659
16660 /* Now make it the first. */
16661 Fsetcdr (tail, list);
16662 return tail;
16663 }
16664 else
16665 prev = tail;
16666 tail = XCDR (tail);
16667 QUIT;
16668 }
16669
16670 /* Not found--return unchanged LIST. */
16671 return list;
16672 }
16673
16674 /* Contribute ELT to the mode line for window IT->w. How it
16675 translates into text depends on its data type.
16676
16677 IT describes the display environment in which we display, as usual.
16678
16679 DEPTH is the depth in recursion. It is used to prevent
16680 infinite recursion here.
16681
16682 FIELD_WIDTH is the number of characters the display of ELT should
16683 occupy in the mode line, and PRECISION is the maximum number of
16684 characters to display from ELT's representation. See
16685 display_string for details.
16686
16687 Returns the hpos of the end of the text generated by ELT.
16688
16689 PROPS is a property list to add to any string we encounter.
16690
16691 If RISKY is nonzero, remove (disregard) any properties in any string
16692 we encounter, and ignore :eval and :propertize.
16693
16694 The global variable `mode_line_target' determines whether the
16695 output is passed to `store_mode_line_noprop',
16696 `store_mode_line_string', or `display_string'. */
16697
16698 static int
16699 display_mode_element (it, depth, field_width, precision, elt, props, risky)
16700 struct it *it;
16701 int depth;
16702 int field_width, precision;
16703 Lisp_Object elt, props;
16704 int risky;
16705 {
16706 int n = 0, field, prec;
16707 int literal = 0;
16708
16709 tail_recurse:
16710 if (depth > 100)
16711 elt = build_string ("*too-deep*");
16712
16713 depth++;
16714
16715 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
16716 {
16717 case Lisp_String:
16718 {
16719 /* A string: output it and check for %-constructs within it. */
16720 unsigned char c;
16721 int offset = 0;
16722
16723 if (SCHARS (elt) > 0
16724 && (!NILP (props) || risky))
16725 {
16726 Lisp_Object oprops, aelt;
16727 oprops = Ftext_properties_at (make_number (0), elt);
16728
16729 /* If the starting string's properties are not what
16730 we want, translate the string. Also, if the string
16731 is risky, do that anyway. */
16732
16733 if (NILP (Fequal (props, oprops)) || risky)
16734 {
16735 /* If the starting string has properties,
16736 merge the specified ones onto the existing ones. */
16737 if (! NILP (oprops) && !risky)
16738 {
16739 Lisp_Object tem;
16740
16741 oprops = Fcopy_sequence (oprops);
16742 tem = props;
16743 while (CONSP (tem))
16744 {
16745 oprops = Fplist_put (oprops, XCAR (tem),
16746 XCAR (XCDR (tem)));
16747 tem = XCDR (XCDR (tem));
16748 }
16749 props = oprops;
16750 }
16751
16752 aelt = Fassoc (elt, mode_line_proptrans_alist);
16753 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
16754 {
16755 /* AELT is what we want. Move it to the front
16756 without consing. */
16757 elt = XCAR (aelt);
16758 mode_line_proptrans_alist
16759 = move_elt_to_front (aelt, mode_line_proptrans_alist);
16760 }
16761 else
16762 {
16763 Lisp_Object tem;
16764
16765 /* If AELT has the wrong props, it is useless.
16766 so get rid of it. */
16767 if (! NILP (aelt))
16768 mode_line_proptrans_alist
16769 = Fdelq (aelt, mode_line_proptrans_alist);
16770
16771 elt = Fcopy_sequence (elt);
16772 Fset_text_properties (make_number (0), Flength (elt),
16773 props, elt);
16774 /* Add this item to mode_line_proptrans_alist. */
16775 mode_line_proptrans_alist
16776 = Fcons (Fcons (elt, props),
16777 mode_line_proptrans_alist);
16778 /* Truncate mode_line_proptrans_alist
16779 to at most 50 elements. */
16780 tem = Fnthcdr (make_number (50),
16781 mode_line_proptrans_alist);
16782 if (! NILP (tem))
16783 XSETCDR (tem, Qnil);
16784 }
16785 }
16786 }
16787
16788 offset = 0;
16789
16790 if (literal)
16791 {
16792 prec = precision - n;
16793 switch (mode_line_target)
16794 {
16795 case MODE_LINE_NOPROP:
16796 case MODE_LINE_TITLE:
16797 n += store_mode_line_noprop (SDATA (elt), -1, prec);
16798 break;
16799 case MODE_LINE_STRING:
16800 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
16801 break;
16802 case MODE_LINE_DISPLAY:
16803 n += display_string (NULL, elt, Qnil, 0, 0, it,
16804 0, prec, 0, STRING_MULTIBYTE (elt));
16805 break;
16806 }
16807
16808 break;
16809 }
16810
16811 /* Handle the non-literal case. */
16812
16813 while ((precision <= 0 || n < precision)
16814 && SREF (elt, offset) != 0
16815 && (mode_line_target != MODE_LINE_DISPLAY
16816 || it->current_x < it->last_visible_x))
16817 {
16818 int last_offset = offset;
16819
16820 /* Advance to end of string or next format specifier. */
16821 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
16822 ;
16823
16824 if (offset - 1 != last_offset)
16825 {
16826 int nchars, nbytes;
16827
16828 /* Output to end of string or up to '%'. Field width
16829 is length of string. Don't output more than
16830 PRECISION allows us. */
16831 offset--;
16832
16833 prec = c_string_width (SDATA (elt) + last_offset,
16834 offset - last_offset, precision - n,
16835 &nchars, &nbytes);
16836
16837 switch (mode_line_target)
16838 {
16839 case MODE_LINE_NOPROP:
16840 case MODE_LINE_TITLE:
16841 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
16842 break;
16843 case MODE_LINE_STRING:
16844 {
16845 int bytepos = last_offset;
16846 int charpos = string_byte_to_char (elt, bytepos);
16847 int endpos = (precision <= 0
16848 ? string_byte_to_char (elt, offset)
16849 : charpos + nchars);
16850
16851 n += store_mode_line_string (NULL,
16852 Fsubstring (elt, make_number (charpos),
16853 make_number (endpos)),
16854 0, 0, 0, Qnil);
16855 }
16856 break;
16857 case MODE_LINE_DISPLAY:
16858 {
16859 int bytepos = last_offset;
16860 int charpos = string_byte_to_char (elt, bytepos);
16861
16862 if (precision <= 0)
16863 nchars = string_byte_to_char (elt, offset) - charpos;
16864 n += display_string (NULL, elt, Qnil, 0, charpos,
16865 it, 0, nchars, 0,
16866 STRING_MULTIBYTE (elt));
16867 }
16868 break;
16869 }
16870 }
16871 else /* c == '%' */
16872 {
16873 int percent_position = offset;
16874
16875 /* Get the specified minimum width. Zero means
16876 don't pad. */
16877 field = 0;
16878 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
16879 field = field * 10 + c - '0';
16880
16881 /* Don't pad beyond the total padding allowed. */
16882 if (field_width - n > 0 && field > field_width - n)
16883 field = field_width - n;
16884
16885 /* Note that either PRECISION <= 0 or N < PRECISION. */
16886 prec = precision - n;
16887
16888 if (c == 'M')
16889 n += display_mode_element (it, depth, field, prec,
16890 Vglobal_mode_string, props,
16891 risky);
16892 else if (c != 0)
16893 {
16894 int multibyte;
16895 int bytepos, charpos;
16896 unsigned char *spec;
16897
16898 bytepos = percent_position;
16899 charpos = (STRING_MULTIBYTE (elt)
16900 ? string_byte_to_char (elt, bytepos)
16901 : bytepos);
16902
16903 spec
16904 = decode_mode_spec (it->w, c, field, prec, &multibyte);
16905
16906 switch (mode_line_target)
16907 {
16908 case MODE_LINE_NOPROP:
16909 case MODE_LINE_TITLE:
16910 n += store_mode_line_noprop (spec, field, prec);
16911 break;
16912 case MODE_LINE_STRING:
16913 {
16914 int len = strlen (spec);
16915 Lisp_Object tem = make_string (spec, len);
16916 props = Ftext_properties_at (make_number (charpos), elt);
16917 /* Should only keep face property in props */
16918 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
16919 }
16920 break;
16921 case MODE_LINE_DISPLAY:
16922 {
16923 int nglyphs_before, nwritten;
16924
16925 nglyphs_before = it->glyph_row->used[TEXT_AREA];
16926 nwritten = display_string (spec, Qnil, elt,
16927 charpos, 0, it,
16928 field, prec, 0,
16929 multibyte);
16930
16931 /* Assign to the glyphs written above the
16932 string where the `%x' came from, position
16933 of the `%'. */
16934 if (nwritten > 0)
16935 {
16936 struct glyph *glyph
16937 = (it->glyph_row->glyphs[TEXT_AREA]
16938 + nglyphs_before);
16939 int i;
16940
16941 for (i = 0; i < nwritten; ++i)
16942 {
16943 glyph[i].object = elt;
16944 glyph[i].charpos = charpos;
16945 }
16946
16947 n += nwritten;
16948 }
16949 }
16950 break;
16951 }
16952 }
16953 else /* c == 0 */
16954 break;
16955 }
16956 }
16957 }
16958 break;
16959
16960 case Lisp_Symbol:
16961 /* A symbol: process the value of the symbol recursively
16962 as if it appeared here directly. Avoid error if symbol void.
16963 Special case: if value of symbol is a string, output the string
16964 literally. */
16965 {
16966 register Lisp_Object tem;
16967
16968 /* If the variable is not marked as risky to set
16969 then its contents are risky to use. */
16970 if (NILP (Fget (elt, Qrisky_local_variable)))
16971 risky = 1;
16972
16973 tem = Fboundp (elt);
16974 if (!NILP (tem))
16975 {
16976 tem = Fsymbol_value (elt);
16977 /* If value is a string, output that string literally:
16978 don't check for % within it. */
16979 if (STRINGP (tem))
16980 literal = 1;
16981
16982 if (!EQ (tem, elt))
16983 {
16984 /* Give up right away for nil or t. */
16985 elt = tem;
16986 goto tail_recurse;
16987 }
16988 }
16989 }
16990 break;
16991
16992 case Lisp_Cons:
16993 {
16994 register Lisp_Object car, tem;
16995
16996 /* A cons cell: five distinct cases.
16997 If first element is :eval or :propertize, do something special.
16998 If first element is a string or a cons, process all the elements
16999 and effectively concatenate them.
17000 If first element is a negative number, truncate displaying cdr to
17001 at most that many characters. If positive, pad (with spaces)
17002 to at least that many characters.
17003 If first element is a symbol, process the cadr or caddr recursively
17004 according to whether the symbol's value is non-nil or nil. */
17005 car = XCAR (elt);
17006 if (EQ (car, QCeval))
17007 {
17008 /* An element of the form (:eval FORM) means evaluate FORM
17009 and use the result as mode line elements. */
17010
17011 if (risky)
17012 break;
17013
17014 if (CONSP (XCDR (elt)))
17015 {
17016 Lisp_Object spec;
17017 spec = safe_eval (XCAR (XCDR (elt)));
17018 n += display_mode_element (it, depth, field_width - n,
17019 precision - n, spec, props,
17020 risky);
17021 }
17022 }
17023 else if (EQ (car, QCpropertize))
17024 {
17025 /* An element of the form (:propertize ELT PROPS...)
17026 means display ELT but applying properties PROPS. */
17027
17028 if (risky)
17029 break;
17030
17031 if (CONSP (XCDR (elt)))
17032 n += display_mode_element (it, depth, field_width - n,
17033 precision - n, XCAR (XCDR (elt)),
17034 XCDR (XCDR (elt)), risky);
17035 }
17036 else if (SYMBOLP (car))
17037 {
17038 tem = Fboundp (car);
17039 elt = XCDR (elt);
17040 if (!CONSP (elt))
17041 goto invalid;
17042 /* elt is now the cdr, and we know it is a cons cell.
17043 Use its car if CAR has a non-nil value. */
17044 if (!NILP (tem))
17045 {
17046 tem = Fsymbol_value (car);
17047 if (!NILP (tem))
17048 {
17049 elt = XCAR (elt);
17050 goto tail_recurse;
17051 }
17052 }
17053 /* Symbol's value is nil (or symbol is unbound)
17054 Get the cddr of the original list
17055 and if possible find the caddr and use that. */
17056 elt = XCDR (elt);
17057 if (NILP (elt))
17058 break;
17059 else if (!CONSP (elt))
17060 goto invalid;
17061 elt = XCAR (elt);
17062 goto tail_recurse;
17063 }
17064 else if (INTEGERP (car))
17065 {
17066 register int lim = XINT (car);
17067 elt = XCDR (elt);
17068 if (lim < 0)
17069 {
17070 /* Negative int means reduce maximum width. */
17071 if (precision <= 0)
17072 precision = -lim;
17073 else
17074 precision = min (precision, -lim);
17075 }
17076 else if (lim > 0)
17077 {
17078 /* Padding specified. Don't let it be more than
17079 current maximum. */
17080 if (precision > 0)
17081 lim = min (precision, lim);
17082
17083 /* If that's more padding than already wanted, queue it.
17084 But don't reduce padding already specified even if
17085 that is beyond the current truncation point. */
17086 field_width = max (lim, field_width);
17087 }
17088 goto tail_recurse;
17089 }
17090 else if (STRINGP (car) || CONSP (car))
17091 {
17092 register int limit = 50;
17093 /* Limit is to protect against circular lists. */
17094 while (CONSP (elt)
17095 && --limit > 0
17096 && (precision <= 0 || n < precision))
17097 {
17098 n += display_mode_element (it, depth,
17099 /* Do padding only after the last
17100 element in the list. */
17101 (! CONSP (XCDR (elt))
17102 ? field_width - n
17103 : 0),
17104 precision - n, XCAR (elt),
17105 props, risky);
17106 elt = XCDR (elt);
17107 }
17108 }
17109 }
17110 break;
17111
17112 default:
17113 invalid:
17114 elt = build_string ("*invalid*");
17115 goto tail_recurse;
17116 }
17117
17118 /* Pad to FIELD_WIDTH. */
17119 if (field_width > 0 && n < field_width)
17120 {
17121 switch (mode_line_target)
17122 {
17123 case MODE_LINE_NOPROP:
17124 case MODE_LINE_TITLE:
17125 n += store_mode_line_noprop ("", field_width - n, 0);
17126 break;
17127 case MODE_LINE_STRING:
17128 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
17129 break;
17130 case MODE_LINE_DISPLAY:
17131 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
17132 0, 0, 0);
17133 break;
17134 }
17135 }
17136
17137 return n;
17138 }
17139
17140 /* Store a mode-line string element in mode_line_string_list.
17141
17142 If STRING is non-null, display that C string. Otherwise, the Lisp
17143 string LISP_STRING is displayed.
17144
17145 FIELD_WIDTH is the minimum number of output glyphs to produce.
17146 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17147 with spaces. FIELD_WIDTH <= 0 means don't pad.
17148
17149 PRECISION is the maximum number of characters to output from
17150 STRING. PRECISION <= 0 means don't truncate the string.
17151
17152 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
17153 properties to the string.
17154
17155 PROPS are the properties to add to the string.
17156 The mode_line_string_face face property is always added to the string.
17157 */
17158
17159 static int
17160 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
17161 char *string;
17162 Lisp_Object lisp_string;
17163 int copy_string;
17164 int field_width;
17165 int precision;
17166 Lisp_Object props;
17167 {
17168 int len;
17169 int n = 0;
17170
17171 if (string != NULL)
17172 {
17173 len = strlen (string);
17174 if (precision > 0 && len > precision)
17175 len = precision;
17176 lisp_string = make_string (string, len);
17177 if (NILP (props))
17178 props = mode_line_string_face_prop;
17179 else if (!NILP (mode_line_string_face))
17180 {
17181 Lisp_Object face = Fplist_get (props, Qface);
17182 props = Fcopy_sequence (props);
17183 if (NILP (face))
17184 face = mode_line_string_face;
17185 else
17186 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17187 props = Fplist_put (props, Qface, face);
17188 }
17189 Fadd_text_properties (make_number (0), make_number (len),
17190 props, lisp_string);
17191 }
17192 else
17193 {
17194 len = XFASTINT (Flength (lisp_string));
17195 if (precision > 0 && len > precision)
17196 {
17197 len = precision;
17198 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
17199 precision = -1;
17200 }
17201 if (!NILP (mode_line_string_face))
17202 {
17203 Lisp_Object face;
17204 if (NILP (props))
17205 props = Ftext_properties_at (make_number (0), lisp_string);
17206 face = Fplist_get (props, Qface);
17207 if (NILP (face))
17208 face = mode_line_string_face;
17209 else
17210 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17211 props = Fcons (Qface, Fcons (face, Qnil));
17212 if (copy_string)
17213 lisp_string = Fcopy_sequence (lisp_string);
17214 }
17215 if (!NILP (props))
17216 Fadd_text_properties (make_number (0), make_number (len),
17217 props, lisp_string);
17218 }
17219
17220 if (len > 0)
17221 {
17222 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17223 n += len;
17224 }
17225
17226 if (field_width > len)
17227 {
17228 field_width -= len;
17229 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
17230 if (!NILP (props))
17231 Fadd_text_properties (make_number (0), make_number (field_width),
17232 props, lisp_string);
17233 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17234 n += field_width;
17235 }
17236
17237 return n;
17238 }
17239
17240
17241 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
17242 1, 4, 0,
17243 doc: /* Format a string out of a mode line format specification.
17244 First arg FORMAT specifies the mode line format (see `mode-line-format'
17245 for details) to use.
17246
17247 Optional second arg FACE specifies the face property to put
17248 on all characters for which no face is specified.
17249 t means whatever face the window's mode line currently uses
17250 \(either `mode-line' or `mode-line-inactive', depending).
17251 nil means the default is no face property.
17252 If FACE is an integer, the value string has no text properties.
17253
17254 Optional third and fourth args WINDOW and BUFFER specify the window
17255 and buffer to use as the context for the formatting (defaults
17256 are the selected window and the window's buffer). */)
17257 (format, face, window, buffer)
17258 Lisp_Object format, face, window, buffer;
17259 {
17260 struct it it;
17261 int len;
17262 struct window *w;
17263 struct buffer *old_buffer = NULL;
17264 int face_id = -1;
17265 int no_props = INTEGERP (face);
17266 int count = SPECPDL_INDEX ();
17267 Lisp_Object str;
17268 int string_start = 0;
17269
17270 if (NILP (window))
17271 window = selected_window;
17272 CHECK_WINDOW (window);
17273 w = XWINDOW (window);
17274
17275 if (NILP (buffer))
17276 buffer = w->buffer;
17277 CHECK_BUFFER (buffer);
17278
17279 if (NILP (format))
17280 return build_string ("");
17281
17282 if (no_props)
17283 face = Qnil;
17284
17285 if (!NILP (face))
17286 {
17287 if (EQ (face, Qt))
17288 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
17289 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
17290 }
17291
17292 if (face_id < 0)
17293 face_id = DEFAULT_FACE_ID;
17294
17295 if (XBUFFER (buffer) != current_buffer)
17296 old_buffer = current_buffer;
17297
17298 /* Save things including mode_line_proptrans_alist,
17299 and set that to nil so that we don't alter the outer value. */
17300 record_unwind_protect (unwind_format_mode_line,
17301 format_mode_line_unwind_data (old_buffer, 1));
17302 mode_line_proptrans_alist = Qnil;
17303
17304 if (old_buffer)
17305 set_buffer_internal_1 (XBUFFER (buffer));
17306
17307 init_iterator (&it, w, -1, -1, NULL, face_id);
17308
17309 if (no_props)
17310 {
17311 mode_line_target = MODE_LINE_NOPROP;
17312 mode_line_string_face_prop = Qnil;
17313 mode_line_string_list = Qnil;
17314 string_start = MODE_LINE_NOPROP_LEN (0);
17315 }
17316 else
17317 {
17318 mode_line_target = MODE_LINE_STRING;
17319 mode_line_string_list = Qnil;
17320 mode_line_string_face = face;
17321 mode_line_string_face_prop
17322 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
17323 }
17324
17325 push_frame_kboard (it.f);
17326 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
17327 pop_frame_kboard ();
17328
17329 if (no_props)
17330 {
17331 len = MODE_LINE_NOPROP_LEN (string_start);
17332 str = make_string (mode_line_noprop_buf + string_start, len);
17333 }
17334 else
17335 {
17336 mode_line_string_list = Fnreverse (mode_line_string_list);
17337 str = Fmapconcat (intern ("identity"), mode_line_string_list,
17338 make_string ("", 0));
17339 }
17340
17341 unbind_to (count, Qnil);
17342 return str;
17343 }
17344
17345 /* Write a null-terminated, right justified decimal representation of
17346 the positive integer D to BUF using a minimal field width WIDTH. */
17347
17348 static void
17349 pint2str (buf, width, d)
17350 register char *buf;
17351 register int width;
17352 register int d;
17353 {
17354 register char *p = buf;
17355
17356 if (d <= 0)
17357 *p++ = '0';
17358 else
17359 {
17360 while (d > 0)
17361 {
17362 *p++ = d % 10 + '0';
17363 d /= 10;
17364 }
17365 }
17366
17367 for (width -= (int) (p - buf); width > 0; --width)
17368 *p++ = ' ';
17369 *p-- = '\0';
17370 while (p > buf)
17371 {
17372 d = *buf;
17373 *buf++ = *p;
17374 *p-- = d;
17375 }
17376 }
17377
17378 /* Write a null-terminated, right justified decimal and "human
17379 readable" representation of the nonnegative integer D to BUF using
17380 a minimal field width WIDTH. D should be smaller than 999.5e24. */
17381
17382 static const char power_letter[] =
17383 {
17384 0, /* not used */
17385 'k', /* kilo */
17386 'M', /* mega */
17387 'G', /* giga */
17388 'T', /* tera */
17389 'P', /* peta */
17390 'E', /* exa */
17391 'Z', /* zetta */
17392 'Y' /* yotta */
17393 };
17394
17395 static void
17396 pint2hrstr (buf, width, d)
17397 char *buf;
17398 int width;
17399 int d;
17400 {
17401 /* We aim to represent the nonnegative integer D as
17402 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
17403 int quotient = d;
17404 int remainder = 0;
17405 /* -1 means: do not use TENTHS. */
17406 int tenths = -1;
17407 int exponent = 0;
17408
17409 /* Length of QUOTIENT.TENTHS as a string. */
17410 int length;
17411
17412 char * psuffix;
17413 char * p;
17414
17415 if (1000 <= quotient)
17416 {
17417 /* Scale to the appropriate EXPONENT. */
17418 do
17419 {
17420 remainder = quotient % 1000;
17421 quotient /= 1000;
17422 exponent++;
17423 }
17424 while (1000 <= quotient);
17425
17426 /* Round to nearest and decide whether to use TENTHS or not. */
17427 if (quotient <= 9)
17428 {
17429 tenths = remainder / 100;
17430 if (50 <= remainder % 100)
17431 {
17432 if (tenths < 9)
17433 tenths++;
17434 else
17435 {
17436 quotient++;
17437 if (quotient == 10)
17438 tenths = -1;
17439 else
17440 tenths = 0;
17441 }
17442 }
17443 }
17444 else
17445 if (500 <= remainder)
17446 {
17447 if (quotient < 999)
17448 quotient++;
17449 else
17450 {
17451 quotient = 1;
17452 exponent++;
17453 tenths = 0;
17454 }
17455 }
17456 }
17457
17458 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
17459 if (tenths == -1 && quotient <= 99)
17460 if (quotient <= 9)
17461 length = 1;
17462 else
17463 length = 2;
17464 else
17465 length = 3;
17466 p = psuffix = buf + max (width, length);
17467
17468 /* Print EXPONENT. */
17469 if (exponent)
17470 *psuffix++ = power_letter[exponent];
17471 *psuffix = '\0';
17472
17473 /* Print TENTHS. */
17474 if (tenths >= 0)
17475 {
17476 *--p = '0' + tenths;
17477 *--p = '.';
17478 }
17479
17480 /* Print QUOTIENT. */
17481 do
17482 {
17483 int digit = quotient % 10;
17484 *--p = '0' + digit;
17485 }
17486 while ((quotient /= 10) != 0);
17487
17488 /* Print leading spaces. */
17489 while (buf < p)
17490 *--p = ' ';
17491 }
17492
17493 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
17494 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
17495 type of CODING_SYSTEM. Return updated pointer into BUF. */
17496
17497 static unsigned char invalid_eol_type[] = "(*invalid*)";
17498
17499 static char *
17500 decode_mode_spec_coding (coding_system, buf, eol_flag)
17501 Lisp_Object coding_system;
17502 register char *buf;
17503 int eol_flag;
17504 {
17505 Lisp_Object val;
17506 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
17507 const unsigned char *eol_str;
17508 int eol_str_len;
17509 /* The EOL conversion we are using. */
17510 Lisp_Object eoltype;
17511
17512 val = Fget (coding_system, Qcoding_system);
17513 eoltype = Qnil;
17514
17515 if (!VECTORP (val)) /* Not yet decided. */
17516 {
17517 if (multibyte)
17518 *buf++ = '-';
17519 if (eol_flag)
17520 eoltype = eol_mnemonic_undecided;
17521 /* Don't mention EOL conversion if it isn't decided. */
17522 }
17523 else
17524 {
17525 Lisp_Object eolvalue;
17526
17527 eolvalue = Fget (coding_system, Qeol_type);
17528
17529 if (multibyte)
17530 *buf++ = XFASTINT (AREF (val, 1));
17531
17532 if (eol_flag)
17533 {
17534 /* The EOL conversion that is normal on this system. */
17535
17536 if (NILP (eolvalue)) /* Not yet decided. */
17537 eoltype = eol_mnemonic_undecided;
17538 else if (VECTORP (eolvalue)) /* Not yet decided. */
17539 eoltype = eol_mnemonic_undecided;
17540 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
17541 eoltype = (XFASTINT (eolvalue) == 0
17542 ? eol_mnemonic_unix
17543 : (XFASTINT (eolvalue) == 1
17544 ? eol_mnemonic_dos : eol_mnemonic_mac));
17545 }
17546 }
17547
17548 if (eol_flag)
17549 {
17550 /* Mention the EOL conversion if it is not the usual one. */
17551 if (STRINGP (eoltype))
17552 {
17553 eol_str = SDATA (eoltype);
17554 eol_str_len = SBYTES (eoltype);
17555 }
17556 else if (INTEGERP (eoltype)
17557 && CHAR_VALID_P (XINT (eoltype), 0))
17558 {
17559 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
17560 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
17561 eol_str = tmp;
17562 }
17563 else
17564 {
17565 eol_str = invalid_eol_type;
17566 eol_str_len = sizeof (invalid_eol_type) - 1;
17567 }
17568 bcopy (eol_str, buf, eol_str_len);
17569 buf += eol_str_len;
17570 }
17571
17572 return buf;
17573 }
17574
17575 /* Return a string for the output of a mode line %-spec for window W,
17576 generated by character C. PRECISION >= 0 means don't return a
17577 string longer than that value. FIELD_WIDTH > 0 means pad the
17578 string returned with spaces to that value. Return 1 in *MULTIBYTE
17579 if the result is multibyte text.
17580
17581 Note we operate on the current buffer for most purposes,
17582 the exception being w->base_line_pos. */
17583
17584 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
17585
17586 static char *
17587 decode_mode_spec (w, c, field_width, precision, multibyte)
17588 struct window *w;
17589 register int c;
17590 int field_width, precision;
17591 int *multibyte;
17592 {
17593 Lisp_Object obj;
17594 struct frame *f = XFRAME (WINDOW_FRAME (w));
17595 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
17596 struct buffer *b = current_buffer;
17597
17598 obj = Qnil;
17599 *multibyte = 0;
17600
17601 switch (c)
17602 {
17603 case '*':
17604 if (!NILP (b->read_only))
17605 return "%";
17606 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17607 return "*";
17608 return "-";
17609
17610 case '+':
17611 /* This differs from %* only for a modified read-only buffer. */
17612 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17613 return "*";
17614 if (!NILP (b->read_only))
17615 return "%";
17616 return "-";
17617
17618 case '&':
17619 /* This differs from %* in ignoring read-only-ness. */
17620 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17621 return "*";
17622 return "-";
17623
17624 case '%':
17625 return "%";
17626
17627 case '[':
17628 {
17629 int i;
17630 char *p;
17631
17632 if (command_loop_level > 5)
17633 return "[[[... ";
17634 p = decode_mode_spec_buf;
17635 for (i = 0; i < command_loop_level; i++)
17636 *p++ = '[';
17637 *p = 0;
17638 return decode_mode_spec_buf;
17639 }
17640
17641 case ']':
17642 {
17643 int i;
17644 char *p;
17645
17646 if (command_loop_level > 5)
17647 return " ...]]]";
17648 p = decode_mode_spec_buf;
17649 for (i = 0; i < command_loop_level; i++)
17650 *p++ = ']';
17651 *p = 0;
17652 return decode_mode_spec_buf;
17653 }
17654
17655 case '-':
17656 {
17657 register int i;
17658
17659 /* Let lots_of_dashes be a string of infinite length. */
17660 if (mode_line_target == MODE_LINE_NOPROP ||
17661 mode_line_target == MODE_LINE_STRING)
17662 return "--";
17663 if (field_width <= 0
17664 || field_width > sizeof (lots_of_dashes))
17665 {
17666 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
17667 decode_mode_spec_buf[i] = '-';
17668 decode_mode_spec_buf[i] = '\0';
17669 return decode_mode_spec_buf;
17670 }
17671 else
17672 return lots_of_dashes;
17673 }
17674
17675 case 'b':
17676 obj = b->name;
17677 break;
17678
17679 case 'c':
17680 {
17681 int col = (int) current_column (); /* iftc */
17682 w->column_number_displayed = make_number (col);
17683 pint2str (decode_mode_spec_buf, field_width, col);
17684 return decode_mode_spec_buf;
17685 }
17686
17687 case 'e':
17688 #ifndef SYSTEM_MALLOC
17689 {
17690 if (NILP (Vmemory_full))
17691 return "";
17692 else
17693 return "!MEM FULL! ";
17694 }
17695 #else
17696 return "";
17697 #endif
17698
17699 case 'F':
17700 /* %F displays the frame name. */
17701 if (!NILP (f->title))
17702 return (char *) SDATA (f->title);
17703 if (f->explicit_name || ! FRAME_WINDOW_P (f))
17704 return (char *) SDATA (f->name);
17705 return "Emacs";
17706
17707 case 'f':
17708 obj = b->filename;
17709 break;
17710
17711 case 'i':
17712 {
17713 int size = ZV - BEGV;
17714 pint2str (decode_mode_spec_buf, field_width, size);
17715 return decode_mode_spec_buf;
17716 }
17717
17718 case 'I':
17719 {
17720 int size = ZV - BEGV;
17721 pint2hrstr (decode_mode_spec_buf, field_width, size);
17722 return decode_mode_spec_buf;
17723 }
17724
17725 case 'l':
17726 {
17727 int startpos = XMARKER (w->start)->charpos;
17728 int startpos_byte = marker_byte_position (w->start);
17729 int line, linepos, linepos_byte, topline;
17730 int nlines, junk;
17731 int height = WINDOW_TOTAL_LINES (w);
17732
17733 /* If we decided that this buffer isn't suitable for line numbers,
17734 don't forget that too fast. */
17735 if (EQ (w->base_line_pos, w->buffer))
17736 goto no_value;
17737 /* But do forget it, if the window shows a different buffer now. */
17738 else if (BUFFERP (w->base_line_pos))
17739 w->base_line_pos = Qnil;
17740
17741 /* If the buffer is very big, don't waste time. */
17742 if (INTEGERP (Vline_number_display_limit)
17743 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
17744 {
17745 w->base_line_pos = Qnil;
17746 w->base_line_number = Qnil;
17747 goto no_value;
17748 }
17749
17750 if (!NILP (w->base_line_number)
17751 && !NILP (w->base_line_pos)
17752 && XFASTINT (w->base_line_pos) <= startpos)
17753 {
17754 line = XFASTINT (w->base_line_number);
17755 linepos = XFASTINT (w->base_line_pos);
17756 linepos_byte = buf_charpos_to_bytepos (b, linepos);
17757 }
17758 else
17759 {
17760 line = 1;
17761 linepos = BUF_BEGV (b);
17762 linepos_byte = BUF_BEGV_BYTE (b);
17763 }
17764
17765 /* Count lines from base line to window start position. */
17766 nlines = display_count_lines (linepos, linepos_byte,
17767 startpos_byte,
17768 startpos, &junk);
17769
17770 topline = nlines + line;
17771
17772 /* Determine a new base line, if the old one is too close
17773 or too far away, or if we did not have one.
17774 "Too close" means it's plausible a scroll-down would
17775 go back past it. */
17776 if (startpos == BUF_BEGV (b))
17777 {
17778 w->base_line_number = make_number (topline);
17779 w->base_line_pos = make_number (BUF_BEGV (b));
17780 }
17781 else if (nlines < height + 25 || nlines > height * 3 + 50
17782 || linepos == BUF_BEGV (b))
17783 {
17784 int limit = BUF_BEGV (b);
17785 int limit_byte = BUF_BEGV_BYTE (b);
17786 int position;
17787 int distance = (height * 2 + 30) * line_number_display_limit_width;
17788
17789 if (startpos - distance > limit)
17790 {
17791 limit = startpos - distance;
17792 limit_byte = CHAR_TO_BYTE (limit);
17793 }
17794
17795 nlines = display_count_lines (startpos, startpos_byte,
17796 limit_byte,
17797 - (height * 2 + 30),
17798 &position);
17799 /* If we couldn't find the lines we wanted within
17800 line_number_display_limit_width chars per line,
17801 give up on line numbers for this window. */
17802 if (position == limit_byte && limit == startpos - distance)
17803 {
17804 w->base_line_pos = w->buffer;
17805 w->base_line_number = Qnil;
17806 goto no_value;
17807 }
17808
17809 w->base_line_number = make_number (topline - nlines);
17810 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
17811 }
17812
17813 /* Now count lines from the start pos to point. */
17814 nlines = display_count_lines (startpos, startpos_byte,
17815 PT_BYTE, PT, &junk);
17816
17817 /* Record that we did display the line number. */
17818 line_number_displayed = 1;
17819
17820 /* Make the string to show. */
17821 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
17822 return decode_mode_spec_buf;
17823 no_value:
17824 {
17825 char* p = decode_mode_spec_buf;
17826 int pad = field_width - 2;
17827 while (pad-- > 0)
17828 *p++ = ' ';
17829 *p++ = '?';
17830 *p++ = '?';
17831 *p = '\0';
17832 return decode_mode_spec_buf;
17833 }
17834 }
17835 break;
17836
17837 case 'm':
17838 obj = b->mode_name;
17839 break;
17840
17841 case 'n':
17842 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
17843 return " Narrow";
17844 break;
17845
17846 case 'p':
17847 {
17848 int pos = marker_position (w->start);
17849 int total = BUF_ZV (b) - BUF_BEGV (b);
17850
17851 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
17852 {
17853 if (pos <= BUF_BEGV (b))
17854 return "All";
17855 else
17856 return "Bottom";
17857 }
17858 else if (pos <= BUF_BEGV (b))
17859 return "Top";
17860 else
17861 {
17862 if (total > 1000000)
17863 /* Do it differently for a large value, to avoid overflow. */
17864 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
17865 else
17866 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
17867 /* We can't normally display a 3-digit number,
17868 so get us a 2-digit number that is close. */
17869 if (total == 100)
17870 total = 99;
17871 sprintf (decode_mode_spec_buf, "%2d%%", total);
17872 return decode_mode_spec_buf;
17873 }
17874 }
17875
17876 /* Display percentage of size above the bottom of the screen. */
17877 case 'P':
17878 {
17879 int toppos = marker_position (w->start);
17880 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
17881 int total = BUF_ZV (b) - BUF_BEGV (b);
17882
17883 if (botpos >= BUF_ZV (b))
17884 {
17885 if (toppos <= BUF_BEGV (b))
17886 return "All";
17887 else
17888 return "Bottom";
17889 }
17890 else
17891 {
17892 if (total > 1000000)
17893 /* Do it differently for a large value, to avoid overflow. */
17894 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
17895 else
17896 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
17897 /* We can't normally display a 3-digit number,
17898 so get us a 2-digit number that is close. */
17899 if (total == 100)
17900 total = 99;
17901 if (toppos <= BUF_BEGV (b))
17902 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
17903 else
17904 sprintf (decode_mode_spec_buf, "%2d%%", total);
17905 return decode_mode_spec_buf;
17906 }
17907 }
17908
17909 case 's':
17910 /* status of process */
17911 obj = Fget_buffer_process (Fcurrent_buffer ());
17912 if (NILP (obj))
17913 return "no process";
17914 #ifdef subprocesses
17915 obj = Fsymbol_name (Fprocess_status (obj));
17916 #endif
17917 break;
17918
17919 case 't': /* indicate TEXT or BINARY */
17920 #ifdef MODE_LINE_BINARY_TEXT
17921 return MODE_LINE_BINARY_TEXT (b);
17922 #else
17923 return "T";
17924 #endif
17925
17926 case 'z':
17927 /* coding-system (not including end-of-line format) */
17928 case 'Z':
17929 /* coding-system (including end-of-line type) */
17930 {
17931 int eol_flag = (c == 'Z');
17932 char *p = decode_mode_spec_buf;
17933
17934 if (! FRAME_WINDOW_P (f))
17935 {
17936 /* No need to mention EOL here--the terminal never needs
17937 to do EOL conversion. */
17938 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
17939 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
17940 }
17941 p = decode_mode_spec_coding (b->buffer_file_coding_system,
17942 p, eol_flag);
17943
17944 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
17945 #ifdef subprocesses
17946 obj = Fget_buffer_process (Fcurrent_buffer ());
17947 if (PROCESSP (obj))
17948 {
17949 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
17950 p, eol_flag);
17951 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
17952 p, eol_flag);
17953 }
17954 #endif /* subprocesses */
17955 #endif /* 0 */
17956 *p = 0;
17957 return decode_mode_spec_buf;
17958 }
17959 }
17960
17961 if (STRINGP (obj))
17962 {
17963 *multibyte = STRING_MULTIBYTE (obj);
17964 return (char *) SDATA (obj);
17965 }
17966 else
17967 return "";
17968 }
17969
17970
17971 /* Count up to COUNT lines starting from START / START_BYTE.
17972 But don't go beyond LIMIT_BYTE.
17973 Return the number of lines thus found (always nonnegative).
17974
17975 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
17976
17977 static int
17978 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
17979 int start, start_byte, limit_byte, count;
17980 int *byte_pos_ptr;
17981 {
17982 register unsigned char *cursor;
17983 unsigned char *base;
17984
17985 register int ceiling;
17986 register unsigned char *ceiling_addr;
17987 int orig_count = count;
17988
17989 /* If we are not in selective display mode,
17990 check only for newlines. */
17991 int selective_display = (!NILP (current_buffer->selective_display)
17992 && !INTEGERP (current_buffer->selective_display));
17993
17994 if (count > 0)
17995 {
17996 while (start_byte < limit_byte)
17997 {
17998 ceiling = BUFFER_CEILING_OF (start_byte);
17999 ceiling = min (limit_byte - 1, ceiling);
18000 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
18001 base = (cursor = BYTE_POS_ADDR (start_byte));
18002 while (1)
18003 {
18004 if (selective_display)
18005 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
18006 ;
18007 else
18008 while (*cursor != '\n' && ++cursor != ceiling_addr)
18009 ;
18010
18011 if (cursor != ceiling_addr)
18012 {
18013 if (--count == 0)
18014 {
18015 start_byte += cursor - base + 1;
18016 *byte_pos_ptr = start_byte;
18017 return orig_count;
18018 }
18019 else
18020 if (++cursor == ceiling_addr)
18021 break;
18022 }
18023 else
18024 break;
18025 }
18026 start_byte += cursor - base;
18027 }
18028 }
18029 else
18030 {
18031 while (start_byte > limit_byte)
18032 {
18033 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
18034 ceiling = max (limit_byte, ceiling);
18035 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
18036 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
18037 while (1)
18038 {
18039 if (selective_display)
18040 while (--cursor != ceiling_addr
18041 && *cursor != '\n' && *cursor != 015)
18042 ;
18043 else
18044 while (--cursor != ceiling_addr && *cursor != '\n')
18045 ;
18046
18047 if (cursor != ceiling_addr)
18048 {
18049 if (++count == 0)
18050 {
18051 start_byte += cursor - base + 1;
18052 *byte_pos_ptr = start_byte;
18053 /* When scanning backwards, we should
18054 not count the newline posterior to which we stop. */
18055 return - orig_count - 1;
18056 }
18057 }
18058 else
18059 break;
18060 }
18061 /* Here we add 1 to compensate for the last decrement
18062 of CURSOR, which took it past the valid range. */
18063 start_byte += cursor - base + 1;
18064 }
18065 }
18066
18067 *byte_pos_ptr = limit_byte;
18068
18069 if (count < 0)
18070 return - orig_count + count;
18071 return orig_count - count;
18072
18073 }
18074
18075
18076 \f
18077 /***********************************************************************
18078 Displaying strings
18079 ***********************************************************************/
18080
18081 /* Display a NUL-terminated string, starting with index START.
18082
18083 If STRING is non-null, display that C string. Otherwise, the Lisp
18084 string LISP_STRING is displayed.
18085
18086 If FACE_STRING is not nil, FACE_STRING_POS is a position in
18087 FACE_STRING. Display STRING or LISP_STRING with the face at
18088 FACE_STRING_POS in FACE_STRING:
18089
18090 Display the string in the environment given by IT, but use the
18091 standard display table, temporarily.
18092
18093 FIELD_WIDTH is the minimum number of output glyphs to produce.
18094 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18095 with spaces. If STRING has more characters, more than FIELD_WIDTH
18096 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
18097
18098 PRECISION is the maximum number of characters to output from
18099 STRING. PRECISION < 0 means don't truncate the string.
18100
18101 This is roughly equivalent to printf format specifiers:
18102
18103 FIELD_WIDTH PRECISION PRINTF
18104 ----------------------------------------
18105 -1 -1 %s
18106 -1 10 %.10s
18107 10 -1 %10s
18108 20 10 %20.10s
18109
18110 MULTIBYTE zero means do not display multibyte chars, > 0 means do
18111 display them, and < 0 means obey the current buffer's value of
18112 enable_multibyte_characters.
18113
18114 Value is the number of columns displayed. */
18115
18116 static int
18117 display_string (string, lisp_string, face_string, face_string_pos,
18118 start, it, field_width, precision, max_x, multibyte)
18119 unsigned char *string;
18120 Lisp_Object lisp_string;
18121 Lisp_Object face_string;
18122 int face_string_pos;
18123 int start;
18124 struct it *it;
18125 int field_width, precision, max_x;
18126 int multibyte;
18127 {
18128 int hpos_at_start = it->hpos;
18129 int saved_face_id = it->face_id;
18130 struct glyph_row *row = it->glyph_row;
18131
18132 /* Initialize the iterator IT for iteration over STRING beginning
18133 with index START. */
18134 reseat_to_string (it, string, lisp_string, start,
18135 precision, field_width, multibyte);
18136
18137 /* If displaying STRING, set up the face of the iterator
18138 from LISP_STRING, if that's given. */
18139 if (STRINGP (face_string))
18140 {
18141 int endptr;
18142 struct face *face;
18143
18144 it->face_id
18145 = face_at_string_position (it->w, face_string, face_string_pos,
18146 0, it->region_beg_charpos,
18147 it->region_end_charpos,
18148 &endptr, it->base_face_id, 0);
18149 face = FACE_FROM_ID (it->f, it->face_id);
18150 it->face_box_p = face->box != FACE_NO_BOX;
18151 }
18152
18153 /* Set max_x to the maximum allowed X position. Don't let it go
18154 beyond the right edge of the window. */
18155 if (max_x <= 0)
18156 max_x = it->last_visible_x;
18157 else
18158 max_x = min (max_x, it->last_visible_x);
18159
18160 /* Skip over display elements that are not visible. because IT->w is
18161 hscrolled. */
18162 if (it->current_x < it->first_visible_x)
18163 move_it_in_display_line_to (it, 100000, it->first_visible_x,
18164 MOVE_TO_POS | MOVE_TO_X);
18165
18166 row->ascent = it->max_ascent;
18167 row->height = it->max_ascent + it->max_descent;
18168 row->phys_ascent = it->max_phys_ascent;
18169 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18170 row->extra_line_spacing = it->max_extra_line_spacing;
18171
18172 /* This condition is for the case that we are called with current_x
18173 past last_visible_x. */
18174 while (it->current_x < max_x)
18175 {
18176 int x_before, x, n_glyphs_before, i, nglyphs;
18177
18178 /* Get the next display element. */
18179 if (!get_next_display_element (it))
18180 break;
18181
18182 /* Produce glyphs. */
18183 x_before = it->current_x;
18184 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
18185 PRODUCE_GLYPHS (it);
18186
18187 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
18188 i = 0;
18189 x = x_before;
18190 while (i < nglyphs)
18191 {
18192 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18193
18194 if (!it->truncate_lines_p
18195 && x + glyph->pixel_width > max_x)
18196 {
18197 /* End of continued line or max_x reached. */
18198 if (CHAR_GLYPH_PADDING_P (*glyph))
18199 {
18200 /* A wide character is unbreakable. */
18201 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
18202 it->current_x = x_before;
18203 }
18204 else
18205 {
18206 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
18207 it->current_x = x;
18208 }
18209 break;
18210 }
18211 else if (x + glyph->pixel_width > it->first_visible_x)
18212 {
18213 /* Glyph is at least partially visible. */
18214 ++it->hpos;
18215 if (x < it->first_visible_x)
18216 it->glyph_row->x = x - it->first_visible_x;
18217 }
18218 else
18219 {
18220 /* Glyph is off the left margin of the display area.
18221 Should not happen. */
18222 abort ();
18223 }
18224
18225 row->ascent = max (row->ascent, it->max_ascent);
18226 row->height = max (row->height, it->max_ascent + it->max_descent);
18227 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18228 row->phys_height = max (row->phys_height,
18229 it->max_phys_ascent + it->max_phys_descent);
18230 row->extra_line_spacing = max (row->extra_line_spacing,
18231 it->max_extra_line_spacing);
18232 x += glyph->pixel_width;
18233 ++i;
18234 }
18235
18236 /* Stop if max_x reached. */
18237 if (i < nglyphs)
18238 break;
18239
18240 /* Stop at line ends. */
18241 if (ITERATOR_AT_END_OF_LINE_P (it))
18242 {
18243 it->continuation_lines_width = 0;
18244 break;
18245 }
18246
18247 set_iterator_to_next (it, 1);
18248
18249 /* Stop if truncating at the right edge. */
18250 if (it->truncate_lines_p
18251 && it->current_x >= it->last_visible_x)
18252 {
18253 /* Add truncation mark, but don't do it if the line is
18254 truncated at a padding space. */
18255 if (IT_CHARPOS (*it) < it->string_nchars)
18256 {
18257 if (!FRAME_WINDOW_P (it->f))
18258 {
18259 int i, n;
18260
18261 if (it->current_x > it->last_visible_x)
18262 {
18263 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
18264 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18265 break;
18266 for (n = row->used[TEXT_AREA]; i < n; ++i)
18267 {
18268 row->used[TEXT_AREA] = i;
18269 produce_special_glyphs (it, IT_TRUNCATION);
18270 }
18271 }
18272 produce_special_glyphs (it, IT_TRUNCATION);
18273 }
18274 it->glyph_row->truncated_on_right_p = 1;
18275 }
18276 break;
18277 }
18278 }
18279
18280 /* Maybe insert a truncation at the left. */
18281 if (it->first_visible_x
18282 && IT_CHARPOS (*it) > 0)
18283 {
18284 if (!FRAME_WINDOW_P (it->f))
18285 insert_left_trunc_glyphs (it);
18286 it->glyph_row->truncated_on_left_p = 1;
18287 }
18288
18289 it->face_id = saved_face_id;
18290
18291 /* Value is number of columns displayed. */
18292 return it->hpos - hpos_at_start;
18293 }
18294
18295
18296 \f
18297 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
18298 appears as an element of LIST or as the car of an element of LIST.
18299 If PROPVAL is a list, compare each element against LIST in that
18300 way, and return 1/2 if any element of PROPVAL is found in LIST.
18301 Otherwise return 0. This function cannot quit.
18302 The return value is 2 if the text is invisible but with an ellipsis
18303 and 1 if it's invisible and without an ellipsis. */
18304
18305 int
18306 invisible_p (propval, list)
18307 register Lisp_Object propval;
18308 Lisp_Object list;
18309 {
18310 register Lisp_Object tail, proptail;
18311
18312 for (tail = list; CONSP (tail); tail = XCDR (tail))
18313 {
18314 register Lisp_Object tem;
18315 tem = XCAR (tail);
18316 if (EQ (propval, tem))
18317 return 1;
18318 if (CONSP (tem) && EQ (propval, XCAR (tem)))
18319 return NILP (XCDR (tem)) ? 1 : 2;
18320 }
18321
18322 if (CONSP (propval))
18323 {
18324 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
18325 {
18326 Lisp_Object propelt;
18327 propelt = XCAR (proptail);
18328 for (tail = list; CONSP (tail); tail = XCDR (tail))
18329 {
18330 register Lisp_Object tem;
18331 tem = XCAR (tail);
18332 if (EQ (propelt, tem))
18333 return 1;
18334 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
18335 return NILP (XCDR (tem)) ? 1 : 2;
18336 }
18337 }
18338 }
18339
18340 return 0;
18341 }
18342
18343 /* Calculate a width or height in pixels from a specification using
18344 the following elements:
18345
18346 SPEC ::=
18347 NUM - a (fractional) multiple of the default font width/height
18348 (NUM) - specifies exactly NUM pixels
18349 UNIT - a fixed number of pixels, see below.
18350 ELEMENT - size of a display element in pixels, see below.
18351 (NUM . SPEC) - equals NUM * SPEC
18352 (+ SPEC SPEC ...) - add pixel values
18353 (- SPEC SPEC ...) - subtract pixel values
18354 (- SPEC) - negate pixel value
18355
18356 NUM ::=
18357 INT or FLOAT - a number constant
18358 SYMBOL - use symbol's (buffer local) variable binding.
18359
18360 UNIT ::=
18361 in - pixels per inch *)
18362 mm - pixels per 1/1000 meter *)
18363 cm - pixels per 1/100 meter *)
18364 width - width of current font in pixels.
18365 height - height of current font in pixels.
18366
18367 *) using the ratio(s) defined in display-pixels-per-inch.
18368
18369 ELEMENT ::=
18370
18371 left-fringe - left fringe width in pixels
18372 right-fringe - right fringe width in pixels
18373
18374 left-margin - left margin width in pixels
18375 right-margin - right margin width in pixels
18376
18377 scroll-bar - scroll-bar area width in pixels
18378
18379 Examples:
18380
18381 Pixels corresponding to 5 inches:
18382 (5 . in)
18383
18384 Total width of non-text areas on left side of window (if scroll-bar is on left):
18385 '(space :width (+ left-fringe left-margin scroll-bar))
18386
18387 Align to first text column (in header line):
18388 '(space :align-to 0)
18389
18390 Align to middle of text area minus half the width of variable `my-image'
18391 containing a loaded image:
18392 '(space :align-to (0.5 . (- text my-image)))
18393
18394 Width of left margin minus width of 1 character in the default font:
18395 '(space :width (- left-margin 1))
18396
18397 Width of left margin minus width of 2 characters in the current font:
18398 '(space :width (- left-margin (2 . width)))
18399
18400 Center 1 character over left-margin (in header line):
18401 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
18402
18403 Different ways to express width of left fringe plus left margin minus one pixel:
18404 '(space :width (- (+ left-fringe left-margin) (1)))
18405 '(space :width (+ left-fringe left-margin (- (1))))
18406 '(space :width (+ left-fringe left-margin (-1)))
18407
18408 */
18409
18410 #define NUMVAL(X) \
18411 ((INTEGERP (X) || FLOATP (X)) \
18412 ? XFLOATINT (X) \
18413 : - 1)
18414
18415 int
18416 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
18417 double *res;
18418 struct it *it;
18419 Lisp_Object prop;
18420 void *font;
18421 int width_p, *align_to;
18422 {
18423 double pixels;
18424
18425 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
18426 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
18427
18428 if (NILP (prop))
18429 return OK_PIXELS (0);
18430
18431 if (SYMBOLP (prop))
18432 {
18433 if (SCHARS (SYMBOL_NAME (prop)) == 2)
18434 {
18435 char *unit = SDATA (SYMBOL_NAME (prop));
18436
18437 if (unit[0] == 'i' && unit[1] == 'n')
18438 pixels = 1.0;
18439 else if (unit[0] == 'm' && unit[1] == 'm')
18440 pixels = 25.4;
18441 else if (unit[0] == 'c' && unit[1] == 'm')
18442 pixels = 2.54;
18443 else
18444 pixels = 0;
18445 if (pixels > 0)
18446 {
18447 double ppi;
18448 #ifdef HAVE_WINDOW_SYSTEM
18449 if (FRAME_WINDOW_P (it->f)
18450 && (ppi = (width_p
18451 ? FRAME_X_DISPLAY_INFO (it->f)->resx
18452 : FRAME_X_DISPLAY_INFO (it->f)->resy),
18453 ppi > 0))
18454 return OK_PIXELS (ppi / pixels);
18455 #endif
18456
18457 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
18458 || (CONSP (Vdisplay_pixels_per_inch)
18459 && (ppi = (width_p
18460 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
18461 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
18462 ppi > 0)))
18463 return OK_PIXELS (ppi / pixels);
18464
18465 return 0;
18466 }
18467 }
18468
18469 #ifdef HAVE_WINDOW_SYSTEM
18470 if (EQ (prop, Qheight))
18471 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
18472 if (EQ (prop, Qwidth))
18473 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
18474 #else
18475 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
18476 return OK_PIXELS (1);
18477 #endif
18478
18479 if (EQ (prop, Qtext))
18480 return OK_PIXELS (width_p
18481 ? window_box_width (it->w, TEXT_AREA)
18482 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
18483
18484 if (align_to && *align_to < 0)
18485 {
18486 *res = 0;
18487 if (EQ (prop, Qleft))
18488 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
18489 if (EQ (prop, Qright))
18490 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
18491 if (EQ (prop, Qcenter))
18492 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
18493 + window_box_width (it->w, TEXT_AREA) / 2);
18494 if (EQ (prop, Qleft_fringe))
18495 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18496 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
18497 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
18498 if (EQ (prop, Qright_fringe))
18499 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18500 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18501 : window_box_right_offset (it->w, TEXT_AREA));
18502 if (EQ (prop, Qleft_margin))
18503 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
18504 if (EQ (prop, Qright_margin))
18505 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
18506 if (EQ (prop, Qscroll_bar))
18507 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18508 ? 0
18509 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18510 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18511 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18512 : 0)));
18513 }
18514 else
18515 {
18516 if (EQ (prop, Qleft_fringe))
18517 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
18518 if (EQ (prop, Qright_fringe))
18519 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
18520 if (EQ (prop, Qleft_margin))
18521 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
18522 if (EQ (prop, Qright_margin))
18523 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
18524 if (EQ (prop, Qscroll_bar))
18525 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
18526 }
18527
18528 prop = Fbuffer_local_value (prop, it->w->buffer);
18529 }
18530
18531 if (INTEGERP (prop) || FLOATP (prop))
18532 {
18533 int base_unit = (width_p
18534 ? FRAME_COLUMN_WIDTH (it->f)
18535 : FRAME_LINE_HEIGHT (it->f));
18536 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18537 }
18538
18539 if (CONSP (prop))
18540 {
18541 Lisp_Object car = XCAR (prop);
18542 Lisp_Object cdr = XCDR (prop);
18543
18544 if (SYMBOLP (car))
18545 {
18546 #ifdef HAVE_WINDOW_SYSTEM
18547 if (valid_image_p (prop))
18548 {
18549 int id = lookup_image (it->f, prop);
18550 struct image *img = IMAGE_FROM_ID (it->f, id);
18551
18552 return OK_PIXELS (width_p ? img->width : img->height);
18553 }
18554 #endif
18555 if (EQ (car, Qplus) || EQ (car, Qminus))
18556 {
18557 int first = 1;
18558 double px;
18559
18560 pixels = 0;
18561 while (CONSP (cdr))
18562 {
18563 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
18564 font, width_p, align_to))
18565 return 0;
18566 if (first)
18567 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18568 else
18569 pixels += px;
18570 cdr = XCDR (cdr);
18571 }
18572 if (EQ (car, Qminus))
18573 pixels = -pixels;
18574 return OK_PIXELS (pixels);
18575 }
18576
18577 car = Fbuffer_local_value (car, it->w->buffer);
18578 }
18579
18580 if (INTEGERP (car) || FLOATP (car))
18581 {
18582 double fact;
18583 pixels = XFLOATINT (car);
18584 if (NILP (cdr))
18585 return OK_PIXELS (pixels);
18586 if (calc_pixel_width_or_height (&fact, it, cdr,
18587 font, width_p, align_to))
18588 return OK_PIXELS (pixels * fact);
18589 return 0;
18590 }
18591
18592 return 0;
18593 }
18594
18595 return 0;
18596 }
18597
18598 \f
18599 /***********************************************************************
18600 Glyph Display
18601 ***********************************************************************/
18602
18603 #ifdef HAVE_WINDOW_SYSTEM
18604
18605 #if GLYPH_DEBUG
18606
18607 void
18608 dump_glyph_string (s)
18609 struct glyph_string *s;
18610 {
18611 fprintf (stderr, "glyph string\n");
18612 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
18613 s->x, s->y, s->width, s->height);
18614 fprintf (stderr, " ybase = %d\n", s->ybase);
18615 fprintf (stderr, " hl = %d\n", s->hl);
18616 fprintf (stderr, " left overhang = %d, right = %d\n",
18617 s->left_overhang, s->right_overhang);
18618 fprintf (stderr, " nchars = %d\n", s->nchars);
18619 fprintf (stderr, " extends to end of line = %d\n",
18620 s->extends_to_end_of_line_p);
18621 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
18622 fprintf (stderr, " bg width = %d\n", s->background_width);
18623 }
18624
18625 #endif /* GLYPH_DEBUG */
18626
18627 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
18628 of XChar2b structures for S; it can't be allocated in
18629 init_glyph_string because it must be allocated via `alloca'. W
18630 is the window on which S is drawn. ROW and AREA are the glyph row
18631 and area within the row from which S is constructed. START is the
18632 index of the first glyph structure covered by S. HL is a
18633 face-override for drawing S. */
18634
18635 #ifdef HAVE_NTGUI
18636 #define OPTIONAL_HDC(hdc) hdc,
18637 #define DECLARE_HDC(hdc) HDC hdc;
18638 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
18639 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
18640 #endif
18641
18642 #ifndef OPTIONAL_HDC
18643 #define OPTIONAL_HDC(hdc)
18644 #define DECLARE_HDC(hdc)
18645 #define ALLOCATE_HDC(hdc, f)
18646 #define RELEASE_HDC(hdc, f)
18647 #endif
18648
18649 static void
18650 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
18651 struct glyph_string *s;
18652 DECLARE_HDC (hdc)
18653 XChar2b *char2b;
18654 struct window *w;
18655 struct glyph_row *row;
18656 enum glyph_row_area area;
18657 int start;
18658 enum draw_glyphs_face hl;
18659 {
18660 bzero (s, sizeof *s);
18661 s->w = w;
18662 s->f = XFRAME (w->frame);
18663 #ifdef HAVE_NTGUI
18664 s->hdc = hdc;
18665 #endif
18666 s->display = FRAME_X_DISPLAY (s->f);
18667 s->window = FRAME_X_WINDOW (s->f);
18668 s->char2b = char2b;
18669 s->hl = hl;
18670 s->row = row;
18671 s->area = area;
18672 s->first_glyph = row->glyphs[area] + start;
18673 s->height = row->height;
18674 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
18675
18676 /* Display the internal border below the tool-bar window. */
18677 if (WINDOWP (s->f->tool_bar_window)
18678 && s->w == XWINDOW (s->f->tool_bar_window))
18679 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
18680
18681 s->ybase = s->y + row->ascent;
18682 }
18683
18684
18685 /* Append the list of glyph strings with head H and tail T to the list
18686 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
18687
18688 static INLINE void
18689 append_glyph_string_lists (head, tail, h, t)
18690 struct glyph_string **head, **tail;
18691 struct glyph_string *h, *t;
18692 {
18693 if (h)
18694 {
18695 if (*head)
18696 (*tail)->next = h;
18697 else
18698 *head = h;
18699 h->prev = *tail;
18700 *tail = t;
18701 }
18702 }
18703
18704
18705 /* Prepend the list of glyph strings with head H and tail T to the
18706 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
18707 result. */
18708
18709 static INLINE void
18710 prepend_glyph_string_lists (head, tail, h, t)
18711 struct glyph_string **head, **tail;
18712 struct glyph_string *h, *t;
18713 {
18714 if (h)
18715 {
18716 if (*head)
18717 (*head)->prev = t;
18718 else
18719 *tail = t;
18720 t->next = *head;
18721 *head = h;
18722 }
18723 }
18724
18725
18726 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
18727 Set *HEAD and *TAIL to the resulting list. */
18728
18729 static INLINE void
18730 append_glyph_string (head, tail, s)
18731 struct glyph_string **head, **tail;
18732 struct glyph_string *s;
18733 {
18734 s->next = s->prev = NULL;
18735 append_glyph_string_lists (head, tail, s, s);
18736 }
18737
18738
18739 /* Get face and two-byte form of character glyph GLYPH on frame F.
18740 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
18741 a pointer to a realized face that is ready for display. */
18742
18743 static INLINE struct face *
18744 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
18745 struct frame *f;
18746 struct glyph *glyph;
18747 XChar2b *char2b;
18748 int *two_byte_p;
18749 {
18750 struct face *face;
18751
18752 xassert (glyph->type == CHAR_GLYPH);
18753 face = FACE_FROM_ID (f, glyph->face_id);
18754
18755 if (two_byte_p)
18756 *two_byte_p = 0;
18757
18758 if (!glyph->multibyte_p)
18759 {
18760 /* Unibyte case. We don't have to encode, but we have to make
18761 sure to use a face suitable for unibyte. */
18762 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
18763 }
18764 else if (glyph->u.ch < 128)
18765 {
18766 /* Case of ASCII in a face known to fit ASCII. */
18767 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
18768 }
18769 else
18770 {
18771 int c1, c2, charset;
18772
18773 /* Split characters into bytes. If c2 is -1 afterwards, C is
18774 really a one-byte character so that byte1 is zero. */
18775 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
18776 if (c2 > 0)
18777 STORE_XCHAR2B (char2b, c1, c2);
18778 else
18779 STORE_XCHAR2B (char2b, 0, c1);
18780
18781 /* Maybe encode the character in *CHAR2B. */
18782 if (charset != CHARSET_ASCII)
18783 {
18784 struct font_info *font_info
18785 = FONT_INFO_FROM_ID (f, face->font_info_id);
18786 if (font_info)
18787 glyph->font_type
18788 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
18789 }
18790 }
18791
18792 /* Make sure X resources of the face are allocated. */
18793 xassert (face != NULL);
18794 PREPARE_FACE_FOR_DISPLAY (f, face);
18795 return face;
18796 }
18797
18798
18799 /* Fill glyph string S with composition components specified by S->cmp.
18800
18801 FACES is an array of faces for all components of this composition.
18802 S->gidx is the index of the first component for S.
18803
18804 OVERLAPS non-zero means S should draw the foreground only, and use
18805 its physical height for clipping. See also draw_glyphs.
18806
18807 Value is the index of a component not in S. */
18808
18809 static int
18810 fill_composite_glyph_string (s, faces, overlaps)
18811 struct glyph_string *s;
18812 struct face **faces;
18813 int overlaps;
18814 {
18815 int i;
18816
18817 xassert (s);
18818
18819 s->for_overlaps = overlaps;
18820
18821 s->face = faces[s->gidx];
18822 s->font = s->face->font;
18823 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18824
18825 /* For all glyphs of this composition, starting at the offset
18826 S->gidx, until we reach the end of the definition or encounter a
18827 glyph that requires the different face, add it to S. */
18828 ++s->nchars;
18829 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
18830 ++s->nchars;
18831
18832 /* All glyph strings for the same composition has the same width,
18833 i.e. the width set for the first component of the composition. */
18834
18835 s->width = s->first_glyph->pixel_width;
18836
18837 /* If the specified font could not be loaded, use the frame's
18838 default font, but record the fact that we couldn't load it in
18839 the glyph string so that we can draw rectangles for the
18840 characters of the glyph string. */
18841 if (s->font == NULL)
18842 {
18843 s->font_not_found_p = 1;
18844 s->font = FRAME_FONT (s->f);
18845 }
18846
18847 /* Adjust base line for subscript/superscript text. */
18848 s->ybase += s->first_glyph->voffset;
18849
18850 xassert (s->face && s->face->gc);
18851
18852 /* This glyph string must always be drawn with 16-bit functions. */
18853 s->two_byte_p = 1;
18854
18855 return s->gidx + s->nchars;
18856 }
18857
18858
18859 /* Fill glyph string S from a sequence of character glyphs.
18860
18861 FACE_ID is the face id of the string. START is the index of the
18862 first glyph to consider, END is the index of the last + 1.
18863 OVERLAPS non-zero means S should draw the foreground only, and use
18864 its physical height for clipping. See also draw_glyphs.
18865
18866 Value is the index of the first glyph not in S. */
18867
18868 static int
18869 fill_glyph_string (s, face_id, start, end, overlaps)
18870 struct glyph_string *s;
18871 int face_id;
18872 int start, end, overlaps;
18873 {
18874 struct glyph *glyph, *last;
18875 int voffset;
18876 int glyph_not_available_p;
18877
18878 xassert (s->f == XFRAME (s->w->frame));
18879 xassert (s->nchars == 0);
18880 xassert (start >= 0 && end > start);
18881
18882 s->for_overlaps = overlaps,
18883 glyph = s->row->glyphs[s->area] + start;
18884 last = s->row->glyphs[s->area] + end;
18885 voffset = glyph->voffset;
18886
18887 glyph_not_available_p = glyph->glyph_not_available_p;
18888
18889 while (glyph < last
18890 && glyph->type == CHAR_GLYPH
18891 && glyph->voffset == voffset
18892 /* Same face id implies same font, nowadays. */
18893 && glyph->face_id == face_id
18894 && glyph->glyph_not_available_p == glyph_not_available_p)
18895 {
18896 int two_byte_p;
18897
18898 s->face = get_glyph_face_and_encoding (s->f, glyph,
18899 s->char2b + s->nchars,
18900 &two_byte_p);
18901 s->two_byte_p = two_byte_p;
18902 ++s->nchars;
18903 xassert (s->nchars <= end - start);
18904 s->width += glyph->pixel_width;
18905 ++glyph;
18906 }
18907
18908 s->font = s->face->font;
18909 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18910
18911 /* If the specified font could not be loaded, use the frame's font,
18912 but record the fact that we couldn't load it in
18913 S->font_not_found_p so that we can draw rectangles for the
18914 characters of the glyph string. */
18915 if (s->font == NULL || glyph_not_available_p)
18916 {
18917 s->font_not_found_p = 1;
18918 s->font = FRAME_FONT (s->f);
18919 }
18920
18921 /* Adjust base line for subscript/superscript text. */
18922 s->ybase += voffset;
18923
18924 xassert (s->face && s->face->gc);
18925 return glyph - s->row->glyphs[s->area];
18926 }
18927
18928
18929 /* Fill glyph string S from image glyph S->first_glyph. */
18930
18931 static void
18932 fill_image_glyph_string (s)
18933 struct glyph_string *s;
18934 {
18935 xassert (s->first_glyph->type == IMAGE_GLYPH);
18936 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
18937 xassert (s->img);
18938 s->slice = s->first_glyph->slice;
18939 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
18940 s->font = s->face->font;
18941 s->width = s->first_glyph->pixel_width;
18942
18943 /* Adjust base line for subscript/superscript text. */
18944 s->ybase += s->first_glyph->voffset;
18945 }
18946
18947
18948 /* Fill glyph string S from a sequence of stretch glyphs.
18949
18950 ROW is the glyph row in which the glyphs are found, AREA is the
18951 area within the row. START is the index of the first glyph to
18952 consider, END is the index of the last + 1.
18953
18954 Value is the index of the first glyph not in S. */
18955
18956 static int
18957 fill_stretch_glyph_string (s, row, area, start, end)
18958 struct glyph_string *s;
18959 struct glyph_row *row;
18960 enum glyph_row_area area;
18961 int start, end;
18962 {
18963 struct glyph *glyph, *last;
18964 int voffset, face_id;
18965
18966 xassert (s->first_glyph->type == STRETCH_GLYPH);
18967
18968 glyph = s->row->glyphs[s->area] + start;
18969 last = s->row->glyphs[s->area] + end;
18970 face_id = glyph->face_id;
18971 s->face = FACE_FROM_ID (s->f, face_id);
18972 s->font = s->face->font;
18973 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18974 s->width = glyph->pixel_width;
18975 s->nchars = 1;
18976 voffset = glyph->voffset;
18977
18978 for (++glyph;
18979 (glyph < last
18980 && glyph->type == STRETCH_GLYPH
18981 && glyph->voffset == voffset
18982 && glyph->face_id == face_id);
18983 ++glyph)
18984 s->width += glyph->pixel_width;
18985
18986 /* Adjust base line for subscript/superscript text. */
18987 s->ybase += voffset;
18988
18989 /* The case that face->gc == 0 is handled when drawing the glyph
18990 string by calling PREPARE_FACE_FOR_DISPLAY. */
18991 xassert (s->face);
18992 return glyph - s->row->glyphs[s->area];
18993 }
18994
18995
18996 /* EXPORT for RIF:
18997 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
18998 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
18999 assumed to be zero. */
19000
19001 void
19002 x_get_glyph_overhangs (glyph, f, left, right)
19003 struct glyph *glyph;
19004 struct frame *f;
19005 int *left, *right;
19006 {
19007 *left = *right = 0;
19008
19009 if (glyph->type == CHAR_GLYPH)
19010 {
19011 XFontStruct *font;
19012 struct face *face;
19013 struct font_info *font_info;
19014 XChar2b char2b;
19015 XCharStruct *pcm;
19016
19017 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
19018 font = face->font;
19019 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
19020 if (font /* ++KFS: Should this be font_info ? */
19021 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
19022 {
19023 if (pcm->rbearing > pcm->width)
19024 *right = pcm->rbearing - pcm->width;
19025 if (pcm->lbearing < 0)
19026 *left = -pcm->lbearing;
19027 }
19028 }
19029 }
19030
19031
19032 /* Return the index of the first glyph preceding glyph string S that
19033 is overwritten by S because of S's left overhang. Value is -1
19034 if no glyphs are overwritten. */
19035
19036 static int
19037 left_overwritten (s)
19038 struct glyph_string *s;
19039 {
19040 int k;
19041
19042 if (s->left_overhang)
19043 {
19044 int x = 0, i;
19045 struct glyph *glyphs = s->row->glyphs[s->area];
19046 int first = s->first_glyph - glyphs;
19047
19048 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
19049 x -= glyphs[i].pixel_width;
19050
19051 k = i + 1;
19052 }
19053 else
19054 k = -1;
19055
19056 return k;
19057 }
19058
19059
19060 /* Return the index of the first glyph preceding glyph string S that
19061 is overwriting S because of its right overhang. Value is -1 if no
19062 glyph in front of S overwrites S. */
19063
19064 static int
19065 left_overwriting (s)
19066 struct glyph_string *s;
19067 {
19068 int i, k, x;
19069 struct glyph *glyphs = s->row->glyphs[s->area];
19070 int first = s->first_glyph - glyphs;
19071
19072 k = -1;
19073 x = 0;
19074 for (i = first - 1; i >= 0; --i)
19075 {
19076 int left, right;
19077 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19078 if (x + right > 0)
19079 k = i;
19080 x -= glyphs[i].pixel_width;
19081 }
19082
19083 return k;
19084 }
19085
19086
19087 /* Return the index of the last glyph following glyph string S that is
19088 not overwritten by S because of S's right overhang. Value is -1 if
19089 no such glyph is found. */
19090
19091 static int
19092 right_overwritten (s)
19093 struct glyph_string *s;
19094 {
19095 int k = -1;
19096
19097 if (s->right_overhang)
19098 {
19099 int x = 0, i;
19100 struct glyph *glyphs = s->row->glyphs[s->area];
19101 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19102 int end = s->row->used[s->area];
19103
19104 for (i = first; i < end && s->right_overhang > x; ++i)
19105 x += glyphs[i].pixel_width;
19106
19107 k = i;
19108 }
19109
19110 return k;
19111 }
19112
19113
19114 /* Return the index of the last glyph following glyph string S that
19115 overwrites S because of its left overhang. Value is negative
19116 if no such glyph is found. */
19117
19118 static int
19119 right_overwriting (s)
19120 struct glyph_string *s;
19121 {
19122 int i, k, x;
19123 int end = s->row->used[s->area];
19124 struct glyph *glyphs = s->row->glyphs[s->area];
19125 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19126
19127 k = -1;
19128 x = 0;
19129 for (i = first; i < end; ++i)
19130 {
19131 int left, right;
19132 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19133 if (x - left < 0)
19134 k = i;
19135 x += glyphs[i].pixel_width;
19136 }
19137
19138 return k;
19139 }
19140
19141
19142 /* Get face and two-byte form of character C in face FACE_ID on frame
19143 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
19144 means we want to display multibyte text. DISPLAY_P non-zero means
19145 make sure that X resources for the face returned are allocated.
19146 Value is a pointer to a realized face that is ready for display if
19147 DISPLAY_P is non-zero. */
19148
19149 static INLINE struct face *
19150 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
19151 struct frame *f;
19152 int c, face_id;
19153 XChar2b *char2b;
19154 int multibyte_p, display_p;
19155 {
19156 struct face *face = FACE_FROM_ID (f, face_id);
19157
19158 if (!multibyte_p)
19159 {
19160 /* Unibyte case. We don't have to encode, but we have to make
19161 sure to use a face suitable for unibyte. */
19162 STORE_XCHAR2B (char2b, 0, c);
19163 face_id = FACE_FOR_CHAR (f, face, c);
19164 face = FACE_FROM_ID (f, face_id);
19165 }
19166 else if (c < 128)
19167 {
19168 /* Case of ASCII in a face known to fit ASCII. */
19169 STORE_XCHAR2B (char2b, 0, c);
19170 }
19171 else
19172 {
19173 int c1, c2, charset;
19174
19175 /* Split characters into bytes. If c2 is -1 afterwards, C is
19176 really a one-byte character so that byte1 is zero. */
19177 SPLIT_CHAR (c, charset, c1, c2);
19178 if (c2 > 0)
19179 STORE_XCHAR2B (char2b, c1, c2);
19180 else
19181 STORE_XCHAR2B (char2b, 0, c1);
19182
19183 /* Maybe encode the character in *CHAR2B. */
19184 if (face->font != NULL)
19185 {
19186 struct font_info *font_info
19187 = FONT_INFO_FROM_ID (f, face->font_info_id);
19188 if (font_info)
19189 rif->encode_char (c, char2b, font_info, 0);
19190 }
19191 }
19192
19193 /* Make sure X resources of the face are allocated. */
19194 #ifdef HAVE_X_WINDOWS
19195 if (display_p)
19196 #endif
19197 {
19198 xassert (face != NULL);
19199 PREPARE_FACE_FOR_DISPLAY (f, face);
19200 }
19201
19202 return face;
19203 }
19204
19205
19206 /* Set background width of glyph string S. START is the index of the
19207 first glyph following S. LAST_X is the right-most x-position + 1
19208 in the drawing area. */
19209
19210 static INLINE void
19211 set_glyph_string_background_width (s, start, last_x)
19212 struct glyph_string *s;
19213 int start;
19214 int last_x;
19215 {
19216 /* If the face of this glyph string has to be drawn to the end of
19217 the drawing area, set S->extends_to_end_of_line_p. */
19218
19219 if (start == s->row->used[s->area]
19220 && s->area == TEXT_AREA
19221 && ((s->row->fill_line_p
19222 && (s->hl == DRAW_NORMAL_TEXT
19223 || s->hl == DRAW_IMAGE_RAISED
19224 || s->hl == DRAW_IMAGE_SUNKEN))
19225 || s->hl == DRAW_MOUSE_FACE))
19226 s->extends_to_end_of_line_p = 1;
19227
19228 /* If S extends its face to the end of the line, set its
19229 background_width to the distance to the right edge of the drawing
19230 area. */
19231 if (s->extends_to_end_of_line_p)
19232 s->background_width = last_x - s->x + 1;
19233 else
19234 s->background_width = s->width;
19235 }
19236
19237
19238 /* Compute overhangs and x-positions for glyph string S and its
19239 predecessors, or successors. X is the starting x-position for S.
19240 BACKWARD_P non-zero means process predecessors. */
19241
19242 static void
19243 compute_overhangs_and_x (s, x, backward_p)
19244 struct glyph_string *s;
19245 int x;
19246 int backward_p;
19247 {
19248 if (backward_p)
19249 {
19250 while (s)
19251 {
19252 if (rif->compute_glyph_string_overhangs)
19253 rif->compute_glyph_string_overhangs (s);
19254 x -= s->width;
19255 s->x = x;
19256 s = s->prev;
19257 }
19258 }
19259 else
19260 {
19261 while (s)
19262 {
19263 if (rif->compute_glyph_string_overhangs)
19264 rif->compute_glyph_string_overhangs (s);
19265 s->x = x;
19266 x += s->width;
19267 s = s->next;
19268 }
19269 }
19270 }
19271
19272
19273
19274 /* The following macros are only called from draw_glyphs below.
19275 They reference the following parameters of that function directly:
19276 `w', `row', `area', and `overlap_p'
19277 as well as the following local variables:
19278 `s', `f', and `hdc' (in W32) */
19279
19280 #ifdef HAVE_NTGUI
19281 /* On W32, silently add local `hdc' variable to argument list of
19282 init_glyph_string. */
19283 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19284 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
19285 #else
19286 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19287 init_glyph_string (s, char2b, w, row, area, start, hl)
19288 #endif
19289
19290 /* Add a glyph string for a stretch glyph to the list of strings
19291 between HEAD and TAIL. START is the index of the stretch glyph in
19292 row area AREA of glyph row ROW. END is the index of the last glyph
19293 in that glyph row area. X is the current output position assigned
19294 to the new glyph string constructed. HL overrides that face of the
19295 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19296 is the right-most x-position of the drawing area. */
19297
19298 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
19299 and below -- keep them on one line. */
19300 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19301 do \
19302 { \
19303 s = (struct glyph_string *) alloca (sizeof *s); \
19304 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19305 START = fill_stretch_glyph_string (s, row, area, START, END); \
19306 append_glyph_string (&HEAD, &TAIL, s); \
19307 s->x = (X); \
19308 } \
19309 while (0)
19310
19311
19312 /* Add a glyph string for an image glyph to the list of strings
19313 between HEAD and TAIL. START is the index of the image glyph in
19314 row area AREA of glyph row ROW. END is the index of the last glyph
19315 in that glyph row area. X is the current output position assigned
19316 to the new glyph string constructed. HL overrides that face of the
19317 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19318 is the right-most x-position of the drawing area. */
19319
19320 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19321 do \
19322 { \
19323 s = (struct glyph_string *) alloca (sizeof *s); \
19324 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19325 fill_image_glyph_string (s); \
19326 append_glyph_string (&HEAD, &TAIL, s); \
19327 ++START; \
19328 s->x = (X); \
19329 } \
19330 while (0)
19331
19332
19333 /* Add a glyph string for a sequence of character glyphs to the list
19334 of strings between HEAD and TAIL. START is the index of the first
19335 glyph in row area AREA of glyph row ROW that is part of the new
19336 glyph string. END is the index of the last glyph in that glyph row
19337 area. X is the current output position assigned to the new glyph
19338 string constructed. HL overrides that face of the glyph; e.g. it
19339 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
19340 right-most x-position of the drawing area. */
19341
19342 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19343 do \
19344 { \
19345 int c, face_id; \
19346 XChar2b *char2b; \
19347 \
19348 c = (row)->glyphs[area][START].u.ch; \
19349 face_id = (row)->glyphs[area][START].face_id; \
19350 \
19351 s = (struct glyph_string *) alloca (sizeof *s); \
19352 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
19353 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
19354 append_glyph_string (&HEAD, &TAIL, s); \
19355 s->x = (X); \
19356 START = fill_glyph_string (s, face_id, START, END, overlaps); \
19357 } \
19358 while (0)
19359
19360
19361 /* Add a glyph string for a composite sequence to the list of strings
19362 between HEAD and TAIL. START is the index of the first glyph in
19363 row area AREA of glyph row ROW that is part of the new glyph
19364 string. END is the index of the last glyph in that glyph row area.
19365 X is the current output position assigned to the new glyph string
19366 constructed. HL overrides that face of the glyph; e.g. it is
19367 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
19368 x-position of the drawing area. */
19369
19370 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19371 do { \
19372 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
19373 int face_id = (row)->glyphs[area][START].face_id; \
19374 struct face *base_face = FACE_FROM_ID (f, face_id); \
19375 struct composition *cmp = composition_table[cmp_id]; \
19376 int glyph_len = cmp->glyph_len; \
19377 XChar2b *char2b; \
19378 struct face **faces; \
19379 struct glyph_string *first_s = NULL; \
19380 int n; \
19381 \
19382 base_face = base_face->ascii_face; \
19383 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
19384 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
19385 /* At first, fill in `char2b' and `faces'. */ \
19386 for (n = 0; n < glyph_len; n++) \
19387 { \
19388 int c = COMPOSITION_GLYPH (cmp, n); \
19389 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
19390 faces[n] = FACE_FROM_ID (f, this_face_id); \
19391 get_char_face_and_encoding (f, c, this_face_id, \
19392 char2b + n, 1, 1); \
19393 } \
19394 \
19395 /* Make glyph_strings for each glyph sequence that is drawable by \
19396 the same face, and append them to HEAD/TAIL. */ \
19397 for (n = 0; n < cmp->glyph_len;) \
19398 { \
19399 s = (struct glyph_string *) alloca (sizeof *s); \
19400 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
19401 append_glyph_string (&(HEAD), &(TAIL), s); \
19402 s->cmp = cmp; \
19403 s->gidx = n; \
19404 s->x = (X); \
19405 \
19406 if (n == 0) \
19407 first_s = s; \
19408 \
19409 n = fill_composite_glyph_string (s, faces, overlaps); \
19410 } \
19411 \
19412 ++START; \
19413 s = first_s; \
19414 } while (0)
19415
19416
19417 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
19418 of AREA of glyph row ROW on window W between indices START and END.
19419 HL overrides the face for drawing glyph strings, e.g. it is
19420 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
19421 x-positions of the drawing area.
19422
19423 This is an ugly monster macro construct because we must use alloca
19424 to allocate glyph strings (because draw_glyphs can be called
19425 asynchronously). */
19426
19427 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19428 do \
19429 { \
19430 HEAD = TAIL = NULL; \
19431 while (START < END) \
19432 { \
19433 struct glyph *first_glyph = (row)->glyphs[area] + START; \
19434 switch (first_glyph->type) \
19435 { \
19436 case CHAR_GLYPH: \
19437 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
19438 HL, X, LAST_X); \
19439 break; \
19440 \
19441 case COMPOSITE_GLYPH: \
19442 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
19443 HL, X, LAST_X); \
19444 break; \
19445 \
19446 case STRETCH_GLYPH: \
19447 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
19448 HL, X, LAST_X); \
19449 break; \
19450 \
19451 case IMAGE_GLYPH: \
19452 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
19453 HL, X, LAST_X); \
19454 break; \
19455 \
19456 default: \
19457 abort (); \
19458 } \
19459 \
19460 set_glyph_string_background_width (s, START, LAST_X); \
19461 (X) += s->width; \
19462 } \
19463 } \
19464 while (0)
19465
19466
19467 /* Draw glyphs between START and END in AREA of ROW on window W,
19468 starting at x-position X. X is relative to AREA in W. HL is a
19469 face-override with the following meaning:
19470
19471 DRAW_NORMAL_TEXT draw normally
19472 DRAW_CURSOR draw in cursor face
19473 DRAW_MOUSE_FACE draw in mouse face.
19474 DRAW_INVERSE_VIDEO draw in mode line face
19475 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
19476 DRAW_IMAGE_RAISED draw an image with a raised relief around it
19477
19478 If OVERLAPS is non-zero, draw only the foreground of characters and
19479 clip to the physical height of ROW. Non-zero value also defines
19480 the overlapping part to be drawn:
19481
19482 OVERLAPS_PRED overlap with preceding rows
19483 OVERLAPS_SUCC overlap with succeeding rows
19484 OVERLAPS_BOTH overlap with both preceding/succeeding rows
19485 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
19486
19487 Value is the x-position reached, relative to AREA of W. */
19488
19489 static int
19490 draw_glyphs (w, x, row, area, start, end, hl, overlaps)
19491 struct window *w;
19492 int x;
19493 struct glyph_row *row;
19494 enum glyph_row_area area;
19495 int start, end;
19496 enum draw_glyphs_face hl;
19497 int overlaps;
19498 {
19499 struct glyph_string *head, *tail;
19500 struct glyph_string *s;
19501 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
19502 int last_x, area_width;
19503 int x_reached;
19504 int i, j;
19505 struct frame *f = XFRAME (WINDOW_FRAME (w));
19506 DECLARE_HDC (hdc);
19507
19508 ALLOCATE_HDC (hdc, f);
19509
19510 /* Let's rather be paranoid than getting a SEGV. */
19511 end = min (end, row->used[area]);
19512 start = max (0, start);
19513 start = min (end, start);
19514
19515 /* Translate X to frame coordinates. Set last_x to the right
19516 end of the drawing area. */
19517 if (row->full_width_p)
19518 {
19519 /* X is relative to the left edge of W, without scroll bars
19520 or fringes. */
19521 x += WINDOW_LEFT_EDGE_X (w);
19522 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
19523 }
19524 else
19525 {
19526 int area_left = window_box_left (w, area);
19527 x += area_left;
19528 area_width = window_box_width (w, area);
19529 last_x = area_left + area_width;
19530 }
19531
19532 /* Build a doubly-linked list of glyph_string structures between
19533 head and tail from what we have to draw. Note that the macro
19534 BUILD_GLYPH_STRINGS will modify its start parameter. That's
19535 the reason we use a separate variable `i'. */
19536 i = start;
19537 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
19538 if (tail)
19539 x_reached = tail->x + tail->background_width;
19540 else
19541 x_reached = x;
19542
19543 /* If there are any glyphs with lbearing < 0 or rbearing > width in
19544 the row, redraw some glyphs in front or following the glyph
19545 strings built above. */
19546 if (head && !overlaps && row->contains_overlapping_glyphs_p)
19547 {
19548 int dummy_x = 0;
19549 struct glyph_string *h, *t;
19550
19551 /* Compute overhangs for all glyph strings. */
19552 if (rif->compute_glyph_string_overhangs)
19553 for (s = head; s; s = s->next)
19554 rif->compute_glyph_string_overhangs (s);
19555
19556 /* Prepend glyph strings for glyphs in front of the first glyph
19557 string that are overwritten because of the first glyph
19558 string's left overhang. The background of all strings
19559 prepended must be drawn because the first glyph string
19560 draws over it. */
19561 i = left_overwritten (head);
19562 if (i >= 0)
19563 {
19564 j = i;
19565 BUILD_GLYPH_STRINGS (j, start, h, t,
19566 DRAW_NORMAL_TEXT, dummy_x, last_x);
19567 start = i;
19568 compute_overhangs_and_x (t, head->x, 1);
19569 prepend_glyph_string_lists (&head, &tail, h, t);
19570 clip_head = head;
19571 }
19572
19573 /* Prepend glyph strings for glyphs in front of the first glyph
19574 string that overwrite that glyph string because of their
19575 right overhang. For these strings, only the foreground must
19576 be drawn, because it draws over the glyph string at `head'.
19577 The background must not be drawn because this would overwrite
19578 right overhangs of preceding glyphs for which no glyph
19579 strings exist. */
19580 i = left_overwriting (head);
19581 if (i >= 0)
19582 {
19583 clip_head = head;
19584 BUILD_GLYPH_STRINGS (i, start, h, t,
19585 DRAW_NORMAL_TEXT, dummy_x, last_x);
19586 for (s = h; s; s = s->next)
19587 s->background_filled_p = 1;
19588 compute_overhangs_and_x (t, head->x, 1);
19589 prepend_glyph_string_lists (&head, &tail, h, t);
19590 }
19591
19592 /* Append glyphs strings for glyphs following the last glyph
19593 string tail that are overwritten by tail. The background of
19594 these strings has to be drawn because tail's foreground draws
19595 over it. */
19596 i = right_overwritten (tail);
19597 if (i >= 0)
19598 {
19599 BUILD_GLYPH_STRINGS (end, i, h, t,
19600 DRAW_NORMAL_TEXT, x, last_x);
19601 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19602 append_glyph_string_lists (&head, &tail, h, t);
19603 clip_tail = tail;
19604 }
19605
19606 /* Append glyph strings for glyphs following the last glyph
19607 string tail that overwrite tail. The foreground of such
19608 glyphs has to be drawn because it writes into the background
19609 of tail. The background must not be drawn because it could
19610 paint over the foreground of following glyphs. */
19611 i = right_overwriting (tail);
19612 if (i >= 0)
19613 {
19614 clip_tail = tail;
19615 BUILD_GLYPH_STRINGS (end, i, h, t,
19616 DRAW_NORMAL_TEXT, x, last_x);
19617 for (s = h; s; s = s->next)
19618 s->background_filled_p = 1;
19619 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19620 append_glyph_string_lists (&head, &tail, h, t);
19621 }
19622 if (clip_head || clip_tail)
19623 for (s = head; s; s = s->next)
19624 {
19625 s->clip_head = clip_head;
19626 s->clip_tail = clip_tail;
19627 }
19628 }
19629
19630 /* Draw all strings. */
19631 for (s = head; s; s = s->next)
19632 rif->draw_glyph_string (s);
19633
19634 if (area == TEXT_AREA
19635 && !row->full_width_p
19636 /* When drawing overlapping rows, only the glyph strings'
19637 foreground is drawn, which doesn't erase a cursor
19638 completely. */
19639 && !overlaps)
19640 {
19641 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
19642 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
19643 : (tail ? tail->x + tail->background_width : x));
19644
19645 int text_left = window_box_left (w, TEXT_AREA);
19646 x0 -= text_left;
19647 x1 -= text_left;
19648
19649 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
19650 row->y, MATRIX_ROW_BOTTOM_Y (row));
19651 }
19652
19653 /* Value is the x-position up to which drawn, relative to AREA of W.
19654 This doesn't include parts drawn because of overhangs. */
19655 if (row->full_width_p)
19656 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
19657 else
19658 x_reached -= window_box_left (w, area);
19659
19660 RELEASE_HDC (hdc, f);
19661
19662 return x_reached;
19663 }
19664
19665 /* Expand row matrix if too narrow. Don't expand if area
19666 is not present. */
19667
19668 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
19669 { \
19670 if (!fonts_changed_p \
19671 && (it->glyph_row->glyphs[area] \
19672 < it->glyph_row->glyphs[area + 1])) \
19673 { \
19674 it->w->ncols_scale_factor++; \
19675 fonts_changed_p = 1; \
19676 } \
19677 }
19678
19679 /* Store one glyph for IT->char_to_display in IT->glyph_row.
19680 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19681
19682 static INLINE void
19683 append_glyph (it)
19684 struct it *it;
19685 {
19686 struct glyph *glyph;
19687 enum glyph_row_area area = it->area;
19688
19689 xassert (it->glyph_row);
19690 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
19691
19692 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19693 if (glyph < it->glyph_row->glyphs[area + 1])
19694 {
19695 glyph->charpos = CHARPOS (it->position);
19696 glyph->object = it->object;
19697 glyph->pixel_width = it->pixel_width;
19698 glyph->ascent = it->ascent;
19699 glyph->descent = it->descent;
19700 glyph->voffset = it->voffset;
19701 glyph->type = CHAR_GLYPH;
19702 glyph->multibyte_p = it->multibyte_p;
19703 glyph->left_box_line_p = it->start_of_box_run_p;
19704 glyph->right_box_line_p = it->end_of_box_run_p;
19705 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
19706 || it->phys_descent > it->descent);
19707 glyph->padding_p = 0;
19708 glyph->glyph_not_available_p = it->glyph_not_available_p;
19709 glyph->face_id = it->face_id;
19710 glyph->u.ch = it->char_to_display;
19711 glyph->slice = null_glyph_slice;
19712 glyph->font_type = FONT_TYPE_UNKNOWN;
19713 ++it->glyph_row->used[area];
19714 }
19715 else
19716 IT_EXPAND_MATRIX_WIDTH (it, area);
19717 }
19718
19719 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
19720 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19721
19722 static INLINE void
19723 append_composite_glyph (it)
19724 struct it *it;
19725 {
19726 struct glyph *glyph;
19727 enum glyph_row_area area = it->area;
19728
19729 xassert (it->glyph_row);
19730
19731 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19732 if (glyph < it->glyph_row->glyphs[area + 1])
19733 {
19734 glyph->charpos = CHARPOS (it->position);
19735 glyph->object = it->object;
19736 glyph->pixel_width = it->pixel_width;
19737 glyph->ascent = it->ascent;
19738 glyph->descent = it->descent;
19739 glyph->voffset = it->voffset;
19740 glyph->type = COMPOSITE_GLYPH;
19741 glyph->multibyte_p = it->multibyte_p;
19742 glyph->left_box_line_p = it->start_of_box_run_p;
19743 glyph->right_box_line_p = it->end_of_box_run_p;
19744 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
19745 || it->phys_descent > it->descent);
19746 glyph->padding_p = 0;
19747 glyph->glyph_not_available_p = 0;
19748 glyph->face_id = it->face_id;
19749 glyph->u.cmp_id = it->cmp_id;
19750 glyph->slice = null_glyph_slice;
19751 glyph->font_type = FONT_TYPE_UNKNOWN;
19752 ++it->glyph_row->used[area];
19753 }
19754 else
19755 IT_EXPAND_MATRIX_WIDTH (it, area);
19756 }
19757
19758
19759 /* Change IT->ascent and IT->height according to the setting of
19760 IT->voffset. */
19761
19762 static INLINE void
19763 take_vertical_position_into_account (it)
19764 struct it *it;
19765 {
19766 if (it->voffset)
19767 {
19768 if (it->voffset < 0)
19769 /* Increase the ascent so that we can display the text higher
19770 in the line. */
19771 it->ascent -= it->voffset;
19772 else
19773 /* Increase the descent so that we can display the text lower
19774 in the line. */
19775 it->descent += it->voffset;
19776 }
19777 }
19778
19779
19780 /* Produce glyphs/get display metrics for the image IT is loaded with.
19781 See the description of struct display_iterator in dispextern.h for
19782 an overview of struct display_iterator. */
19783
19784 static void
19785 produce_image_glyph (it)
19786 struct it *it;
19787 {
19788 struct image *img;
19789 struct face *face;
19790 int glyph_ascent, crop;
19791 struct glyph_slice slice;
19792
19793 xassert (it->what == IT_IMAGE);
19794
19795 face = FACE_FROM_ID (it->f, it->face_id);
19796 xassert (face);
19797 /* Make sure X resources of the face is loaded. */
19798 PREPARE_FACE_FOR_DISPLAY (it->f, face);
19799
19800 if (it->image_id < 0)
19801 {
19802 /* Fringe bitmap. */
19803 it->ascent = it->phys_ascent = 0;
19804 it->descent = it->phys_descent = 0;
19805 it->pixel_width = 0;
19806 it->nglyphs = 0;
19807 return;
19808 }
19809
19810 img = IMAGE_FROM_ID (it->f, it->image_id);
19811 xassert (img);
19812 /* Make sure X resources of the image is loaded. */
19813 prepare_image_for_display (it->f, img);
19814
19815 slice.x = slice.y = 0;
19816 slice.width = img->width;
19817 slice.height = img->height;
19818
19819 if (INTEGERP (it->slice.x))
19820 slice.x = XINT (it->slice.x);
19821 else if (FLOATP (it->slice.x))
19822 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
19823
19824 if (INTEGERP (it->slice.y))
19825 slice.y = XINT (it->slice.y);
19826 else if (FLOATP (it->slice.y))
19827 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
19828
19829 if (INTEGERP (it->slice.width))
19830 slice.width = XINT (it->slice.width);
19831 else if (FLOATP (it->slice.width))
19832 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
19833
19834 if (INTEGERP (it->slice.height))
19835 slice.height = XINT (it->slice.height);
19836 else if (FLOATP (it->slice.height))
19837 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
19838
19839 if (slice.x >= img->width)
19840 slice.x = img->width;
19841 if (slice.y >= img->height)
19842 slice.y = img->height;
19843 if (slice.x + slice.width >= img->width)
19844 slice.width = img->width - slice.x;
19845 if (slice.y + slice.height > img->height)
19846 slice.height = img->height - slice.y;
19847
19848 if (slice.width == 0 || slice.height == 0)
19849 return;
19850
19851 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
19852
19853 it->descent = slice.height - glyph_ascent;
19854 if (slice.y == 0)
19855 it->descent += img->vmargin;
19856 if (slice.y + slice.height == img->height)
19857 it->descent += img->vmargin;
19858 it->phys_descent = it->descent;
19859
19860 it->pixel_width = slice.width;
19861 if (slice.x == 0)
19862 it->pixel_width += img->hmargin;
19863 if (slice.x + slice.width == img->width)
19864 it->pixel_width += img->hmargin;
19865
19866 /* It's quite possible for images to have an ascent greater than
19867 their height, so don't get confused in that case. */
19868 if (it->descent < 0)
19869 it->descent = 0;
19870
19871 #if 0 /* this breaks image tiling */
19872 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
19873 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
19874 if (face_ascent > it->ascent)
19875 it->ascent = it->phys_ascent = face_ascent;
19876 #endif
19877
19878 it->nglyphs = 1;
19879
19880 if (face->box != FACE_NO_BOX)
19881 {
19882 if (face->box_line_width > 0)
19883 {
19884 if (slice.y == 0)
19885 it->ascent += face->box_line_width;
19886 if (slice.y + slice.height == img->height)
19887 it->descent += face->box_line_width;
19888 }
19889
19890 if (it->start_of_box_run_p && slice.x == 0)
19891 it->pixel_width += abs (face->box_line_width);
19892 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
19893 it->pixel_width += abs (face->box_line_width);
19894 }
19895
19896 take_vertical_position_into_account (it);
19897
19898 /* Automatically crop wide image glyphs at right edge so we can
19899 draw the cursor on same display row. */
19900 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
19901 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
19902 {
19903 it->pixel_width -= crop;
19904 slice.width -= crop;
19905 }
19906
19907 if (it->glyph_row)
19908 {
19909 struct glyph *glyph;
19910 enum glyph_row_area area = it->area;
19911
19912 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19913 if (glyph < it->glyph_row->glyphs[area + 1])
19914 {
19915 glyph->charpos = CHARPOS (it->position);
19916 glyph->object = it->object;
19917 glyph->pixel_width = it->pixel_width;
19918 glyph->ascent = glyph_ascent;
19919 glyph->descent = it->descent;
19920 glyph->voffset = it->voffset;
19921 glyph->type = IMAGE_GLYPH;
19922 glyph->multibyte_p = it->multibyte_p;
19923 glyph->left_box_line_p = it->start_of_box_run_p;
19924 glyph->right_box_line_p = it->end_of_box_run_p;
19925 glyph->overlaps_vertically_p = 0;
19926 glyph->padding_p = 0;
19927 glyph->glyph_not_available_p = 0;
19928 glyph->face_id = it->face_id;
19929 glyph->u.img_id = img->id;
19930 glyph->slice = slice;
19931 glyph->font_type = FONT_TYPE_UNKNOWN;
19932 ++it->glyph_row->used[area];
19933 }
19934 else
19935 IT_EXPAND_MATRIX_WIDTH (it, area);
19936 }
19937 }
19938
19939
19940 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
19941 of the glyph, WIDTH and HEIGHT are the width and height of the
19942 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
19943
19944 static void
19945 append_stretch_glyph (it, object, width, height, ascent)
19946 struct it *it;
19947 Lisp_Object object;
19948 int width, height;
19949 int ascent;
19950 {
19951 struct glyph *glyph;
19952 enum glyph_row_area area = it->area;
19953
19954 xassert (ascent >= 0 && ascent <= height);
19955
19956 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19957 if (glyph < it->glyph_row->glyphs[area + 1])
19958 {
19959 glyph->charpos = CHARPOS (it->position);
19960 glyph->object = object;
19961 glyph->pixel_width = width;
19962 glyph->ascent = ascent;
19963 glyph->descent = height - ascent;
19964 glyph->voffset = it->voffset;
19965 glyph->type = STRETCH_GLYPH;
19966 glyph->multibyte_p = it->multibyte_p;
19967 glyph->left_box_line_p = it->start_of_box_run_p;
19968 glyph->right_box_line_p = it->end_of_box_run_p;
19969 glyph->overlaps_vertically_p = 0;
19970 glyph->padding_p = 0;
19971 glyph->glyph_not_available_p = 0;
19972 glyph->face_id = it->face_id;
19973 glyph->u.stretch.ascent = ascent;
19974 glyph->u.stretch.height = height;
19975 glyph->slice = null_glyph_slice;
19976 glyph->font_type = FONT_TYPE_UNKNOWN;
19977 ++it->glyph_row->used[area];
19978 }
19979 else
19980 IT_EXPAND_MATRIX_WIDTH (it, area);
19981 }
19982
19983
19984 /* Produce a stretch glyph for iterator IT. IT->object is the value
19985 of the glyph property displayed. The value must be a list
19986 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
19987 being recognized:
19988
19989 1. `:width WIDTH' specifies that the space should be WIDTH *
19990 canonical char width wide. WIDTH may be an integer or floating
19991 point number.
19992
19993 2. `:relative-width FACTOR' specifies that the width of the stretch
19994 should be computed from the width of the first character having the
19995 `glyph' property, and should be FACTOR times that width.
19996
19997 3. `:align-to HPOS' specifies that the space should be wide enough
19998 to reach HPOS, a value in canonical character units.
19999
20000 Exactly one of the above pairs must be present.
20001
20002 4. `:height HEIGHT' specifies that the height of the stretch produced
20003 should be HEIGHT, measured in canonical character units.
20004
20005 5. `:relative-height FACTOR' specifies that the height of the
20006 stretch should be FACTOR times the height of the characters having
20007 the glyph property.
20008
20009 Either none or exactly one of 4 or 5 must be present.
20010
20011 6. `:ascent ASCENT' specifies that ASCENT percent of the height
20012 of the stretch should be used for the ascent of the stretch.
20013 ASCENT must be in the range 0 <= ASCENT <= 100. */
20014
20015 static void
20016 produce_stretch_glyph (it)
20017 struct it *it;
20018 {
20019 /* (space :width WIDTH :height HEIGHT ...) */
20020 Lisp_Object prop, plist;
20021 int width = 0, height = 0, align_to = -1;
20022 int zero_width_ok_p = 0, zero_height_ok_p = 0;
20023 int ascent = 0;
20024 double tem;
20025 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20026 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
20027
20028 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20029
20030 /* List should start with `space'. */
20031 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
20032 plist = XCDR (it->object);
20033
20034 /* Compute the width of the stretch. */
20035 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
20036 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
20037 {
20038 /* Absolute width `:width WIDTH' specified and valid. */
20039 zero_width_ok_p = 1;
20040 width = (int)tem;
20041 }
20042 else if (prop = Fplist_get (plist, QCrelative_width),
20043 NUMVAL (prop) > 0)
20044 {
20045 /* Relative width `:relative-width FACTOR' specified and valid.
20046 Compute the width of the characters having the `glyph'
20047 property. */
20048 struct it it2;
20049 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
20050
20051 it2 = *it;
20052 if (it->multibyte_p)
20053 {
20054 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
20055 - IT_BYTEPOS (*it));
20056 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
20057 }
20058 else
20059 it2.c = *p, it2.len = 1;
20060
20061 it2.glyph_row = NULL;
20062 it2.what = IT_CHARACTER;
20063 x_produce_glyphs (&it2);
20064 width = NUMVAL (prop) * it2.pixel_width;
20065 }
20066 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
20067 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
20068 {
20069 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
20070 align_to = (align_to < 0
20071 ? 0
20072 : align_to - window_box_left_offset (it->w, TEXT_AREA));
20073 else if (align_to < 0)
20074 align_to = window_box_left_offset (it->w, TEXT_AREA);
20075 width = max (0, (int)tem + align_to - it->current_x);
20076 zero_width_ok_p = 1;
20077 }
20078 else
20079 /* Nothing specified -> width defaults to canonical char width. */
20080 width = FRAME_COLUMN_WIDTH (it->f);
20081
20082 if (width <= 0 && (width < 0 || !zero_width_ok_p))
20083 width = 1;
20084
20085 /* Compute height. */
20086 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
20087 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20088 {
20089 height = (int)tem;
20090 zero_height_ok_p = 1;
20091 }
20092 else if (prop = Fplist_get (plist, QCrelative_height),
20093 NUMVAL (prop) > 0)
20094 height = FONT_HEIGHT (font) * NUMVAL (prop);
20095 else
20096 height = FONT_HEIGHT (font);
20097
20098 if (height <= 0 && (height < 0 || !zero_height_ok_p))
20099 height = 1;
20100
20101 /* Compute percentage of height used for ascent. If
20102 `:ascent ASCENT' is present and valid, use that. Otherwise,
20103 derive the ascent from the font in use. */
20104 if (prop = Fplist_get (plist, QCascent),
20105 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
20106 ascent = height * NUMVAL (prop) / 100.0;
20107 else if (!NILP (prop)
20108 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20109 ascent = min (max (0, (int)tem), height);
20110 else
20111 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
20112
20113 if (width > 0 && !it->truncate_lines_p
20114 && it->current_x + width > it->last_visible_x)
20115 width = it->last_visible_x - it->current_x - 1;
20116
20117 if (width > 0 && height > 0 && it->glyph_row)
20118 {
20119 Lisp_Object object = it->stack[it->sp - 1].string;
20120 if (!STRINGP (object))
20121 object = it->w->buffer;
20122 append_stretch_glyph (it, object, width, height, ascent);
20123 }
20124
20125 it->pixel_width = width;
20126 it->ascent = it->phys_ascent = ascent;
20127 it->descent = it->phys_descent = height - it->ascent;
20128 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
20129
20130 take_vertical_position_into_account (it);
20131 }
20132
20133 /* Get line-height and line-spacing property at point.
20134 If line-height has format (HEIGHT TOTAL), return TOTAL
20135 in TOTAL_HEIGHT. */
20136
20137 static Lisp_Object
20138 get_line_height_property (it, prop)
20139 struct it *it;
20140 Lisp_Object prop;
20141 {
20142 Lisp_Object position;
20143
20144 if (STRINGP (it->object))
20145 position = make_number (IT_STRING_CHARPOS (*it));
20146 else if (BUFFERP (it->object))
20147 position = make_number (IT_CHARPOS (*it));
20148 else
20149 return Qnil;
20150
20151 return Fget_char_property (position, prop, it->object);
20152 }
20153
20154 /* Calculate line-height and line-spacing properties.
20155 An integer value specifies explicit pixel value.
20156 A float value specifies relative value to current face height.
20157 A cons (float . face-name) specifies relative value to
20158 height of specified face font.
20159
20160 Returns height in pixels, or nil. */
20161
20162
20163 static Lisp_Object
20164 calc_line_height_property (it, val, font, boff, override)
20165 struct it *it;
20166 Lisp_Object val;
20167 XFontStruct *font;
20168 int boff, override;
20169 {
20170 Lisp_Object face_name = Qnil;
20171 int ascent, descent, height;
20172
20173 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
20174 return val;
20175
20176 if (CONSP (val))
20177 {
20178 face_name = XCAR (val);
20179 val = XCDR (val);
20180 if (!NUMBERP (val))
20181 val = make_number (1);
20182 if (NILP (face_name))
20183 {
20184 height = it->ascent + it->descent;
20185 goto scale;
20186 }
20187 }
20188
20189 if (NILP (face_name))
20190 {
20191 font = FRAME_FONT (it->f);
20192 boff = FRAME_BASELINE_OFFSET (it->f);
20193 }
20194 else if (EQ (face_name, Qt))
20195 {
20196 override = 0;
20197 }
20198 else
20199 {
20200 int face_id;
20201 struct face *face;
20202 struct font_info *font_info;
20203
20204 face_id = lookup_named_face (it->f, face_name, ' ', 0);
20205 if (face_id < 0)
20206 return make_number (-1);
20207
20208 face = FACE_FROM_ID (it->f, face_id);
20209 font = face->font;
20210 if (font == NULL)
20211 return make_number (-1);
20212
20213 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20214 boff = font_info->baseline_offset;
20215 if (font_info->vertical_centering)
20216 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20217 }
20218
20219 ascent = FONT_BASE (font) + boff;
20220 descent = FONT_DESCENT (font) - boff;
20221
20222 if (override)
20223 {
20224 it->override_ascent = ascent;
20225 it->override_descent = descent;
20226 it->override_boff = boff;
20227 }
20228
20229 height = ascent + descent;
20230
20231 scale:
20232 if (FLOATP (val))
20233 height = (int)(XFLOAT_DATA (val) * height);
20234 else if (INTEGERP (val))
20235 height *= XINT (val);
20236
20237 return make_number (height);
20238 }
20239
20240
20241 /* RIF:
20242 Produce glyphs/get display metrics for the display element IT is
20243 loaded with. See the description of struct it in dispextern.h
20244 for an overview of struct it. */
20245
20246 void
20247 x_produce_glyphs (it)
20248 struct it *it;
20249 {
20250 int extra_line_spacing = it->extra_line_spacing;
20251
20252 it->glyph_not_available_p = 0;
20253
20254 if (it->what == IT_CHARACTER)
20255 {
20256 XChar2b char2b;
20257 XFontStruct *font;
20258 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20259 XCharStruct *pcm;
20260 int font_not_found_p;
20261 struct font_info *font_info;
20262 int boff; /* baseline offset */
20263 /* We may change it->multibyte_p upon unibyte<->multibyte
20264 conversion. So, save the current value now and restore it
20265 later.
20266
20267 Note: It seems that we don't have to record multibyte_p in
20268 struct glyph because the character code itself tells if or
20269 not the character is multibyte. Thus, in the future, we must
20270 consider eliminating the field `multibyte_p' in the struct
20271 glyph. */
20272 int saved_multibyte_p = it->multibyte_p;
20273
20274 /* Maybe translate single-byte characters to multibyte, or the
20275 other way. */
20276 it->char_to_display = it->c;
20277 if (!ASCII_BYTE_P (it->c))
20278 {
20279 if (unibyte_display_via_language_environment
20280 && SINGLE_BYTE_CHAR_P (it->c)
20281 && (it->c >= 0240
20282 || !NILP (Vnonascii_translation_table)))
20283 {
20284 it->char_to_display = unibyte_char_to_multibyte (it->c);
20285 it->multibyte_p = 1;
20286 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20287 face = FACE_FROM_ID (it->f, it->face_id);
20288 }
20289 else if (!SINGLE_BYTE_CHAR_P (it->c)
20290 && !it->multibyte_p)
20291 {
20292 it->multibyte_p = 1;
20293 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20294 face = FACE_FROM_ID (it->f, it->face_id);
20295 }
20296 }
20297
20298 /* Get font to use. Encode IT->char_to_display. */
20299 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20300 &char2b, it->multibyte_p, 0);
20301 font = face->font;
20302
20303 /* When no suitable font found, use the default font. */
20304 font_not_found_p = font == NULL;
20305 if (font_not_found_p)
20306 {
20307 font = FRAME_FONT (it->f);
20308 boff = FRAME_BASELINE_OFFSET (it->f);
20309 font_info = NULL;
20310 }
20311 else
20312 {
20313 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20314 boff = font_info->baseline_offset;
20315 if (font_info->vertical_centering)
20316 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20317 }
20318
20319 if (it->char_to_display >= ' '
20320 && (!it->multibyte_p || it->char_to_display < 128))
20321 {
20322 /* Either unibyte or ASCII. */
20323 int stretched_p;
20324
20325 it->nglyphs = 1;
20326
20327 pcm = rif->per_char_metric (font, &char2b,
20328 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
20329
20330 if (it->override_ascent >= 0)
20331 {
20332 it->ascent = it->override_ascent;
20333 it->descent = it->override_descent;
20334 boff = it->override_boff;
20335 }
20336 else
20337 {
20338 it->ascent = FONT_BASE (font) + boff;
20339 it->descent = FONT_DESCENT (font) - boff;
20340 }
20341
20342 if (pcm)
20343 {
20344 it->phys_ascent = pcm->ascent + boff;
20345 it->phys_descent = pcm->descent - boff;
20346 it->pixel_width = pcm->width;
20347 }
20348 else
20349 {
20350 it->glyph_not_available_p = 1;
20351 it->phys_ascent = it->ascent;
20352 it->phys_descent = it->descent;
20353 it->pixel_width = FONT_WIDTH (font);
20354 }
20355
20356 if (it->constrain_row_ascent_descent_p)
20357 {
20358 if (it->descent > it->max_descent)
20359 {
20360 it->ascent += it->descent - it->max_descent;
20361 it->descent = it->max_descent;
20362 }
20363 if (it->ascent > it->max_ascent)
20364 {
20365 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20366 it->ascent = it->max_ascent;
20367 }
20368 it->phys_ascent = min (it->phys_ascent, it->ascent);
20369 it->phys_descent = min (it->phys_descent, it->descent);
20370 extra_line_spacing = 0;
20371 }
20372
20373 /* If this is a space inside a region of text with
20374 `space-width' property, change its width. */
20375 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
20376 if (stretched_p)
20377 it->pixel_width *= XFLOATINT (it->space_width);
20378
20379 /* If face has a box, add the box thickness to the character
20380 height. If character has a box line to the left and/or
20381 right, add the box line width to the character's width. */
20382 if (face->box != FACE_NO_BOX)
20383 {
20384 int thick = face->box_line_width;
20385
20386 if (thick > 0)
20387 {
20388 it->ascent += thick;
20389 it->descent += thick;
20390 }
20391 else
20392 thick = -thick;
20393
20394 if (it->start_of_box_run_p)
20395 it->pixel_width += thick;
20396 if (it->end_of_box_run_p)
20397 it->pixel_width += thick;
20398 }
20399
20400 /* If face has an overline, add the height of the overline
20401 (1 pixel) and a 1 pixel margin to the character height. */
20402 if (face->overline_p)
20403 it->ascent += overline_margin;
20404
20405 if (it->constrain_row_ascent_descent_p)
20406 {
20407 if (it->ascent > it->max_ascent)
20408 it->ascent = it->max_ascent;
20409 if (it->descent > it->max_descent)
20410 it->descent = it->max_descent;
20411 }
20412
20413 take_vertical_position_into_account (it);
20414
20415 /* If we have to actually produce glyphs, do it. */
20416 if (it->glyph_row)
20417 {
20418 if (stretched_p)
20419 {
20420 /* Translate a space with a `space-width' property
20421 into a stretch glyph. */
20422 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
20423 / FONT_HEIGHT (font));
20424 append_stretch_glyph (it, it->object, it->pixel_width,
20425 it->ascent + it->descent, ascent);
20426 }
20427 else
20428 append_glyph (it);
20429
20430 /* If characters with lbearing or rbearing are displayed
20431 in this line, record that fact in a flag of the
20432 glyph row. This is used to optimize X output code. */
20433 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
20434 it->glyph_row->contains_overlapping_glyphs_p = 1;
20435 }
20436 }
20437 else if (it->char_to_display == '\n')
20438 {
20439 /* A newline has no width but we need the height of the line.
20440 But if previous part of the line set a height, don't
20441 increase that height */
20442
20443 Lisp_Object height;
20444 Lisp_Object total_height = Qnil;
20445
20446 it->override_ascent = -1;
20447 it->pixel_width = 0;
20448 it->nglyphs = 0;
20449
20450 height = get_line_height_property(it, Qline_height);
20451 /* Split (line-height total-height) list */
20452 if (CONSP (height)
20453 && CONSP (XCDR (height))
20454 && NILP (XCDR (XCDR (height))))
20455 {
20456 total_height = XCAR (XCDR (height));
20457 height = XCAR (height);
20458 }
20459 height = calc_line_height_property(it, height, font, boff, 1);
20460
20461 if (it->override_ascent >= 0)
20462 {
20463 it->ascent = it->override_ascent;
20464 it->descent = it->override_descent;
20465 boff = it->override_boff;
20466 }
20467 else
20468 {
20469 it->ascent = FONT_BASE (font) + boff;
20470 it->descent = FONT_DESCENT (font) - boff;
20471 }
20472
20473 if (EQ (height, Qt))
20474 {
20475 if (it->descent > it->max_descent)
20476 {
20477 it->ascent += it->descent - it->max_descent;
20478 it->descent = it->max_descent;
20479 }
20480 if (it->ascent > it->max_ascent)
20481 {
20482 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20483 it->ascent = it->max_ascent;
20484 }
20485 it->phys_ascent = min (it->phys_ascent, it->ascent);
20486 it->phys_descent = min (it->phys_descent, it->descent);
20487 it->constrain_row_ascent_descent_p = 1;
20488 extra_line_spacing = 0;
20489 }
20490 else
20491 {
20492 Lisp_Object spacing;
20493
20494 it->phys_ascent = it->ascent;
20495 it->phys_descent = it->descent;
20496
20497 if ((it->max_ascent > 0 || it->max_descent > 0)
20498 && face->box != FACE_NO_BOX
20499 && face->box_line_width > 0)
20500 {
20501 it->ascent += face->box_line_width;
20502 it->descent += face->box_line_width;
20503 }
20504 if (!NILP (height)
20505 && XINT (height) > it->ascent + it->descent)
20506 it->ascent = XINT (height) - it->descent;
20507
20508 if (!NILP (total_height))
20509 spacing = calc_line_height_property(it, total_height, font, boff, 0);
20510 else
20511 {
20512 spacing = get_line_height_property(it, Qline_spacing);
20513 spacing = calc_line_height_property(it, spacing, font, boff, 0);
20514 }
20515 if (INTEGERP (spacing))
20516 {
20517 extra_line_spacing = XINT (spacing);
20518 if (!NILP (total_height))
20519 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20520 }
20521 }
20522 }
20523 else if (it->char_to_display == '\t')
20524 {
20525 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
20526 int x = it->current_x + it->continuation_lines_width;
20527 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
20528
20529 /* If the distance from the current position to the next tab
20530 stop is less than a space character width, use the
20531 tab stop after that. */
20532 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
20533 next_tab_x += tab_width;
20534
20535 it->pixel_width = next_tab_x - x;
20536 it->nglyphs = 1;
20537 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
20538 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
20539
20540 if (it->glyph_row)
20541 {
20542 append_stretch_glyph (it, it->object, it->pixel_width,
20543 it->ascent + it->descent, it->ascent);
20544 }
20545 }
20546 else
20547 {
20548 /* A multi-byte character. Assume that the display width of the
20549 character is the width of the character multiplied by the
20550 width of the font. */
20551
20552 /* If we found a font, this font should give us the right
20553 metrics. If we didn't find a font, use the frame's
20554 default font and calculate the width of the character
20555 from the charset width; this is what old redisplay code
20556 did. */
20557
20558 pcm = rif->per_char_metric (font, &char2b,
20559 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
20560
20561 if (font_not_found_p || !pcm)
20562 {
20563 int charset = CHAR_CHARSET (it->char_to_display);
20564
20565 it->glyph_not_available_p = 1;
20566 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
20567 * CHARSET_WIDTH (charset));
20568 it->phys_ascent = FONT_BASE (font) + boff;
20569 it->phys_descent = FONT_DESCENT (font) - boff;
20570 }
20571 else
20572 {
20573 it->pixel_width = pcm->width;
20574 it->phys_ascent = pcm->ascent + boff;
20575 it->phys_descent = pcm->descent - boff;
20576 if (it->glyph_row
20577 && (pcm->lbearing < 0
20578 || pcm->rbearing > pcm->width))
20579 it->glyph_row->contains_overlapping_glyphs_p = 1;
20580 }
20581 it->nglyphs = 1;
20582 it->ascent = FONT_BASE (font) + boff;
20583 it->descent = FONT_DESCENT (font) - boff;
20584 if (face->box != FACE_NO_BOX)
20585 {
20586 int thick = face->box_line_width;
20587
20588 if (thick > 0)
20589 {
20590 it->ascent += thick;
20591 it->descent += thick;
20592 }
20593 else
20594 thick = - thick;
20595
20596 if (it->start_of_box_run_p)
20597 it->pixel_width += thick;
20598 if (it->end_of_box_run_p)
20599 it->pixel_width += thick;
20600 }
20601
20602 /* If face has an overline, add the height of the overline
20603 (1 pixel) and a 1 pixel margin to the character height. */
20604 if (face->overline_p)
20605 it->ascent += overline_margin;
20606
20607 take_vertical_position_into_account (it);
20608
20609 if (it->glyph_row)
20610 append_glyph (it);
20611 }
20612 it->multibyte_p = saved_multibyte_p;
20613 }
20614 else if (it->what == IT_COMPOSITION)
20615 {
20616 /* Note: A composition is represented as one glyph in the
20617 glyph matrix. There are no padding glyphs. */
20618 XChar2b char2b;
20619 XFontStruct *font;
20620 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20621 XCharStruct *pcm;
20622 int font_not_found_p;
20623 struct font_info *font_info;
20624 int boff; /* baseline offset */
20625 struct composition *cmp = composition_table[it->cmp_id];
20626
20627 /* Maybe translate single-byte characters to multibyte. */
20628 it->char_to_display = it->c;
20629 if (unibyte_display_via_language_environment
20630 && SINGLE_BYTE_CHAR_P (it->c)
20631 && (it->c >= 0240
20632 || (it->c >= 0200
20633 && !NILP (Vnonascii_translation_table))))
20634 {
20635 it->char_to_display = unibyte_char_to_multibyte (it->c);
20636 }
20637
20638 /* Get face and font to use. Encode IT->char_to_display. */
20639 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20640 face = FACE_FROM_ID (it->f, it->face_id);
20641 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20642 &char2b, it->multibyte_p, 0);
20643 font = face->font;
20644
20645 /* When no suitable font found, use the default font. */
20646 font_not_found_p = font == NULL;
20647 if (font_not_found_p)
20648 {
20649 font = FRAME_FONT (it->f);
20650 boff = FRAME_BASELINE_OFFSET (it->f);
20651 font_info = NULL;
20652 }
20653 else
20654 {
20655 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20656 boff = font_info->baseline_offset;
20657 if (font_info->vertical_centering)
20658 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20659 }
20660
20661 /* There are no padding glyphs, so there is only one glyph to
20662 produce for the composition. Important is that pixel_width,
20663 ascent and descent are the values of what is drawn by
20664 draw_glyphs (i.e. the values of the overall glyphs composed). */
20665 it->nglyphs = 1;
20666
20667 /* If we have not yet calculated pixel size data of glyphs of
20668 the composition for the current face font, calculate them
20669 now. Theoretically, we have to check all fonts for the
20670 glyphs, but that requires much time and memory space. So,
20671 here we check only the font of the first glyph. This leads
20672 to incorrect display very rarely, and C-l (recenter) can
20673 correct the display anyway. */
20674 if (cmp->font != (void *) font)
20675 {
20676 /* Ascent and descent of the font of the first character of
20677 this composition (adjusted by baseline offset). Ascent
20678 and descent of overall glyphs should not be less than
20679 them respectively. */
20680 int font_ascent = FONT_BASE (font) + boff;
20681 int font_descent = FONT_DESCENT (font) - boff;
20682 /* Bounding box of the overall glyphs. */
20683 int leftmost, rightmost, lowest, highest;
20684 int i, width, ascent, descent;
20685
20686 cmp->font = (void *) font;
20687
20688 /* Initialize the bounding box. */
20689 if (font_info
20690 && (pcm = rif->per_char_metric (font, &char2b,
20691 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
20692 {
20693 width = pcm->width;
20694 ascent = pcm->ascent;
20695 descent = pcm->descent;
20696 }
20697 else
20698 {
20699 width = FONT_WIDTH (font);
20700 ascent = FONT_BASE (font);
20701 descent = FONT_DESCENT (font);
20702 }
20703
20704 rightmost = width;
20705 lowest = - descent + boff;
20706 highest = ascent + boff;
20707 leftmost = 0;
20708
20709 if (font_info
20710 && font_info->default_ascent
20711 && CHAR_TABLE_P (Vuse_default_ascent)
20712 && !NILP (Faref (Vuse_default_ascent,
20713 make_number (it->char_to_display))))
20714 highest = font_info->default_ascent + boff;
20715
20716 /* Draw the first glyph at the normal position. It may be
20717 shifted to right later if some other glyphs are drawn at
20718 the left. */
20719 cmp->offsets[0] = 0;
20720 cmp->offsets[1] = boff;
20721
20722 /* Set cmp->offsets for the remaining glyphs. */
20723 for (i = 1; i < cmp->glyph_len; i++)
20724 {
20725 int left, right, btm, top;
20726 int ch = COMPOSITION_GLYPH (cmp, i);
20727 int face_id = FACE_FOR_CHAR (it->f, face, ch);
20728
20729 face = FACE_FROM_ID (it->f, face_id);
20730 get_char_face_and_encoding (it->f, ch, face->id,
20731 &char2b, it->multibyte_p, 0);
20732 font = face->font;
20733 if (font == NULL)
20734 {
20735 font = FRAME_FONT (it->f);
20736 boff = FRAME_BASELINE_OFFSET (it->f);
20737 font_info = NULL;
20738 }
20739 else
20740 {
20741 font_info
20742 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20743 boff = font_info->baseline_offset;
20744 if (font_info->vertical_centering)
20745 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20746 }
20747
20748 if (font_info
20749 && (pcm = rif->per_char_metric (font, &char2b,
20750 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
20751 {
20752 width = pcm->width;
20753 ascent = pcm->ascent;
20754 descent = pcm->descent;
20755 }
20756 else
20757 {
20758 width = FONT_WIDTH (font);
20759 ascent = 1;
20760 descent = 0;
20761 }
20762
20763 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
20764 {
20765 /* Relative composition with or without
20766 alternate chars. */
20767 left = (leftmost + rightmost - width) / 2;
20768 btm = - descent + boff;
20769 if (font_info && font_info->relative_compose
20770 && (! CHAR_TABLE_P (Vignore_relative_composition)
20771 || NILP (Faref (Vignore_relative_composition,
20772 make_number (ch)))))
20773 {
20774
20775 if (- descent >= font_info->relative_compose)
20776 /* One extra pixel between two glyphs. */
20777 btm = highest + 1;
20778 else if (ascent <= 0)
20779 /* One extra pixel between two glyphs. */
20780 btm = lowest - 1 - ascent - descent;
20781 }
20782 }
20783 else
20784 {
20785 /* A composition rule is specified by an integer
20786 value that encodes global and new reference
20787 points (GREF and NREF). GREF and NREF are
20788 specified by numbers as below:
20789
20790 0---1---2 -- ascent
20791 | |
20792 | |
20793 | |
20794 9--10--11 -- center
20795 | |
20796 ---3---4---5--- baseline
20797 | |
20798 6---7---8 -- descent
20799 */
20800 int rule = COMPOSITION_RULE (cmp, i);
20801 int gref, nref, grefx, grefy, nrefx, nrefy;
20802
20803 COMPOSITION_DECODE_RULE (rule, gref, nref);
20804 grefx = gref % 3, nrefx = nref % 3;
20805 grefy = gref / 3, nrefy = nref / 3;
20806
20807 left = (leftmost
20808 + grefx * (rightmost - leftmost) / 2
20809 - nrefx * width / 2);
20810 btm = ((grefy == 0 ? highest
20811 : grefy == 1 ? 0
20812 : grefy == 2 ? lowest
20813 : (highest + lowest) / 2)
20814 - (nrefy == 0 ? ascent + descent
20815 : nrefy == 1 ? descent - boff
20816 : nrefy == 2 ? 0
20817 : (ascent + descent) / 2));
20818 }
20819
20820 cmp->offsets[i * 2] = left;
20821 cmp->offsets[i * 2 + 1] = btm + descent;
20822
20823 /* Update the bounding box of the overall glyphs. */
20824 right = left + width;
20825 top = btm + descent + ascent;
20826 if (left < leftmost)
20827 leftmost = left;
20828 if (right > rightmost)
20829 rightmost = right;
20830 if (top > highest)
20831 highest = top;
20832 if (btm < lowest)
20833 lowest = btm;
20834 }
20835
20836 /* If there are glyphs whose x-offsets are negative,
20837 shift all glyphs to the right and make all x-offsets
20838 non-negative. */
20839 if (leftmost < 0)
20840 {
20841 for (i = 0; i < cmp->glyph_len; i++)
20842 cmp->offsets[i * 2] -= leftmost;
20843 rightmost -= leftmost;
20844 }
20845
20846 cmp->pixel_width = rightmost;
20847 cmp->ascent = highest;
20848 cmp->descent = - lowest;
20849 if (cmp->ascent < font_ascent)
20850 cmp->ascent = font_ascent;
20851 if (cmp->descent < font_descent)
20852 cmp->descent = font_descent;
20853 }
20854
20855 it->pixel_width = cmp->pixel_width;
20856 it->ascent = it->phys_ascent = cmp->ascent;
20857 it->descent = it->phys_descent = cmp->descent;
20858
20859 if (face->box != FACE_NO_BOX)
20860 {
20861 int thick = face->box_line_width;
20862
20863 if (thick > 0)
20864 {
20865 it->ascent += thick;
20866 it->descent += thick;
20867 }
20868 else
20869 thick = - thick;
20870
20871 if (it->start_of_box_run_p)
20872 it->pixel_width += thick;
20873 if (it->end_of_box_run_p)
20874 it->pixel_width += thick;
20875 }
20876
20877 /* If face has an overline, add the height of the overline
20878 (1 pixel) and a 1 pixel margin to the character height. */
20879 if (face->overline_p)
20880 it->ascent += overline_margin;
20881
20882 take_vertical_position_into_account (it);
20883
20884 if (it->glyph_row)
20885 append_composite_glyph (it);
20886 }
20887 else if (it->what == IT_IMAGE)
20888 produce_image_glyph (it);
20889 else if (it->what == IT_STRETCH)
20890 produce_stretch_glyph (it);
20891
20892 /* Accumulate dimensions. Note: can't assume that it->descent > 0
20893 because this isn't true for images with `:ascent 100'. */
20894 xassert (it->ascent >= 0 && it->descent >= 0);
20895 if (it->area == TEXT_AREA)
20896 it->current_x += it->pixel_width;
20897
20898 if (extra_line_spacing > 0)
20899 {
20900 it->descent += extra_line_spacing;
20901 if (extra_line_spacing > it->max_extra_line_spacing)
20902 it->max_extra_line_spacing = extra_line_spacing;
20903 }
20904
20905 it->max_ascent = max (it->max_ascent, it->ascent);
20906 it->max_descent = max (it->max_descent, it->descent);
20907 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
20908 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
20909 }
20910
20911 /* EXPORT for RIF:
20912 Output LEN glyphs starting at START at the nominal cursor position.
20913 Advance the nominal cursor over the text. The global variable
20914 updated_window contains the window being updated, updated_row is
20915 the glyph row being updated, and updated_area is the area of that
20916 row being updated. */
20917
20918 void
20919 x_write_glyphs (start, len)
20920 struct glyph *start;
20921 int len;
20922 {
20923 int x, hpos;
20924
20925 xassert (updated_window && updated_row);
20926 BLOCK_INPUT;
20927
20928 /* Write glyphs. */
20929
20930 hpos = start - updated_row->glyphs[updated_area];
20931 x = draw_glyphs (updated_window, output_cursor.x,
20932 updated_row, updated_area,
20933 hpos, hpos + len,
20934 DRAW_NORMAL_TEXT, 0);
20935
20936 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
20937 if (updated_area == TEXT_AREA
20938 && updated_window->phys_cursor_on_p
20939 && updated_window->phys_cursor.vpos == output_cursor.vpos
20940 && updated_window->phys_cursor.hpos >= hpos
20941 && updated_window->phys_cursor.hpos < hpos + len)
20942 updated_window->phys_cursor_on_p = 0;
20943
20944 UNBLOCK_INPUT;
20945
20946 /* Advance the output cursor. */
20947 output_cursor.hpos += len;
20948 output_cursor.x = x;
20949 }
20950
20951
20952 /* EXPORT for RIF:
20953 Insert LEN glyphs from START at the nominal cursor position. */
20954
20955 void
20956 x_insert_glyphs (start, len)
20957 struct glyph *start;
20958 int len;
20959 {
20960 struct frame *f;
20961 struct window *w;
20962 int line_height, shift_by_width, shifted_region_width;
20963 struct glyph_row *row;
20964 struct glyph *glyph;
20965 int frame_x, frame_y, hpos;
20966
20967 xassert (updated_window && updated_row);
20968 BLOCK_INPUT;
20969 w = updated_window;
20970 f = XFRAME (WINDOW_FRAME (w));
20971
20972 /* Get the height of the line we are in. */
20973 row = updated_row;
20974 line_height = row->height;
20975
20976 /* Get the width of the glyphs to insert. */
20977 shift_by_width = 0;
20978 for (glyph = start; glyph < start + len; ++glyph)
20979 shift_by_width += glyph->pixel_width;
20980
20981 /* Get the width of the region to shift right. */
20982 shifted_region_width = (window_box_width (w, updated_area)
20983 - output_cursor.x
20984 - shift_by_width);
20985
20986 /* Shift right. */
20987 frame_x = window_box_left (w, updated_area) + output_cursor.x;
20988 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
20989
20990 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
20991 line_height, shift_by_width);
20992
20993 /* Write the glyphs. */
20994 hpos = start - row->glyphs[updated_area];
20995 draw_glyphs (w, output_cursor.x, row, updated_area,
20996 hpos, hpos + len,
20997 DRAW_NORMAL_TEXT, 0);
20998
20999 /* Advance the output cursor. */
21000 output_cursor.hpos += len;
21001 output_cursor.x += shift_by_width;
21002 UNBLOCK_INPUT;
21003 }
21004
21005
21006 /* EXPORT for RIF:
21007 Erase the current text line from the nominal cursor position
21008 (inclusive) to pixel column TO_X (exclusive). The idea is that
21009 everything from TO_X onward is already erased.
21010
21011 TO_X is a pixel position relative to updated_area of
21012 updated_window. TO_X == -1 means clear to the end of this area. */
21013
21014 void
21015 x_clear_end_of_line (to_x)
21016 int to_x;
21017 {
21018 struct frame *f;
21019 struct window *w = updated_window;
21020 int max_x, min_y, max_y;
21021 int from_x, from_y, to_y;
21022
21023 xassert (updated_window && updated_row);
21024 f = XFRAME (w->frame);
21025
21026 if (updated_row->full_width_p)
21027 max_x = WINDOW_TOTAL_WIDTH (w);
21028 else
21029 max_x = window_box_width (w, updated_area);
21030 max_y = window_text_bottom_y (w);
21031
21032 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
21033 of window. For TO_X > 0, truncate to end of drawing area. */
21034 if (to_x == 0)
21035 return;
21036 else if (to_x < 0)
21037 to_x = max_x;
21038 else
21039 to_x = min (to_x, max_x);
21040
21041 to_y = min (max_y, output_cursor.y + updated_row->height);
21042
21043 /* Notice if the cursor will be cleared by this operation. */
21044 if (!updated_row->full_width_p)
21045 notice_overwritten_cursor (w, updated_area,
21046 output_cursor.x, -1,
21047 updated_row->y,
21048 MATRIX_ROW_BOTTOM_Y (updated_row));
21049
21050 from_x = output_cursor.x;
21051
21052 /* Translate to frame coordinates. */
21053 if (updated_row->full_width_p)
21054 {
21055 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
21056 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
21057 }
21058 else
21059 {
21060 int area_left = window_box_left (w, updated_area);
21061 from_x += area_left;
21062 to_x += area_left;
21063 }
21064
21065 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
21066 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
21067 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
21068
21069 /* Prevent inadvertently clearing to end of the X window. */
21070 if (to_x > from_x && to_y > from_y)
21071 {
21072 BLOCK_INPUT;
21073 rif->clear_frame_area (f, from_x, from_y,
21074 to_x - from_x, to_y - from_y);
21075 UNBLOCK_INPUT;
21076 }
21077 }
21078
21079 #endif /* HAVE_WINDOW_SYSTEM */
21080
21081
21082 \f
21083 /***********************************************************************
21084 Cursor types
21085 ***********************************************************************/
21086
21087 /* Value is the internal representation of the specified cursor type
21088 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
21089 of the bar cursor. */
21090
21091 static enum text_cursor_kinds
21092 get_specified_cursor_type (arg, width)
21093 Lisp_Object arg;
21094 int *width;
21095 {
21096 enum text_cursor_kinds type;
21097
21098 if (NILP (arg))
21099 return NO_CURSOR;
21100
21101 if (EQ (arg, Qbox))
21102 return FILLED_BOX_CURSOR;
21103
21104 if (EQ (arg, Qhollow))
21105 return HOLLOW_BOX_CURSOR;
21106
21107 if (EQ (arg, Qbar))
21108 {
21109 *width = 2;
21110 return BAR_CURSOR;
21111 }
21112
21113 if (CONSP (arg)
21114 && EQ (XCAR (arg), Qbar)
21115 && INTEGERP (XCDR (arg))
21116 && XINT (XCDR (arg)) >= 0)
21117 {
21118 *width = XINT (XCDR (arg));
21119 return BAR_CURSOR;
21120 }
21121
21122 if (EQ (arg, Qhbar))
21123 {
21124 *width = 2;
21125 return HBAR_CURSOR;
21126 }
21127
21128 if (CONSP (arg)
21129 && EQ (XCAR (arg), Qhbar)
21130 && INTEGERP (XCDR (arg))
21131 && XINT (XCDR (arg)) >= 0)
21132 {
21133 *width = XINT (XCDR (arg));
21134 return HBAR_CURSOR;
21135 }
21136
21137 /* Treat anything unknown as "hollow box cursor".
21138 It was bad to signal an error; people have trouble fixing
21139 .Xdefaults with Emacs, when it has something bad in it. */
21140 type = HOLLOW_BOX_CURSOR;
21141
21142 return type;
21143 }
21144
21145 /* Set the default cursor types for specified frame. */
21146 void
21147 set_frame_cursor_types (f, arg)
21148 struct frame *f;
21149 Lisp_Object arg;
21150 {
21151 int width;
21152 Lisp_Object tem;
21153
21154 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
21155 FRAME_CURSOR_WIDTH (f) = width;
21156
21157 /* By default, set up the blink-off state depending on the on-state. */
21158
21159 tem = Fassoc (arg, Vblink_cursor_alist);
21160 if (!NILP (tem))
21161 {
21162 FRAME_BLINK_OFF_CURSOR (f)
21163 = get_specified_cursor_type (XCDR (tem), &width);
21164 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
21165 }
21166 else
21167 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
21168 }
21169
21170
21171 /* Return the cursor we want to be displayed in window W. Return
21172 width of bar/hbar cursor through WIDTH arg. Return with
21173 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
21174 (i.e. if the `system caret' should track this cursor).
21175
21176 In a mini-buffer window, we want the cursor only to appear if we
21177 are reading input from this window. For the selected window, we
21178 want the cursor type given by the frame parameter or buffer local
21179 setting of cursor-type. If explicitly marked off, draw no cursor.
21180 In all other cases, we want a hollow box cursor. */
21181
21182 static enum text_cursor_kinds
21183 get_window_cursor_type (w, glyph, width, active_cursor)
21184 struct window *w;
21185 struct glyph *glyph;
21186 int *width;
21187 int *active_cursor;
21188 {
21189 struct frame *f = XFRAME (w->frame);
21190 struct buffer *b = XBUFFER (w->buffer);
21191 int cursor_type = DEFAULT_CURSOR;
21192 Lisp_Object alt_cursor;
21193 int non_selected = 0;
21194
21195 *active_cursor = 1;
21196
21197 /* Echo area */
21198 if (cursor_in_echo_area
21199 && FRAME_HAS_MINIBUF_P (f)
21200 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
21201 {
21202 if (w == XWINDOW (echo_area_window))
21203 {
21204 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
21205 {
21206 *width = FRAME_CURSOR_WIDTH (f);
21207 return FRAME_DESIRED_CURSOR (f);
21208 }
21209 else
21210 return get_specified_cursor_type (b->cursor_type, width);
21211 }
21212
21213 *active_cursor = 0;
21214 non_selected = 1;
21215 }
21216
21217 /* Nonselected window or nonselected frame. */
21218 else if (w != XWINDOW (f->selected_window)
21219 #ifdef HAVE_WINDOW_SYSTEM
21220 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
21221 #endif
21222 )
21223 {
21224 *active_cursor = 0;
21225
21226 if (MINI_WINDOW_P (w) && minibuf_level == 0)
21227 return NO_CURSOR;
21228
21229 non_selected = 1;
21230 }
21231
21232 /* Never display a cursor in a window in which cursor-type is nil. */
21233 if (NILP (b->cursor_type))
21234 return NO_CURSOR;
21235
21236 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
21237 if (non_selected)
21238 {
21239 alt_cursor = b->cursor_in_non_selected_windows;
21240 return get_specified_cursor_type (alt_cursor, width);
21241 }
21242
21243 /* Get the normal cursor type for this window. */
21244 if (EQ (b->cursor_type, Qt))
21245 {
21246 cursor_type = FRAME_DESIRED_CURSOR (f);
21247 *width = FRAME_CURSOR_WIDTH (f);
21248 }
21249 else
21250 cursor_type = get_specified_cursor_type (b->cursor_type, width);
21251
21252 /* Use normal cursor if not blinked off. */
21253 if (!w->cursor_off_p)
21254 {
21255 #ifdef HAVE_WINDOW_SYSTEM
21256 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21257 {
21258 if (cursor_type == FILLED_BOX_CURSOR)
21259 {
21260 /* Using a block cursor on large images can be very annoying.
21261 So use a hollow cursor for "large" images.
21262 If image is not transparent (no mask), also use hollow cursor. */
21263 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21264 if (img != NULL && IMAGEP (img->spec))
21265 {
21266 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
21267 where N = size of default frame font size.
21268 This should cover most of the "tiny" icons people may use. */
21269 if (!img->mask
21270 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
21271 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
21272 cursor_type = HOLLOW_BOX_CURSOR;
21273 }
21274 }
21275 else if (cursor_type != NO_CURSOR)
21276 {
21277 /* Display current only supports BOX and HOLLOW cursors for images.
21278 So for now, unconditionally use a HOLLOW cursor when cursor is
21279 not a solid box cursor. */
21280 cursor_type = HOLLOW_BOX_CURSOR;
21281 }
21282 }
21283 #endif
21284 return cursor_type;
21285 }
21286
21287 /* Cursor is blinked off, so determine how to "toggle" it. */
21288
21289 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
21290 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
21291 return get_specified_cursor_type (XCDR (alt_cursor), width);
21292
21293 /* Then see if frame has specified a specific blink off cursor type. */
21294 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
21295 {
21296 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
21297 return FRAME_BLINK_OFF_CURSOR (f);
21298 }
21299
21300 #if 0
21301 /* Some people liked having a permanently visible blinking cursor,
21302 while others had very strong opinions against it. So it was
21303 decided to remove it. KFS 2003-09-03 */
21304
21305 /* Finally perform built-in cursor blinking:
21306 filled box <-> hollow box
21307 wide [h]bar <-> narrow [h]bar
21308 narrow [h]bar <-> no cursor
21309 other type <-> no cursor */
21310
21311 if (cursor_type == FILLED_BOX_CURSOR)
21312 return HOLLOW_BOX_CURSOR;
21313
21314 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
21315 {
21316 *width = 1;
21317 return cursor_type;
21318 }
21319 #endif
21320
21321 return NO_CURSOR;
21322 }
21323
21324
21325 #ifdef HAVE_WINDOW_SYSTEM
21326
21327 /* Notice when the text cursor of window W has been completely
21328 overwritten by a drawing operation that outputs glyphs in AREA
21329 starting at X0 and ending at X1 in the line starting at Y0 and
21330 ending at Y1. X coordinates are area-relative. X1 < 0 means all
21331 the rest of the line after X0 has been written. Y coordinates
21332 are window-relative. */
21333
21334 static void
21335 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
21336 struct window *w;
21337 enum glyph_row_area area;
21338 int x0, y0, x1, y1;
21339 {
21340 int cx0, cx1, cy0, cy1;
21341 struct glyph_row *row;
21342
21343 if (!w->phys_cursor_on_p)
21344 return;
21345 if (area != TEXT_AREA)
21346 return;
21347
21348 if (w->phys_cursor.vpos < 0
21349 || w->phys_cursor.vpos >= w->current_matrix->nrows
21350 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
21351 !(row->enabled_p && row->displays_text_p)))
21352 return;
21353
21354 if (row->cursor_in_fringe_p)
21355 {
21356 row->cursor_in_fringe_p = 0;
21357 draw_fringe_bitmap (w, row, 0);
21358 w->phys_cursor_on_p = 0;
21359 return;
21360 }
21361
21362 cx0 = w->phys_cursor.x;
21363 cx1 = cx0 + w->phys_cursor_width;
21364 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
21365 return;
21366
21367 /* The cursor image will be completely removed from the
21368 screen if the output area intersects the cursor area in
21369 y-direction. When we draw in [y0 y1[, and some part of
21370 the cursor is at y < y0, that part must have been drawn
21371 before. When scrolling, the cursor is erased before
21372 actually scrolling, so we don't come here. When not
21373 scrolling, the rows above the old cursor row must have
21374 changed, and in this case these rows must have written
21375 over the cursor image.
21376
21377 Likewise if part of the cursor is below y1, with the
21378 exception of the cursor being in the first blank row at
21379 the buffer and window end because update_text_area
21380 doesn't draw that row. (Except when it does, but
21381 that's handled in update_text_area.) */
21382
21383 cy0 = w->phys_cursor.y;
21384 cy1 = cy0 + w->phys_cursor_height;
21385 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
21386 return;
21387
21388 w->phys_cursor_on_p = 0;
21389 }
21390
21391 #endif /* HAVE_WINDOW_SYSTEM */
21392
21393 \f
21394 /************************************************************************
21395 Mouse Face
21396 ************************************************************************/
21397
21398 #ifdef HAVE_WINDOW_SYSTEM
21399
21400 /* EXPORT for RIF:
21401 Fix the display of area AREA of overlapping row ROW in window W
21402 with respect to the overlapping part OVERLAPS. */
21403
21404 void
21405 x_fix_overlapping_area (w, row, area, overlaps)
21406 struct window *w;
21407 struct glyph_row *row;
21408 enum glyph_row_area area;
21409 int overlaps;
21410 {
21411 int i, x;
21412
21413 BLOCK_INPUT;
21414
21415 x = 0;
21416 for (i = 0; i < row->used[area];)
21417 {
21418 if (row->glyphs[area][i].overlaps_vertically_p)
21419 {
21420 int start = i, start_x = x;
21421
21422 do
21423 {
21424 x += row->glyphs[area][i].pixel_width;
21425 ++i;
21426 }
21427 while (i < row->used[area]
21428 && row->glyphs[area][i].overlaps_vertically_p);
21429
21430 draw_glyphs (w, start_x, row, area,
21431 start, i,
21432 DRAW_NORMAL_TEXT, overlaps);
21433 }
21434 else
21435 {
21436 x += row->glyphs[area][i].pixel_width;
21437 ++i;
21438 }
21439 }
21440
21441 UNBLOCK_INPUT;
21442 }
21443
21444
21445 /* EXPORT:
21446 Draw the cursor glyph of window W in glyph row ROW. See the
21447 comment of draw_glyphs for the meaning of HL. */
21448
21449 void
21450 draw_phys_cursor_glyph (w, row, hl)
21451 struct window *w;
21452 struct glyph_row *row;
21453 enum draw_glyphs_face hl;
21454 {
21455 /* If cursor hpos is out of bounds, don't draw garbage. This can
21456 happen in mini-buffer windows when switching between echo area
21457 glyphs and mini-buffer. */
21458 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
21459 {
21460 int on_p = w->phys_cursor_on_p;
21461 int x1;
21462 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
21463 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
21464 hl, 0);
21465 w->phys_cursor_on_p = on_p;
21466
21467 if (hl == DRAW_CURSOR)
21468 w->phys_cursor_width = x1 - w->phys_cursor.x;
21469 /* When we erase the cursor, and ROW is overlapped by other
21470 rows, make sure that these overlapping parts of other rows
21471 are redrawn. */
21472 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
21473 {
21474 w->phys_cursor_width = x1 - w->phys_cursor.x;
21475
21476 if (row > w->current_matrix->rows
21477 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
21478 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
21479 OVERLAPS_ERASED_CURSOR);
21480
21481 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
21482 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
21483 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
21484 OVERLAPS_ERASED_CURSOR);
21485 }
21486 }
21487 }
21488
21489
21490 /* EXPORT:
21491 Erase the image of a cursor of window W from the screen. */
21492
21493 void
21494 erase_phys_cursor (w)
21495 struct window *w;
21496 {
21497 struct frame *f = XFRAME (w->frame);
21498 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21499 int hpos = w->phys_cursor.hpos;
21500 int vpos = w->phys_cursor.vpos;
21501 int mouse_face_here_p = 0;
21502 struct glyph_matrix *active_glyphs = w->current_matrix;
21503 struct glyph_row *cursor_row;
21504 struct glyph *cursor_glyph;
21505 enum draw_glyphs_face hl;
21506
21507 /* No cursor displayed or row invalidated => nothing to do on the
21508 screen. */
21509 if (w->phys_cursor_type == NO_CURSOR)
21510 goto mark_cursor_off;
21511
21512 /* VPOS >= active_glyphs->nrows means that window has been resized.
21513 Don't bother to erase the cursor. */
21514 if (vpos >= active_glyphs->nrows)
21515 goto mark_cursor_off;
21516
21517 /* If row containing cursor is marked invalid, there is nothing we
21518 can do. */
21519 cursor_row = MATRIX_ROW (active_glyphs, vpos);
21520 if (!cursor_row->enabled_p)
21521 goto mark_cursor_off;
21522
21523 /* If line spacing is > 0, old cursor may only be partially visible in
21524 window after split-window. So adjust visible height. */
21525 cursor_row->visible_height = min (cursor_row->visible_height,
21526 window_text_bottom_y (w) - cursor_row->y);
21527
21528 /* If row is completely invisible, don't attempt to delete a cursor which
21529 isn't there. This can happen if cursor is at top of a window, and
21530 we switch to a buffer with a header line in that window. */
21531 if (cursor_row->visible_height <= 0)
21532 goto mark_cursor_off;
21533
21534 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
21535 if (cursor_row->cursor_in_fringe_p)
21536 {
21537 cursor_row->cursor_in_fringe_p = 0;
21538 draw_fringe_bitmap (w, cursor_row, 0);
21539 goto mark_cursor_off;
21540 }
21541
21542 /* This can happen when the new row is shorter than the old one.
21543 In this case, either draw_glyphs or clear_end_of_line
21544 should have cleared the cursor. Note that we wouldn't be
21545 able to erase the cursor in this case because we don't have a
21546 cursor glyph at hand. */
21547 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
21548 goto mark_cursor_off;
21549
21550 /* If the cursor is in the mouse face area, redisplay that when
21551 we clear the cursor. */
21552 if (! NILP (dpyinfo->mouse_face_window)
21553 && w == XWINDOW (dpyinfo->mouse_face_window)
21554 && (vpos > dpyinfo->mouse_face_beg_row
21555 || (vpos == dpyinfo->mouse_face_beg_row
21556 && hpos >= dpyinfo->mouse_face_beg_col))
21557 && (vpos < dpyinfo->mouse_face_end_row
21558 || (vpos == dpyinfo->mouse_face_end_row
21559 && hpos < dpyinfo->mouse_face_end_col))
21560 /* Don't redraw the cursor's spot in mouse face if it is at the
21561 end of a line (on a newline). The cursor appears there, but
21562 mouse highlighting does not. */
21563 && cursor_row->used[TEXT_AREA] > hpos)
21564 mouse_face_here_p = 1;
21565
21566 /* Maybe clear the display under the cursor. */
21567 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
21568 {
21569 int x, y, left_x;
21570 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
21571 int width;
21572
21573 cursor_glyph = get_phys_cursor_glyph (w);
21574 if (cursor_glyph == NULL)
21575 goto mark_cursor_off;
21576
21577 width = cursor_glyph->pixel_width;
21578 left_x = window_box_left_offset (w, TEXT_AREA);
21579 x = w->phys_cursor.x;
21580 if (x < left_x)
21581 width -= left_x - x;
21582 width = min (width, window_box_width (w, TEXT_AREA) - x);
21583 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
21584 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
21585
21586 if (width > 0)
21587 rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
21588 }
21589
21590 /* Erase the cursor by redrawing the character underneath it. */
21591 if (mouse_face_here_p)
21592 hl = DRAW_MOUSE_FACE;
21593 else
21594 hl = DRAW_NORMAL_TEXT;
21595 draw_phys_cursor_glyph (w, cursor_row, hl);
21596
21597 mark_cursor_off:
21598 w->phys_cursor_on_p = 0;
21599 w->phys_cursor_type = NO_CURSOR;
21600 }
21601
21602
21603 /* EXPORT:
21604 Display or clear cursor of window W. If ON is zero, clear the
21605 cursor. If it is non-zero, display the cursor. If ON is nonzero,
21606 where to put the cursor is specified by HPOS, VPOS, X and Y. */
21607
21608 void
21609 display_and_set_cursor (w, on, hpos, vpos, x, y)
21610 struct window *w;
21611 int on, hpos, vpos, x, y;
21612 {
21613 struct frame *f = XFRAME (w->frame);
21614 int new_cursor_type;
21615 int new_cursor_width;
21616 int active_cursor;
21617 struct glyph_row *glyph_row;
21618 struct glyph *glyph;
21619
21620 /* This is pointless on invisible frames, and dangerous on garbaged
21621 windows and frames; in the latter case, the frame or window may
21622 be in the midst of changing its size, and x and y may be off the
21623 window. */
21624 if (! FRAME_VISIBLE_P (f)
21625 || FRAME_GARBAGED_P (f)
21626 || vpos >= w->current_matrix->nrows
21627 || hpos >= w->current_matrix->matrix_w)
21628 return;
21629
21630 /* If cursor is off and we want it off, return quickly. */
21631 if (!on && !w->phys_cursor_on_p)
21632 return;
21633
21634 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
21635 /* If cursor row is not enabled, we don't really know where to
21636 display the cursor. */
21637 if (!glyph_row->enabled_p)
21638 {
21639 w->phys_cursor_on_p = 0;
21640 return;
21641 }
21642
21643 glyph = NULL;
21644 if (!glyph_row->exact_window_width_line_p
21645 || hpos < glyph_row->used[TEXT_AREA])
21646 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
21647
21648 xassert (interrupt_input_blocked);
21649
21650 /* Set new_cursor_type to the cursor we want to be displayed. */
21651 new_cursor_type = get_window_cursor_type (w, glyph,
21652 &new_cursor_width, &active_cursor);
21653
21654 /* If cursor is currently being shown and we don't want it to be or
21655 it is in the wrong place, or the cursor type is not what we want,
21656 erase it. */
21657 if (w->phys_cursor_on_p
21658 && (!on
21659 || w->phys_cursor.x != x
21660 || w->phys_cursor.y != y
21661 || new_cursor_type != w->phys_cursor_type
21662 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
21663 && new_cursor_width != w->phys_cursor_width)))
21664 erase_phys_cursor (w);
21665
21666 /* Don't check phys_cursor_on_p here because that flag is only set
21667 to zero in some cases where we know that the cursor has been
21668 completely erased, to avoid the extra work of erasing the cursor
21669 twice. In other words, phys_cursor_on_p can be 1 and the cursor
21670 still not be visible, or it has only been partly erased. */
21671 if (on)
21672 {
21673 w->phys_cursor_ascent = glyph_row->ascent;
21674 w->phys_cursor_height = glyph_row->height;
21675
21676 /* Set phys_cursor_.* before x_draw_.* is called because some
21677 of them may need the information. */
21678 w->phys_cursor.x = x;
21679 w->phys_cursor.y = glyph_row->y;
21680 w->phys_cursor.hpos = hpos;
21681 w->phys_cursor.vpos = vpos;
21682 }
21683
21684 rif->draw_window_cursor (w, glyph_row, x, y,
21685 new_cursor_type, new_cursor_width,
21686 on, active_cursor);
21687 }
21688
21689
21690 /* Switch the display of W's cursor on or off, according to the value
21691 of ON. */
21692
21693 static void
21694 update_window_cursor (w, on)
21695 struct window *w;
21696 int on;
21697 {
21698 /* Don't update cursor in windows whose frame is in the process
21699 of being deleted. */
21700 if (w->current_matrix)
21701 {
21702 BLOCK_INPUT;
21703 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
21704 w->phys_cursor.x, w->phys_cursor.y);
21705 UNBLOCK_INPUT;
21706 }
21707 }
21708
21709
21710 /* Call update_window_cursor with parameter ON_P on all leaf windows
21711 in the window tree rooted at W. */
21712
21713 static void
21714 update_cursor_in_window_tree (w, on_p)
21715 struct window *w;
21716 int on_p;
21717 {
21718 while (w)
21719 {
21720 if (!NILP (w->hchild))
21721 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
21722 else if (!NILP (w->vchild))
21723 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
21724 else
21725 update_window_cursor (w, on_p);
21726
21727 w = NILP (w->next) ? 0 : XWINDOW (w->next);
21728 }
21729 }
21730
21731
21732 /* EXPORT:
21733 Display the cursor on window W, or clear it, according to ON_P.
21734 Don't change the cursor's position. */
21735
21736 void
21737 x_update_cursor (f, on_p)
21738 struct frame *f;
21739 int on_p;
21740 {
21741 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
21742 }
21743
21744
21745 /* EXPORT:
21746 Clear the cursor of window W to background color, and mark the
21747 cursor as not shown. This is used when the text where the cursor
21748 is is about to be rewritten. */
21749
21750 void
21751 x_clear_cursor (w)
21752 struct window *w;
21753 {
21754 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
21755 update_window_cursor (w, 0);
21756 }
21757
21758
21759 /* EXPORT:
21760 Display the active region described by mouse_face_* according to DRAW. */
21761
21762 void
21763 show_mouse_face (dpyinfo, draw)
21764 Display_Info *dpyinfo;
21765 enum draw_glyphs_face draw;
21766 {
21767 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
21768 struct frame *f = XFRAME (WINDOW_FRAME (w));
21769
21770 if (/* If window is in the process of being destroyed, don't bother
21771 to do anything. */
21772 w->current_matrix != NULL
21773 /* Don't update mouse highlight if hidden */
21774 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
21775 /* Recognize when we are called to operate on rows that don't exist
21776 anymore. This can happen when a window is split. */
21777 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
21778 {
21779 int phys_cursor_on_p = w->phys_cursor_on_p;
21780 struct glyph_row *row, *first, *last;
21781
21782 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
21783 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
21784
21785 for (row = first; row <= last && row->enabled_p; ++row)
21786 {
21787 int start_hpos, end_hpos, start_x;
21788
21789 /* For all but the first row, the highlight starts at column 0. */
21790 if (row == first)
21791 {
21792 start_hpos = dpyinfo->mouse_face_beg_col;
21793 start_x = dpyinfo->mouse_face_beg_x;
21794 }
21795 else
21796 {
21797 start_hpos = 0;
21798 start_x = 0;
21799 }
21800
21801 if (row == last)
21802 end_hpos = dpyinfo->mouse_face_end_col;
21803 else
21804 {
21805 end_hpos = row->used[TEXT_AREA];
21806 if (draw == DRAW_NORMAL_TEXT)
21807 row->fill_line_p = 1; /* Clear to end of line */
21808 }
21809
21810 if (end_hpos > start_hpos)
21811 {
21812 draw_glyphs (w, start_x, row, TEXT_AREA,
21813 start_hpos, end_hpos,
21814 draw, 0);
21815
21816 row->mouse_face_p
21817 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
21818 }
21819 }
21820
21821 /* When we've written over the cursor, arrange for it to
21822 be displayed again. */
21823 if (phys_cursor_on_p && !w->phys_cursor_on_p)
21824 {
21825 BLOCK_INPUT;
21826 display_and_set_cursor (w, 1,
21827 w->phys_cursor.hpos, w->phys_cursor.vpos,
21828 w->phys_cursor.x, w->phys_cursor.y);
21829 UNBLOCK_INPUT;
21830 }
21831 }
21832
21833 /* Change the mouse cursor. */
21834 if (draw == DRAW_NORMAL_TEXT)
21835 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
21836 else if (draw == DRAW_MOUSE_FACE)
21837 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
21838 else
21839 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
21840 }
21841
21842 /* EXPORT:
21843 Clear out the mouse-highlighted active region.
21844 Redraw it un-highlighted first. Value is non-zero if mouse
21845 face was actually drawn unhighlighted. */
21846
21847 int
21848 clear_mouse_face (dpyinfo)
21849 Display_Info *dpyinfo;
21850 {
21851 int cleared = 0;
21852
21853 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
21854 {
21855 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
21856 cleared = 1;
21857 }
21858
21859 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21860 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21861 dpyinfo->mouse_face_window = Qnil;
21862 dpyinfo->mouse_face_overlay = Qnil;
21863 return cleared;
21864 }
21865
21866
21867 /* EXPORT:
21868 Non-zero if physical cursor of window W is within mouse face. */
21869
21870 int
21871 cursor_in_mouse_face_p (w)
21872 struct window *w;
21873 {
21874 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21875 int in_mouse_face = 0;
21876
21877 if (WINDOWP (dpyinfo->mouse_face_window)
21878 && XWINDOW (dpyinfo->mouse_face_window) == w)
21879 {
21880 int hpos = w->phys_cursor.hpos;
21881 int vpos = w->phys_cursor.vpos;
21882
21883 if (vpos >= dpyinfo->mouse_face_beg_row
21884 && vpos <= dpyinfo->mouse_face_end_row
21885 && (vpos > dpyinfo->mouse_face_beg_row
21886 || hpos >= dpyinfo->mouse_face_beg_col)
21887 && (vpos < dpyinfo->mouse_face_end_row
21888 || hpos < dpyinfo->mouse_face_end_col
21889 || dpyinfo->mouse_face_past_end))
21890 in_mouse_face = 1;
21891 }
21892
21893 return in_mouse_face;
21894 }
21895
21896
21897
21898 \f
21899 /* Find the glyph matrix position of buffer position CHARPOS in window
21900 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
21901 current glyphs must be up to date. If CHARPOS is above window
21902 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
21903 of last line in W. In the row containing CHARPOS, stop before glyphs
21904 having STOP as object. */
21905
21906 #if 1 /* This is a version of fast_find_position that's more correct
21907 in the presence of hscrolling, for example. I didn't install
21908 it right away because the problem fixed is minor, it failed
21909 in 20.x as well, and I think it's too risky to install
21910 so near the release of 21.1. 2001-09-25 gerd. */
21911
21912 static int
21913 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
21914 struct window *w;
21915 int charpos;
21916 int *hpos, *vpos, *x, *y;
21917 Lisp_Object stop;
21918 {
21919 struct glyph_row *row, *first;
21920 struct glyph *glyph, *end;
21921 int past_end = 0;
21922
21923 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
21924 if (charpos < MATRIX_ROW_START_CHARPOS (first))
21925 {
21926 *x = first->x;
21927 *y = first->y;
21928 *hpos = 0;
21929 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
21930 return 1;
21931 }
21932
21933 row = row_containing_pos (w, charpos, first, NULL, 0);
21934 if (row == NULL)
21935 {
21936 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
21937 past_end = 1;
21938 }
21939
21940 /* If whole rows or last part of a row came from a display overlay,
21941 row_containing_pos will skip over such rows because their end pos
21942 equals the start pos of the overlay or interval.
21943
21944 Move back if we have a STOP object and previous row's
21945 end glyph came from STOP. */
21946 if (!NILP (stop))
21947 {
21948 struct glyph_row *prev;
21949 while ((prev = row - 1, prev >= first)
21950 && MATRIX_ROW_END_CHARPOS (prev) == charpos
21951 && prev->used[TEXT_AREA] > 0)
21952 {
21953 struct glyph *beg = prev->glyphs[TEXT_AREA];
21954 glyph = beg + prev->used[TEXT_AREA];
21955 while (--glyph >= beg
21956 && INTEGERP (glyph->object));
21957 if (glyph < beg
21958 || !EQ (stop, glyph->object))
21959 break;
21960 row = prev;
21961 }
21962 }
21963
21964 *x = row->x;
21965 *y = row->y;
21966 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
21967
21968 glyph = row->glyphs[TEXT_AREA];
21969 end = glyph + row->used[TEXT_AREA];
21970
21971 /* Skip over glyphs not having an object at the start of the row.
21972 These are special glyphs like truncation marks on terminal
21973 frames. */
21974 if (row->displays_text_p)
21975 while (glyph < end
21976 && INTEGERP (glyph->object)
21977 && !EQ (stop, glyph->object)
21978 && glyph->charpos < 0)
21979 {
21980 *x += glyph->pixel_width;
21981 ++glyph;
21982 }
21983
21984 while (glyph < end
21985 && !INTEGERP (glyph->object)
21986 && !EQ (stop, glyph->object)
21987 && (!BUFFERP (glyph->object)
21988 || glyph->charpos < charpos))
21989 {
21990 *x += glyph->pixel_width;
21991 ++glyph;
21992 }
21993
21994 *hpos = glyph - row->glyphs[TEXT_AREA];
21995 return !past_end;
21996 }
21997
21998 #else /* not 1 */
21999
22000 static int
22001 fast_find_position (w, pos, hpos, vpos, x, y, stop)
22002 struct window *w;
22003 int pos;
22004 int *hpos, *vpos, *x, *y;
22005 Lisp_Object stop;
22006 {
22007 int i;
22008 int lastcol;
22009 int maybe_next_line_p = 0;
22010 int line_start_position;
22011 int yb = window_text_bottom_y (w);
22012 struct glyph_row *row, *best_row;
22013 int row_vpos, best_row_vpos;
22014 int current_x;
22015
22016 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22017 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22018
22019 while (row->y < yb)
22020 {
22021 if (row->used[TEXT_AREA])
22022 line_start_position = row->glyphs[TEXT_AREA]->charpos;
22023 else
22024 line_start_position = 0;
22025
22026 if (line_start_position > pos)
22027 break;
22028 /* If the position sought is the end of the buffer,
22029 don't include the blank lines at the bottom of the window. */
22030 else if (line_start_position == pos
22031 && pos == BUF_ZV (XBUFFER (w->buffer)))
22032 {
22033 maybe_next_line_p = 1;
22034 break;
22035 }
22036 else if (line_start_position > 0)
22037 {
22038 best_row = row;
22039 best_row_vpos = row_vpos;
22040 }
22041
22042 if (row->y + row->height >= yb)
22043 break;
22044
22045 ++row;
22046 ++row_vpos;
22047 }
22048
22049 /* Find the right column within BEST_ROW. */
22050 lastcol = 0;
22051 current_x = best_row->x;
22052 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
22053 {
22054 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
22055 int charpos = glyph->charpos;
22056
22057 if (BUFFERP (glyph->object))
22058 {
22059 if (charpos == pos)
22060 {
22061 *hpos = i;
22062 *vpos = best_row_vpos;
22063 *x = current_x;
22064 *y = best_row->y;
22065 return 1;
22066 }
22067 else if (charpos > pos)
22068 break;
22069 }
22070 else if (EQ (glyph->object, stop))
22071 break;
22072
22073 if (charpos > 0)
22074 lastcol = i;
22075 current_x += glyph->pixel_width;
22076 }
22077
22078 /* If we're looking for the end of the buffer,
22079 and we didn't find it in the line we scanned,
22080 use the start of the following line. */
22081 if (maybe_next_line_p)
22082 {
22083 ++best_row;
22084 ++best_row_vpos;
22085 lastcol = 0;
22086 current_x = best_row->x;
22087 }
22088
22089 *vpos = best_row_vpos;
22090 *hpos = lastcol + 1;
22091 *x = current_x;
22092 *y = best_row->y;
22093 return 0;
22094 }
22095
22096 #endif /* not 1 */
22097
22098
22099 /* Find the position of the glyph for position POS in OBJECT in
22100 window W's current matrix, and return in *X, *Y the pixel
22101 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
22102
22103 RIGHT_P non-zero means return the position of the right edge of the
22104 glyph, RIGHT_P zero means return the left edge position.
22105
22106 If no glyph for POS exists in the matrix, return the position of
22107 the glyph with the next smaller position that is in the matrix, if
22108 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
22109 exists in the matrix, return the position of the glyph with the
22110 next larger position in OBJECT.
22111
22112 Value is non-zero if a glyph was found. */
22113
22114 static int
22115 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
22116 struct window *w;
22117 int pos;
22118 Lisp_Object object;
22119 int *hpos, *vpos, *x, *y;
22120 int right_p;
22121 {
22122 int yb = window_text_bottom_y (w);
22123 struct glyph_row *r;
22124 struct glyph *best_glyph = NULL;
22125 struct glyph_row *best_row = NULL;
22126 int best_x = 0;
22127
22128 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22129 r->enabled_p && r->y < yb;
22130 ++r)
22131 {
22132 struct glyph *g = r->glyphs[TEXT_AREA];
22133 struct glyph *e = g + r->used[TEXT_AREA];
22134 int gx;
22135
22136 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
22137 if (EQ (g->object, object))
22138 {
22139 if (g->charpos == pos)
22140 {
22141 best_glyph = g;
22142 best_x = gx;
22143 best_row = r;
22144 goto found;
22145 }
22146 else if (best_glyph == NULL
22147 || ((abs (g->charpos - pos)
22148 < abs (best_glyph->charpos - pos))
22149 && (right_p
22150 ? g->charpos < pos
22151 : g->charpos > pos)))
22152 {
22153 best_glyph = g;
22154 best_x = gx;
22155 best_row = r;
22156 }
22157 }
22158 }
22159
22160 found:
22161
22162 if (best_glyph)
22163 {
22164 *x = best_x;
22165 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
22166
22167 if (right_p)
22168 {
22169 *x += best_glyph->pixel_width;
22170 ++*hpos;
22171 }
22172
22173 *y = best_row->y;
22174 *vpos = best_row - w->current_matrix->rows;
22175 }
22176
22177 return best_glyph != NULL;
22178 }
22179
22180
22181 /* See if position X, Y is within a hot-spot of an image. */
22182
22183 static int
22184 on_hot_spot_p (hot_spot, x, y)
22185 Lisp_Object hot_spot;
22186 int x, y;
22187 {
22188 if (!CONSP (hot_spot))
22189 return 0;
22190
22191 if (EQ (XCAR (hot_spot), Qrect))
22192 {
22193 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
22194 Lisp_Object rect = XCDR (hot_spot);
22195 Lisp_Object tem;
22196 if (!CONSP (rect))
22197 return 0;
22198 if (!CONSP (XCAR (rect)))
22199 return 0;
22200 if (!CONSP (XCDR (rect)))
22201 return 0;
22202 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
22203 return 0;
22204 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
22205 return 0;
22206 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
22207 return 0;
22208 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
22209 return 0;
22210 return 1;
22211 }
22212 else if (EQ (XCAR (hot_spot), Qcircle))
22213 {
22214 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
22215 Lisp_Object circ = XCDR (hot_spot);
22216 Lisp_Object lr, lx0, ly0;
22217 if (CONSP (circ)
22218 && CONSP (XCAR (circ))
22219 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
22220 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
22221 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
22222 {
22223 double r = XFLOATINT (lr);
22224 double dx = XINT (lx0) - x;
22225 double dy = XINT (ly0) - y;
22226 return (dx * dx + dy * dy <= r * r);
22227 }
22228 }
22229 else if (EQ (XCAR (hot_spot), Qpoly))
22230 {
22231 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
22232 if (VECTORP (XCDR (hot_spot)))
22233 {
22234 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
22235 Lisp_Object *poly = v->contents;
22236 int n = v->size;
22237 int i;
22238 int inside = 0;
22239 Lisp_Object lx, ly;
22240 int x0, y0;
22241
22242 /* Need an even number of coordinates, and at least 3 edges. */
22243 if (n < 6 || n & 1)
22244 return 0;
22245
22246 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
22247 If count is odd, we are inside polygon. Pixels on edges
22248 may or may not be included depending on actual geometry of the
22249 polygon. */
22250 if ((lx = poly[n-2], !INTEGERP (lx))
22251 || (ly = poly[n-1], !INTEGERP (lx)))
22252 return 0;
22253 x0 = XINT (lx), y0 = XINT (ly);
22254 for (i = 0; i < n; i += 2)
22255 {
22256 int x1 = x0, y1 = y0;
22257 if ((lx = poly[i], !INTEGERP (lx))
22258 || (ly = poly[i+1], !INTEGERP (ly)))
22259 return 0;
22260 x0 = XINT (lx), y0 = XINT (ly);
22261
22262 /* Does this segment cross the X line? */
22263 if (x0 >= x)
22264 {
22265 if (x1 >= x)
22266 continue;
22267 }
22268 else if (x1 < x)
22269 continue;
22270 if (y > y0 && y > y1)
22271 continue;
22272 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
22273 inside = !inside;
22274 }
22275 return inside;
22276 }
22277 }
22278 /* If we don't understand the format, pretend we're not in the hot-spot. */
22279 return 0;
22280 }
22281
22282 Lisp_Object
22283 find_hot_spot (map, x, y)
22284 Lisp_Object map;
22285 int x, y;
22286 {
22287 while (CONSP (map))
22288 {
22289 if (CONSP (XCAR (map))
22290 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
22291 return XCAR (map);
22292 map = XCDR (map);
22293 }
22294
22295 return Qnil;
22296 }
22297
22298 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
22299 3, 3, 0,
22300 doc: /* Lookup in image map MAP coordinates X and Y.
22301 An image map is an alist where each element has the format (AREA ID PLIST).
22302 An AREA is specified as either a rectangle, a circle, or a polygon:
22303 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
22304 pixel coordinates of the upper left and bottom right corners.
22305 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
22306 and the radius of the circle; r may be a float or integer.
22307 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
22308 vector describes one corner in the polygon.
22309 Returns the alist element for the first matching AREA in MAP. */)
22310 (map, x, y)
22311 Lisp_Object map;
22312 Lisp_Object x, y;
22313 {
22314 if (NILP (map))
22315 return Qnil;
22316
22317 CHECK_NUMBER (x);
22318 CHECK_NUMBER (y);
22319
22320 return find_hot_spot (map, XINT (x), XINT (y));
22321 }
22322
22323
22324 /* Display frame CURSOR, optionally using shape defined by POINTER. */
22325 static void
22326 define_frame_cursor1 (f, cursor, pointer)
22327 struct frame *f;
22328 Cursor cursor;
22329 Lisp_Object pointer;
22330 {
22331 /* Do not change cursor shape while dragging mouse. */
22332 if (!NILP (do_mouse_tracking))
22333 return;
22334
22335 if (!NILP (pointer))
22336 {
22337 if (EQ (pointer, Qarrow))
22338 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22339 else if (EQ (pointer, Qhand))
22340 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
22341 else if (EQ (pointer, Qtext))
22342 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22343 else if (EQ (pointer, intern ("hdrag")))
22344 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22345 #ifdef HAVE_X_WINDOWS
22346 else if (EQ (pointer, intern ("vdrag")))
22347 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
22348 #endif
22349 else if (EQ (pointer, intern ("hourglass")))
22350 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
22351 else if (EQ (pointer, Qmodeline))
22352 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
22353 else
22354 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22355 }
22356
22357 if (cursor != No_Cursor)
22358 rif->define_frame_cursor (f, cursor);
22359 }
22360
22361 /* Take proper action when mouse has moved to the mode or header line
22362 or marginal area AREA of window W, x-position X and y-position Y.
22363 X is relative to the start of the text display area of W, so the
22364 width of bitmap areas and scroll bars must be subtracted to get a
22365 position relative to the start of the mode line. */
22366
22367 static void
22368 note_mode_line_or_margin_highlight (window, x, y, area)
22369 Lisp_Object window;
22370 int x, y;
22371 enum window_part area;
22372 {
22373 struct window *w = XWINDOW (window);
22374 struct frame *f = XFRAME (w->frame);
22375 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22376 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22377 Lisp_Object pointer = Qnil;
22378 int charpos, dx, dy, width, height;
22379 Lisp_Object string, object = Qnil;
22380 Lisp_Object pos, help;
22381
22382 Lisp_Object mouse_face;
22383 int original_x_pixel = x;
22384 struct glyph * glyph = NULL;
22385 struct glyph_row *row;
22386
22387 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
22388 {
22389 int x0;
22390 struct glyph *end;
22391
22392 string = mode_line_string (w, area, &x, &y, &charpos,
22393 &object, &dx, &dy, &width, &height);
22394
22395 row = (area == ON_MODE_LINE
22396 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
22397 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
22398
22399 /* Find glyph */
22400 if (row->mode_line_p && row->enabled_p)
22401 {
22402 glyph = row->glyphs[TEXT_AREA];
22403 end = glyph + row->used[TEXT_AREA];
22404
22405 for (x0 = original_x_pixel;
22406 glyph < end && x0 >= glyph->pixel_width;
22407 ++glyph)
22408 x0 -= glyph->pixel_width;
22409
22410 if (glyph >= end)
22411 glyph = NULL;
22412 }
22413 }
22414 else
22415 {
22416 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
22417 string = marginal_area_string (w, area, &x, &y, &charpos,
22418 &object, &dx, &dy, &width, &height);
22419 }
22420
22421 help = Qnil;
22422
22423 if (IMAGEP (object))
22424 {
22425 Lisp_Object image_map, hotspot;
22426 if ((image_map = Fplist_get (XCDR (object), QCmap),
22427 !NILP (image_map))
22428 && (hotspot = find_hot_spot (image_map, dx, dy),
22429 CONSP (hotspot))
22430 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22431 {
22432 Lisp_Object area_id, plist;
22433
22434 area_id = XCAR (hotspot);
22435 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22436 If so, we could look for mouse-enter, mouse-leave
22437 properties in PLIST (and do something...). */
22438 hotspot = XCDR (hotspot);
22439 if (CONSP (hotspot)
22440 && (plist = XCAR (hotspot), CONSP (plist)))
22441 {
22442 pointer = Fplist_get (plist, Qpointer);
22443 if (NILP (pointer))
22444 pointer = Qhand;
22445 help = Fplist_get (plist, Qhelp_echo);
22446 if (!NILP (help))
22447 {
22448 help_echo_string = help;
22449 /* Is this correct? ++kfs */
22450 XSETWINDOW (help_echo_window, w);
22451 help_echo_object = w->buffer;
22452 help_echo_pos = charpos;
22453 }
22454 }
22455 }
22456 if (NILP (pointer))
22457 pointer = Fplist_get (XCDR (object), QCpointer);
22458 }
22459
22460 if (STRINGP (string))
22461 {
22462 pos = make_number (charpos);
22463 /* If we're on a string with `help-echo' text property, arrange
22464 for the help to be displayed. This is done by setting the
22465 global variable help_echo_string to the help string. */
22466 if (NILP (help))
22467 {
22468 help = Fget_text_property (pos, Qhelp_echo, string);
22469 if (!NILP (help))
22470 {
22471 help_echo_string = help;
22472 XSETWINDOW (help_echo_window, w);
22473 help_echo_object = string;
22474 help_echo_pos = charpos;
22475 }
22476 }
22477
22478 if (NILP (pointer))
22479 pointer = Fget_text_property (pos, Qpointer, string);
22480
22481 /* Change the mouse pointer according to what is under X/Y. */
22482 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
22483 {
22484 Lisp_Object map;
22485 map = Fget_text_property (pos, Qlocal_map, string);
22486 if (!KEYMAPP (map))
22487 map = Fget_text_property (pos, Qkeymap, string);
22488 if (!KEYMAPP (map))
22489 cursor = dpyinfo->vertical_scroll_bar_cursor;
22490 }
22491
22492 /* Change the mouse face according to what is under X/Y. */
22493 mouse_face = Fget_text_property (pos, Qmouse_face, string);
22494 if (!NILP (mouse_face)
22495 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22496 && glyph)
22497 {
22498 Lisp_Object b, e;
22499
22500 struct glyph * tmp_glyph;
22501
22502 int gpos;
22503 int gseq_length;
22504 int total_pixel_width;
22505 int ignore;
22506
22507 int vpos, hpos;
22508
22509 b = Fprevious_single_property_change (make_number (charpos + 1),
22510 Qmouse_face, string, Qnil);
22511 if (NILP (b))
22512 b = make_number (0);
22513
22514 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
22515 if (NILP (e))
22516 e = make_number (SCHARS (string));
22517
22518 /* Calculate the position(glyph position: GPOS) of GLYPH in
22519 displayed string. GPOS is different from CHARPOS.
22520
22521 CHARPOS is the position of glyph in internal string
22522 object. A mode line string format has structures which
22523 is converted to a flatten by emacs lisp interpreter.
22524 The internal string is an element of the structures.
22525 The displayed string is the flatten string. */
22526 for (tmp_glyph = glyph - 1, gpos = 0;
22527 tmp_glyph->charpos >= XINT (b);
22528 tmp_glyph--, gpos++)
22529 {
22530 if (!EQ (tmp_glyph->object, glyph->object))
22531 break;
22532 }
22533
22534 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
22535 displayed string holding GLYPH.
22536
22537 GSEQ_LENGTH is different from SCHARS (STRING).
22538 SCHARS (STRING) returns the length of the internal string. */
22539 for (tmp_glyph = glyph, gseq_length = gpos;
22540 tmp_glyph->charpos < XINT (e);
22541 tmp_glyph++, gseq_length++)
22542 {
22543 if (!EQ (tmp_glyph->object, glyph->object))
22544 break;
22545 }
22546
22547 total_pixel_width = 0;
22548 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
22549 total_pixel_width += tmp_glyph->pixel_width;
22550
22551 /* Pre calculation of re-rendering position */
22552 vpos = (x - gpos);
22553 hpos = (area == ON_MODE_LINE
22554 ? (w->current_matrix)->nrows - 1
22555 : 0);
22556
22557 /* If the re-rendering position is included in the last
22558 re-rendering area, we should do nothing. */
22559 if ( EQ (window, dpyinfo->mouse_face_window)
22560 && dpyinfo->mouse_face_beg_col <= vpos
22561 && vpos < dpyinfo->mouse_face_end_col
22562 && dpyinfo->mouse_face_beg_row == hpos )
22563 return;
22564
22565 if (clear_mouse_face (dpyinfo))
22566 cursor = No_Cursor;
22567
22568 dpyinfo->mouse_face_beg_col = vpos;
22569 dpyinfo->mouse_face_beg_row = hpos;
22570
22571 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
22572 dpyinfo->mouse_face_beg_y = 0;
22573
22574 dpyinfo->mouse_face_end_col = vpos + gseq_length;
22575 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
22576
22577 dpyinfo->mouse_face_end_x = 0;
22578 dpyinfo->mouse_face_end_y = 0;
22579
22580 dpyinfo->mouse_face_past_end = 0;
22581 dpyinfo->mouse_face_window = window;
22582
22583 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
22584 charpos,
22585 0, 0, 0, &ignore,
22586 glyph->face_id, 1);
22587 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22588
22589 if (NILP (pointer))
22590 pointer = Qhand;
22591 }
22592 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22593 clear_mouse_face (dpyinfo);
22594 }
22595 define_frame_cursor1 (f, cursor, pointer);
22596 }
22597
22598
22599 /* EXPORT:
22600 Take proper action when the mouse has moved to position X, Y on
22601 frame F as regards highlighting characters that have mouse-face
22602 properties. Also de-highlighting chars where the mouse was before.
22603 X and Y can be negative or out of range. */
22604
22605 void
22606 note_mouse_highlight (f, x, y)
22607 struct frame *f;
22608 int x, y;
22609 {
22610 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22611 enum window_part part;
22612 Lisp_Object window;
22613 struct window *w;
22614 Cursor cursor = No_Cursor;
22615 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
22616 struct buffer *b;
22617
22618 /* When a menu is active, don't highlight because this looks odd. */
22619 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
22620 if (popup_activated ())
22621 return;
22622 #endif
22623
22624 if (NILP (Vmouse_highlight)
22625 || !f->glyphs_initialized_p)
22626 return;
22627
22628 dpyinfo->mouse_face_mouse_x = x;
22629 dpyinfo->mouse_face_mouse_y = y;
22630 dpyinfo->mouse_face_mouse_frame = f;
22631
22632 if (dpyinfo->mouse_face_defer)
22633 return;
22634
22635 if (gc_in_progress)
22636 {
22637 dpyinfo->mouse_face_deferred_gc = 1;
22638 return;
22639 }
22640
22641 /* Which window is that in? */
22642 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
22643
22644 /* If we were displaying active text in another window, clear that.
22645 Also clear if we move out of text area in same window. */
22646 if (! EQ (window, dpyinfo->mouse_face_window)
22647 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
22648 && !NILP (dpyinfo->mouse_face_window)))
22649 clear_mouse_face (dpyinfo);
22650
22651 /* Not on a window -> return. */
22652 if (!WINDOWP (window))
22653 return;
22654
22655 /* Reset help_echo_string. It will get recomputed below. */
22656 help_echo_string = Qnil;
22657
22658 /* Convert to window-relative pixel coordinates. */
22659 w = XWINDOW (window);
22660 frame_to_window_pixel_xy (w, &x, &y);
22661
22662 /* Handle tool-bar window differently since it doesn't display a
22663 buffer. */
22664 if (EQ (window, f->tool_bar_window))
22665 {
22666 note_tool_bar_highlight (f, x, y);
22667 return;
22668 }
22669
22670 /* Mouse is on the mode, header line or margin? */
22671 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
22672 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
22673 {
22674 note_mode_line_or_margin_highlight (window, x, y, part);
22675 return;
22676 }
22677
22678 if (part == ON_VERTICAL_BORDER)
22679 {
22680 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22681 help_echo_string = build_string ("drag-mouse-1: resize");
22682 }
22683 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
22684 || part == ON_SCROLL_BAR)
22685 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22686 else
22687 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22688
22689 /* Are we in a window whose display is up to date?
22690 And verify the buffer's text has not changed. */
22691 b = XBUFFER (w->buffer);
22692 if (part == ON_TEXT
22693 && EQ (w->window_end_valid, w->buffer)
22694 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
22695 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
22696 {
22697 int hpos, vpos, pos, i, dx, dy, area;
22698 struct glyph *glyph;
22699 Lisp_Object object;
22700 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
22701 Lisp_Object *overlay_vec = NULL;
22702 int noverlays;
22703 struct buffer *obuf;
22704 int obegv, ozv, same_region;
22705
22706 /* Find the glyph under X/Y. */
22707 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
22708
22709 /* Look for :pointer property on image. */
22710 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
22711 {
22712 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
22713 if (img != NULL && IMAGEP (img->spec))
22714 {
22715 Lisp_Object image_map, hotspot;
22716 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
22717 !NILP (image_map))
22718 && (hotspot = find_hot_spot (image_map,
22719 glyph->slice.x + dx,
22720 glyph->slice.y + dy),
22721 CONSP (hotspot))
22722 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22723 {
22724 Lisp_Object area_id, plist;
22725
22726 area_id = XCAR (hotspot);
22727 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22728 If so, we could look for mouse-enter, mouse-leave
22729 properties in PLIST (and do something...). */
22730 hotspot = XCDR (hotspot);
22731 if (CONSP (hotspot)
22732 && (plist = XCAR (hotspot), CONSP (plist)))
22733 {
22734 pointer = Fplist_get (plist, Qpointer);
22735 if (NILP (pointer))
22736 pointer = Qhand;
22737 help_echo_string = Fplist_get (plist, Qhelp_echo);
22738 if (!NILP (help_echo_string))
22739 {
22740 help_echo_window = window;
22741 help_echo_object = glyph->object;
22742 help_echo_pos = glyph->charpos;
22743 }
22744 }
22745 }
22746 if (NILP (pointer))
22747 pointer = Fplist_get (XCDR (img->spec), QCpointer);
22748 }
22749 }
22750
22751 /* Clear mouse face if X/Y not over text. */
22752 if (glyph == NULL
22753 || area != TEXT_AREA
22754 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
22755 {
22756 if (clear_mouse_face (dpyinfo))
22757 cursor = No_Cursor;
22758 if (NILP (pointer))
22759 {
22760 if (area != TEXT_AREA)
22761 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22762 else
22763 pointer = Vvoid_text_area_pointer;
22764 }
22765 goto set_cursor;
22766 }
22767
22768 pos = glyph->charpos;
22769 object = glyph->object;
22770 if (!STRINGP (object) && !BUFFERP (object))
22771 goto set_cursor;
22772
22773 /* If we get an out-of-range value, return now; avoid an error. */
22774 if (BUFFERP (object) && pos > BUF_Z (b))
22775 goto set_cursor;
22776
22777 /* Make the window's buffer temporarily current for
22778 overlays_at and compute_char_face. */
22779 obuf = current_buffer;
22780 current_buffer = b;
22781 obegv = BEGV;
22782 ozv = ZV;
22783 BEGV = BEG;
22784 ZV = Z;
22785
22786 /* Is this char mouse-active or does it have help-echo? */
22787 position = make_number (pos);
22788
22789 if (BUFFERP (object))
22790 {
22791 /* Put all the overlays we want in a vector in overlay_vec. */
22792 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
22793 /* Sort overlays into increasing priority order. */
22794 noverlays = sort_overlays (overlay_vec, noverlays, w);
22795 }
22796 else
22797 noverlays = 0;
22798
22799 same_region = (EQ (window, dpyinfo->mouse_face_window)
22800 && vpos >= dpyinfo->mouse_face_beg_row
22801 && vpos <= dpyinfo->mouse_face_end_row
22802 && (vpos > dpyinfo->mouse_face_beg_row
22803 || hpos >= dpyinfo->mouse_face_beg_col)
22804 && (vpos < dpyinfo->mouse_face_end_row
22805 || hpos < dpyinfo->mouse_face_end_col
22806 || dpyinfo->mouse_face_past_end));
22807
22808 if (same_region)
22809 cursor = No_Cursor;
22810
22811 /* Check mouse-face highlighting. */
22812 if (! same_region
22813 /* If there exists an overlay with mouse-face overlapping
22814 the one we are currently highlighting, we have to
22815 check if we enter the overlapping overlay, and then
22816 highlight only that. */
22817 || (OVERLAYP (dpyinfo->mouse_face_overlay)
22818 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
22819 {
22820 /* Find the highest priority overlay that has a mouse-face
22821 property. */
22822 overlay = Qnil;
22823 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
22824 {
22825 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
22826 if (!NILP (mouse_face))
22827 overlay = overlay_vec[i];
22828 }
22829
22830 /* If we're actually highlighting the same overlay as
22831 before, there's no need to do that again. */
22832 if (!NILP (overlay)
22833 && EQ (overlay, dpyinfo->mouse_face_overlay))
22834 goto check_help_echo;
22835
22836 dpyinfo->mouse_face_overlay = overlay;
22837
22838 /* Clear the display of the old active region, if any. */
22839 if (clear_mouse_face (dpyinfo))
22840 cursor = No_Cursor;
22841
22842 /* If no overlay applies, get a text property. */
22843 if (NILP (overlay))
22844 mouse_face = Fget_text_property (position, Qmouse_face, object);
22845
22846 /* Handle the overlay case. */
22847 if (!NILP (overlay))
22848 {
22849 /* Find the range of text around this char that
22850 should be active. */
22851 Lisp_Object before, after;
22852 int ignore;
22853
22854 before = Foverlay_start (overlay);
22855 after = Foverlay_end (overlay);
22856 /* Record this as the current active region. */
22857 fast_find_position (w, XFASTINT (before),
22858 &dpyinfo->mouse_face_beg_col,
22859 &dpyinfo->mouse_face_beg_row,
22860 &dpyinfo->mouse_face_beg_x,
22861 &dpyinfo->mouse_face_beg_y, Qnil);
22862
22863 dpyinfo->mouse_face_past_end
22864 = !fast_find_position (w, XFASTINT (after),
22865 &dpyinfo->mouse_face_end_col,
22866 &dpyinfo->mouse_face_end_row,
22867 &dpyinfo->mouse_face_end_x,
22868 &dpyinfo->mouse_face_end_y, Qnil);
22869 dpyinfo->mouse_face_window = window;
22870
22871 dpyinfo->mouse_face_face_id
22872 = face_at_buffer_position (w, pos, 0, 0,
22873 &ignore, pos + 1,
22874 !dpyinfo->mouse_face_hidden);
22875
22876 /* Display it as active. */
22877 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22878 cursor = No_Cursor;
22879 }
22880 /* Handle the text property case. */
22881 else if (!NILP (mouse_face) && BUFFERP (object))
22882 {
22883 /* Find the range of text around this char that
22884 should be active. */
22885 Lisp_Object before, after, beginning, end;
22886 int ignore;
22887
22888 beginning = Fmarker_position (w->start);
22889 end = make_number (BUF_Z (XBUFFER (object))
22890 - XFASTINT (w->window_end_pos));
22891 before
22892 = Fprevious_single_property_change (make_number (pos + 1),
22893 Qmouse_face,
22894 object, beginning);
22895 after
22896 = Fnext_single_property_change (position, Qmouse_face,
22897 object, end);
22898
22899 /* Record this as the current active region. */
22900 fast_find_position (w, XFASTINT (before),
22901 &dpyinfo->mouse_face_beg_col,
22902 &dpyinfo->mouse_face_beg_row,
22903 &dpyinfo->mouse_face_beg_x,
22904 &dpyinfo->mouse_face_beg_y, Qnil);
22905 dpyinfo->mouse_face_past_end
22906 = !fast_find_position (w, XFASTINT (after),
22907 &dpyinfo->mouse_face_end_col,
22908 &dpyinfo->mouse_face_end_row,
22909 &dpyinfo->mouse_face_end_x,
22910 &dpyinfo->mouse_face_end_y, Qnil);
22911 dpyinfo->mouse_face_window = window;
22912
22913 if (BUFFERP (object))
22914 dpyinfo->mouse_face_face_id
22915 = face_at_buffer_position (w, pos, 0, 0,
22916 &ignore, pos + 1,
22917 !dpyinfo->mouse_face_hidden);
22918
22919 /* Display it as active. */
22920 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22921 cursor = No_Cursor;
22922 }
22923 else if (!NILP (mouse_face) && STRINGP (object))
22924 {
22925 Lisp_Object b, e;
22926 int ignore;
22927
22928 b = Fprevious_single_property_change (make_number (pos + 1),
22929 Qmouse_face,
22930 object, Qnil);
22931 e = Fnext_single_property_change (position, Qmouse_face,
22932 object, Qnil);
22933 if (NILP (b))
22934 b = make_number (0);
22935 if (NILP (e))
22936 e = make_number (SCHARS (object) - 1);
22937
22938 fast_find_string_pos (w, XINT (b), object,
22939 &dpyinfo->mouse_face_beg_col,
22940 &dpyinfo->mouse_face_beg_row,
22941 &dpyinfo->mouse_face_beg_x,
22942 &dpyinfo->mouse_face_beg_y, 0);
22943 fast_find_string_pos (w, XINT (e), object,
22944 &dpyinfo->mouse_face_end_col,
22945 &dpyinfo->mouse_face_end_row,
22946 &dpyinfo->mouse_face_end_x,
22947 &dpyinfo->mouse_face_end_y, 1);
22948 dpyinfo->mouse_face_past_end = 0;
22949 dpyinfo->mouse_face_window = window;
22950 dpyinfo->mouse_face_face_id
22951 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
22952 glyph->face_id, 1);
22953 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22954 cursor = No_Cursor;
22955 }
22956 else if (STRINGP (object) && NILP (mouse_face))
22957 {
22958 /* A string which doesn't have mouse-face, but
22959 the text ``under'' it might have. */
22960 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
22961 int start = MATRIX_ROW_START_CHARPOS (r);
22962
22963 pos = string_buffer_position (w, object, start);
22964 if (pos > 0)
22965 mouse_face = get_char_property_and_overlay (make_number (pos),
22966 Qmouse_face,
22967 w->buffer,
22968 &overlay);
22969 if (!NILP (mouse_face) && !NILP (overlay))
22970 {
22971 Lisp_Object before = Foverlay_start (overlay);
22972 Lisp_Object after = Foverlay_end (overlay);
22973 int ignore;
22974
22975 /* Note that we might not be able to find position
22976 BEFORE in the glyph matrix if the overlay is
22977 entirely covered by a `display' property. In
22978 this case, we overshoot. So let's stop in
22979 the glyph matrix before glyphs for OBJECT. */
22980 fast_find_position (w, XFASTINT (before),
22981 &dpyinfo->mouse_face_beg_col,
22982 &dpyinfo->mouse_face_beg_row,
22983 &dpyinfo->mouse_face_beg_x,
22984 &dpyinfo->mouse_face_beg_y,
22985 object);
22986
22987 dpyinfo->mouse_face_past_end
22988 = !fast_find_position (w, XFASTINT (after),
22989 &dpyinfo->mouse_face_end_col,
22990 &dpyinfo->mouse_face_end_row,
22991 &dpyinfo->mouse_face_end_x,
22992 &dpyinfo->mouse_face_end_y,
22993 Qnil);
22994 dpyinfo->mouse_face_window = window;
22995 dpyinfo->mouse_face_face_id
22996 = face_at_buffer_position (w, pos, 0, 0,
22997 &ignore, pos + 1,
22998 !dpyinfo->mouse_face_hidden);
22999
23000 /* Display it as active. */
23001 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23002 cursor = No_Cursor;
23003 }
23004 }
23005 }
23006
23007 check_help_echo:
23008
23009 /* Look for a `help-echo' property. */
23010 if (NILP (help_echo_string)) {
23011 Lisp_Object help, overlay;
23012
23013 /* Check overlays first. */
23014 help = overlay = Qnil;
23015 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
23016 {
23017 overlay = overlay_vec[i];
23018 help = Foverlay_get (overlay, Qhelp_echo);
23019 }
23020
23021 if (!NILP (help))
23022 {
23023 help_echo_string = help;
23024 help_echo_window = window;
23025 help_echo_object = overlay;
23026 help_echo_pos = pos;
23027 }
23028 else
23029 {
23030 Lisp_Object object = glyph->object;
23031 int charpos = glyph->charpos;
23032
23033 /* Try text properties. */
23034 if (STRINGP (object)
23035 && charpos >= 0
23036 && charpos < SCHARS (object))
23037 {
23038 help = Fget_text_property (make_number (charpos),
23039 Qhelp_echo, object);
23040 if (NILP (help))
23041 {
23042 /* If the string itself doesn't specify a help-echo,
23043 see if the buffer text ``under'' it does. */
23044 struct glyph_row *r
23045 = MATRIX_ROW (w->current_matrix, vpos);
23046 int start = MATRIX_ROW_START_CHARPOS (r);
23047 int pos = string_buffer_position (w, object, start);
23048 if (pos > 0)
23049 {
23050 help = Fget_char_property (make_number (pos),
23051 Qhelp_echo, w->buffer);
23052 if (!NILP (help))
23053 {
23054 charpos = pos;
23055 object = w->buffer;
23056 }
23057 }
23058 }
23059 }
23060 else if (BUFFERP (object)
23061 && charpos >= BEGV
23062 && charpos < ZV)
23063 help = Fget_text_property (make_number (charpos), Qhelp_echo,
23064 object);
23065
23066 if (!NILP (help))
23067 {
23068 help_echo_string = help;
23069 help_echo_window = window;
23070 help_echo_object = object;
23071 help_echo_pos = charpos;
23072 }
23073 }
23074 }
23075
23076 /* Look for a `pointer' property. */
23077 if (NILP (pointer))
23078 {
23079 /* Check overlays first. */
23080 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
23081 pointer = Foverlay_get (overlay_vec[i], Qpointer);
23082
23083 if (NILP (pointer))
23084 {
23085 Lisp_Object object = glyph->object;
23086 int charpos = glyph->charpos;
23087
23088 /* Try text properties. */
23089 if (STRINGP (object)
23090 && charpos >= 0
23091 && charpos < SCHARS (object))
23092 {
23093 pointer = Fget_text_property (make_number (charpos),
23094 Qpointer, object);
23095 if (NILP (pointer))
23096 {
23097 /* If the string itself doesn't specify a pointer,
23098 see if the buffer text ``under'' it does. */
23099 struct glyph_row *r
23100 = MATRIX_ROW (w->current_matrix, vpos);
23101 int start = MATRIX_ROW_START_CHARPOS (r);
23102 int pos = string_buffer_position (w, object, start);
23103 if (pos > 0)
23104 pointer = Fget_char_property (make_number (pos),
23105 Qpointer, w->buffer);
23106 }
23107 }
23108 else if (BUFFERP (object)
23109 && charpos >= BEGV
23110 && charpos < ZV)
23111 pointer = Fget_text_property (make_number (charpos),
23112 Qpointer, object);
23113 }
23114 }
23115
23116 BEGV = obegv;
23117 ZV = ozv;
23118 current_buffer = obuf;
23119 }
23120
23121 set_cursor:
23122
23123 define_frame_cursor1 (f, cursor, pointer);
23124 }
23125
23126
23127 /* EXPORT for RIF:
23128 Clear any mouse-face on window W. This function is part of the
23129 redisplay interface, and is called from try_window_id and similar
23130 functions to ensure the mouse-highlight is off. */
23131
23132 void
23133 x_clear_window_mouse_face (w)
23134 struct window *w;
23135 {
23136 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23137 Lisp_Object window;
23138
23139 BLOCK_INPUT;
23140 XSETWINDOW (window, w);
23141 if (EQ (window, dpyinfo->mouse_face_window))
23142 clear_mouse_face (dpyinfo);
23143 UNBLOCK_INPUT;
23144 }
23145
23146
23147 /* EXPORT:
23148 Just discard the mouse face information for frame F, if any.
23149 This is used when the size of F is changed. */
23150
23151 void
23152 cancel_mouse_face (f)
23153 struct frame *f;
23154 {
23155 Lisp_Object window;
23156 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23157
23158 window = dpyinfo->mouse_face_window;
23159 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
23160 {
23161 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
23162 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
23163 dpyinfo->mouse_face_window = Qnil;
23164 }
23165 }
23166
23167
23168 #endif /* HAVE_WINDOW_SYSTEM */
23169
23170 \f
23171 /***********************************************************************
23172 Exposure Events
23173 ***********************************************************************/
23174
23175 #ifdef HAVE_WINDOW_SYSTEM
23176
23177 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
23178 which intersects rectangle R. R is in window-relative coordinates. */
23179
23180 static void
23181 expose_area (w, row, r, area)
23182 struct window *w;
23183 struct glyph_row *row;
23184 XRectangle *r;
23185 enum glyph_row_area area;
23186 {
23187 struct glyph *first = row->glyphs[area];
23188 struct glyph *end = row->glyphs[area] + row->used[area];
23189 struct glyph *last;
23190 int first_x, start_x, x;
23191
23192 if (area == TEXT_AREA && row->fill_line_p)
23193 /* If row extends face to end of line write the whole line. */
23194 draw_glyphs (w, 0, row, area,
23195 0, row->used[area],
23196 DRAW_NORMAL_TEXT, 0);
23197 else
23198 {
23199 /* Set START_X to the window-relative start position for drawing glyphs of
23200 AREA. The first glyph of the text area can be partially visible.
23201 The first glyphs of other areas cannot. */
23202 start_x = window_box_left_offset (w, area);
23203 x = start_x;
23204 if (area == TEXT_AREA)
23205 x += row->x;
23206
23207 /* Find the first glyph that must be redrawn. */
23208 while (first < end
23209 && x + first->pixel_width < r->x)
23210 {
23211 x += first->pixel_width;
23212 ++first;
23213 }
23214
23215 /* Find the last one. */
23216 last = first;
23217 first_x = x;
23218 while (last < end
23219 && x < r->x + r->width)
23220 {
23221 x += last->pixel_width;
23222 ++last;
23223 }
23224
23225 /* Repaint. */
23226 if (last > first)
23227 draw_glyphs (w, first_x - start_x, row, area,
23228 first - row->glyphs[area], last - row->glyphs[area],
23229 DRAW_NORMAL_TEXT, 0);
23230 }
23231 }
23232
23233
23234 /* Redraw the parts of the glyph row ROW on window W intersecting
23235 rectangle R. R is in window-relative coordinates. Value is
23236 non-zero if mouse-face was overwritten. */
23237
23238 static int
23239 expose_line (w, row, r)
23240 struct window *w;
23241 struct glyph_row *row;
23242 XRectangle *r;
23243 {
23244 xassert (row->enabled_p);
23245
23246 if (row->mode_line_p || w->pseudo_window_p)
23247 draw_glyphs (w, 0, row, TEXT_AREA,
23248 0, row->used[TEXT_AREA],
23249 DRAW_NORMAL_TEXT, 0);
23250 else
23251 {
23252 if (row->used[LEFT_MARGIN_AREA])
23253 expose_area (w, row, r, LEFT_MARGIN_AREA);
23254 if (row->used[TEXT_AREA])
23255 expose_area (w, row, r, TEXT_AREA);
23256 if (row->used[RIGHT_MARGIN_AREA])
23257 expose_area (w, row, r, RIGHT_MARGIN_AREA);
23258 draw_row_fringe_bitmaps (w, row);
23259 }
23260
23261 return row->mouse_face_p;
23262 }
23263
23264
23265 /* Redraw those parts of glyphs rows during expose event handling that
23266 overlap other rows. Redrawing of an exposed line writes over parts
23267 of lines overlapping that exposed line; this function fixes that.
23268
23269 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
23270 row in W's current matrix that is exposed and overlaps other rows.
23271 LAST_OVERLAPPING_ROW is the last such row. */
23272
23273 static void
23274 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
23275 struct window *w;
23276 struct glyph_row *first_overlapping_row;
23277 struct glyph_row *last_overlapping_row;
23278 {
23279 struct glyph_row *row;
23280
23281 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
23282 if (row->overlapping_p)
23283 {
23284 xassert (row->enabled_p && !row->mode_line_p);
23285
23286 if (row->used[LEFT_MARGIN_AREA])
23287 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
23288
23289 if (row->used[TEXT_AREA])
23290 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
23291
23292 if (row->used[RIGHT_MARGIN_AREA])
23293 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
23294 }
23295 }
23296
23297
23298 /* Return non-zero if W's cursor intersects rectangle R. */
23299
23300 static int
23301 phys_cursor_in_rect_p (w, r)
23302 struct window *w;
23303 XRectangle *r;
23304 {
23305 XRectangle cr, result;
23306 struct glyph *cursor_glyph;
23307
23308 cursor_glyph = get_phys_cursor_glyph (w);
23309 if (cursor_glyph)
23310 {
23311 /* r is relative to W's box, but w->phys_cursor.x is relative
23312 to left edge of W's TEXT area. Adjust it. */
23313 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
23314 cr.y = w->phys_cursor.y;
23315 cr.width = cursor_glyph->pixel_width;
23316 cr.height = w->phys_cursor_height;
23317 /* ++KFS: W32 version used W32-specific IntersectRect here, but
23318 I assume the effect is the same -- and this is portable. */
23319 return x_intersect_rectangles (&cr, r, &result);
23320 }
23321 else
23322 return 0;
23323 }
23324
23325
23326 /* EXPORT:
23327 Draw a vertical window border to the right of window W if W doesn't
23328 have vertical scroll bars. */
23329
23330 void
23331 x_draw_vertical_border (w)
23332 struct window *w;
23333 {
23334 /* We could do better, if we knew what type of scroll-bar the adjacent
23335 windows (on either side) have... But we don't :-(
23336 However, I think this works ok. ++KFS 2003-04-25 */
23337
23338 /* Redraw borders between horizontally adjacent windows. Don't
23339 do it for frames with vertical scroll bars because either the
23340 right scroll bar of a window, or the left scroll bar of its
23341 neighbor will suffice as a border. */
23342 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
23343 return;
23344
23345 if (!WINDOW_RIGHTMOST_P (w)
23346 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
23347 {
23348 int x0, x1, y0, y1;
23349
23350 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23351 y1 -= 1;
23352
23353 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23354 x1 -= 1;
23355
23356 rif->draw_vertical_window_border (w, x1, y0, y1);
23357 }
23358 else if (!WINDOW_LEFTMOST_P (w)
23359 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
23360 {
23361 int x0, x1, y0, y1;
23362
23363 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23364 y1 -= 1;
23365
23366 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23367 x0 -= 1;
23368
23369 rif->draw_vertical_window_border (w, x0, y0, y1);
23370 }
23371 }
23372
23373
23374 /* Redraw the part of window W intersection rectangle FR. Pixel
23375 coordinates in FR are frame-relative. Call this function with
23376 input blocked. Value is non-zero if the exposure overwrites
23377 mouse-face. */
23378
23379 static int
23380 expose_window (w, fr)
23381 struct window *w;
23382 XRectangle *fr;
23383 {
23384 struct frame *f = XFRAME (w->frame);
23385 XRectangle wr, r;
23386 int mouse_face_overwritten_p = 0;
23387
23388 /* If window is not yet fully initialized, do nothing. This can
23389 happen when toolkit scroll bars are used and a window is split.
23390 Reconfiguring the scroll bar will generate an expose for a newly
23391 created window. */
23392 if (w->current_matrix == NULL)
23393 return 0;
23394
23395 /* When we're currently updating the window, display and current
23396 matrix usually don't agree. Arrange for a thorough display
23397 later. */
23398 if (w == updated_window)
23399 {
23400 SET_FRAME_GARBAGED (f);
23401 return 0;
23402 }
23403
23404 /* Frame-relative pixel rectangle of W. */
23405 wr.x = WINDOW_LEFT_EDGE_X (w);
23406 wr.y = WINDOW_TOP_EDGE_Y (w);
23407 wr.width = WINDOW_TOTAL_WIDTH (w);
23408 wr.height = WINDOW_TOTAL_HEIGHT (w);
23409
23410 if (x_intersect_rectangles (fr, &wr, &r))
23411 {
23412 int yb = window_text_bottom_y (w);
23413 struct glyph_row *row;
23414 int cursor_cleared_p;
23415 struct glyph_row *first_overlapping_row, *last_overlapping_row;
23416
23417 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
23418 r.x, r.y, r.width, r.height));
23419
23420 /* Convert to window coordinates. */
23421 r.x -= WINDOW_LEFT_EDGE_X (w);
23422 r.y -= WINDOW_TOP_EDGE_Y (w);
23423
23424 /* Turn off the cursor. */
23425 if (!w->pseudo_window_p
23426 && phys_cursor_in_rect_p (w, &r))
23427 {
23428 x_clear_cursor (w);
23429 cursor_cleared_p = 1;
23430 }
23431 else
23432 cursor_cleared_p = 0;
23433
23434 /* Update lines intersecting rectangle R. */
23435 first_overlapping_row = last_overlapping_row = NULL;
23436 for (row = w->current_matrix->rows;
23437 row->enabled_p;
23438 ++row)
23439 {
23440 int y0 = row->y;
23441 int y1 = MATRIX_ROW_BOTTOM_Y (row);
23442
23443 if ((y0 >= r.y && y0 < r.y + r.height)
23444 || (y1 > r.y && y1 < r.y + r.height)
23445 || (r.y >= y0 && r.y < y1)
23446 || (r.y + r.height > y0 && r.y + r.height < y1))
23447 {
23448 /* A header line may be overlapping, but there is no need
23449 to fix overlapping areas for them. KFS 2005-02-12 */
23450 if (row->overlapping_p && !row->mode_line_p)
23451 {
23452 if (first_overlapping_row == NULL)
23453 first_overlapping_row = row;
23454 last_overlapping_row = row;
23455 }
23456
23457 if (expose_line (w, row, &r))
23458 mouse_face_overwritten_p = 1;
23459 }
23460
23461 if (y1 >= yb)
23462 break;
23463 }
23464
23465 /* Display the mode line if there is one. */
23466 if (WINDOW_WANTS_MODELINE_P (w)
23467 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
23468 row->enabled_p)
23469 && row->y < r.y + r.height)
23470 {
23471 if (expose_line (w, row, &r))
23472 mouse_face_overwritten_p = 1;
23473 }
23474
23475 if (!w->pseudo_window_p)
23476 {
23477 /* Fix the display of overlapping rows. */
23478 if (first_overlapping_row)
23479 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
23480
23481 /* Draw border between windows. */
23482 x_draw_vertical_border (w);
23483
23484 /* Turn the cursor on again. */
23485 if (cursor_cleared_p)
23486 update_window_cursor (w, 1);
23487 }
23488 }
23489
23490 return mouse_face_overwritten_p;
23491 }
23492
23493
23494
23495 /* Redraw (parts) of all windows in the window tree rooted at W that
23496 intersect R. R contains frame pixel coordinates. Value is
23497 non-zero if the exposure overwrites mouse-face. */
23498
23499 static int
23500 expose_window_tree (w, r)
23501 struct window *w;
23502 XRectangle *r;
23503 {
23504 struct frame *f = XFRAME (w->frame);
23505 int mouse_face_overwritten_p = 0;
23506
23507 while (w && !FRAME_GARBAGED_P (f))
23508 {
23509 if (!NILP (w->hchild))
23510 mouse_face_overwritten_p
23511 |= expose_window_tree (XWINDOW (w->hchild), r);
23512 else if (!NILP (w->vchild))
23513 mouse_face_overwritten_p
23514 |= expose_window_tree (XWINDOW (w->vchild), r);
23515 else
23516 mouse_face_overwritten_p |= expose_window (w, r);
23517
23518 w = NILP (w->next) ? NULL : XWINDOW (w->next);
23519 }
23520
23521 return mouse_face_overwritten_p;
23522 }
23523
23524
23525 /* EXPORT:
23526 Redisplay an exposed area of frame F. X and Y are the upper-left
23527 corner of the exposed rectangle. W and H are width and height of
23528 the exposed area. All are pixel values. W or H zero means redraw
23529 the entire frame. */
23530
23531 void
23532 expose_frame (f, x, y, w, h)
23533 struct frame *f;
23534 int x, y, w, h;
23535 {
23536 XRectangle r;
23537 int mouse_face_overwritten_p = 0;
23538
23539 TRACE ((stderr, "expose_frame "));
23540
23541 /* No need to redraw if frame will be redrawn soon. */
23542 if (FRAME_GARBAGED_P (f))
23543 {
23544 TRACE ((stderr, " garbaged\n"));
23545 return;
23546 }
23547
23548 /* If basic faces haven't been realized yet, there is no point in
23549 trying to redraw anything. This can happen when we get an expose
23550 event while Emacs is starting, e.g. by moving another window. */
23551 if (FRAME_FACE_CACHE (f) == NULL
23552 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
23553 {
23554 TRACE ((stderr, " no faces\n"));
23555 return;
23556 }
23557
23558 if (w == 0 || h == 0)
23559 {
23560 r.x = r.y = 0;
23561 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
23562 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
23563 }
23564 else
23565 {
23566 r.x = x;
23567 r.y = y;
23568 r.width = w;
23569 r.height = h;
23570 }
23571
23572 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
23573 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
23574
23575 if (WINDOWP (f->tool_bar_window))
23576 mouse_face_overwritten_p
23577 |= expose_window (XWINDOW (f->tool_bar_window), &r);
23578
23579 #ifdef HAVE_X_WINDOWS
23580 #ifndef MSDOS
23581 #ifndef USE_X_TOOLKIT
23582 if (WINDOWP (f->menu_bar_window))
23583 mouse_face_overwritten_p
23584 |= expose_window (XWINDOW (f->menu_bar_window), &r);
23585 #endif /* not USE_X_TOOLKIT */
23586 #endif
23587 #endif
23588
23589 /* Some window managers support a focus-follows-mouse style with
23590 delayed raising of frames. Imagine a partially obscured frame,
23591 and moving the mouse into partially obscured mouse-face on that
23592 frame. The visible part of the mouse-face will be highlighted,
23593 then the WM raises the obscured frame. With at least one WM, KDE
23594 2.1, Emacs is not getting any event for the raising of the frame
23595 (even tried with SubstructureRedirectMask), only Expose events.
23596 These expose events will draw text normally, i.e. not
23597 highlighted. Which means we must redo the highlight here.
23598 Subsume it under ``we love X''. --gerd 2001-08-15 */
23599 /* Included in Windows version because Windows most likely does not
23600 do the right thing if any third party tool offers
23601 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
23602 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
23603 {
23604 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23605 if (f == dpyinfo->mouse_face_mouse_frame)
23606 {
23607 int x = dpyinfo->mouse_face_mouse_x;
23608 int y = dpyinfo->mouse_face_mouse_y;
23609 clear_mouse_face (dpyinfo);
23610 note_mouse_highlight (f, x, y);
23611 }
23612 }
23613 }
23614
23615
23616 /* EXPORT:
23617 Determine the intersection of two rectangles R1 and R2. Return
23618 the intersection in *RESULT. Value is non-zero if RESULT is not
23619 empty. */
23620
23621 int
23622 x_intersect_rectangles (r1, r2, result)
23623 XRectangle *r1, *r2, *result;
23624 {
23625 XRectangle *left, *right;
23626 XRectangle *upper, *lower;
23627 int intersection_p = 0;
23628
23629 /* Rearrange so that R1 is the left-most rectangle. */
23630 if (r1->x < r2->x)
23631 left = r1, right = r2;
23632 else
23633 left = r2, right = r1;
23634
23635 /* X0 of the intersection is right.x0, if this is inside R1,
23636 otherwise there is no intersection. */
23637 if (right->x <= left->x + left->width)
23638 {
23639 result->x = right->x;
23640
23641 /* The right end of the intersection is the minimum of the
23642 the right ends of left and right. */
23643 result->width = (min (left->x + left->width, right->x + right->width)
23644 - result->x);
23645
23646 /* Same game for Y. */
23647 if (r1->y < r2->y)
23648 upper = r1, lower = r2;
23649 else
23650 upper = r2, lower = r1;
23651
23652 /* The upper end of the intersection is lower.y0, if this is inside
23653 of upper. Otherwise, there is no intersection. */
23654 if (lower->y <= upper->y + upper->height)
23655 {
23656 result->y = lower->y;
23657
23658 /* The lower end of the intersection is the minimum of the lower
23659 ends of upper and lower. */
23660 result->height = (min (lower->y + lower->height,
23661 upper->y + upper->height)
23662 - result->y);
23663 intersection_p = 1;
23664 }
23665 }
23666
23667 return intersection_p;
23668 }
23669
23670 #endif /* HAVE_WINDOW_SYSTEM */
23671
23672 \f
23673 /***********************************************************************
23674 Initialization
23675 ***********************************************************************/
23676
23677 void
23678 syms_of_xdisp ()
23679 {
23680 Vwith_echo_area_save_vector = Qnil;
23681 staticpro (&Vwith_echo_area_save_vector);
23682
23683 Vmessage_stack = Qnil;
23684 staticpro (&Vmessage_stack);
23685
23686 Qinhibit_redisplay = intern ("inhibit-redisplay");
23687 staticpro (&Qinhibit_redisplay);
23688
23689 message_dolog_marker1 = Fmake_marker ();
23690 staticpro (&message_dolog_marker1);
23691 message_dolog_marker2 = Fmake_marker ();
23692 staticpro (&message_dolog_marker2);
23693 message_dolog_marker3 = Fmake_marker ();
23694 staticpro (&message_dolog_marker3);
23695
23696 #if GLYPH_DEBUG
23697 defsubr (&Sdump_frame_glyph_matrix);
23698 defsubr (&Sdump_glyph_matrix);
23699 defsubr (&Sdump_glyph_row);
23700 defsubr (&Sdump_tool_bar_row);
23701 defsubr (&Strace_redisplay);
23702 defsubr (&Strace_to_stderr);
23703 #endif
23704 #ifdef HAVE_WINDOW_SYSTEM
23705 defsubr (&Stool_bar_lines_needed);
23706 defsubr (&Slookup_image_map);
23707 #endif
23708 defsubr (&Sformat_mode_line);
23709
23710 staticpro (&Qmenu_bar_update_hook);
23711 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
23712
23713 staticpro (&Qoverriding_terminal_local_map);
23714 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
23715
23716 staticpro (&Qoverriding_local_map);
23717 Qoverriding_local_map = intern ("overriding-local-map");
23718
23719 staticpro (&Qwindow_scroll_functions);
23720 Qwindow_scroll_functions = intern ("window-scroll-functions");
23721
23722 staticpro (&Qredisplay_end_trigger_functions);
23723 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
23724
23725 staticpro (&Qinhibit_point_motion_hooks);
23726 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
23727
23728 QCdata = intern (":data");
23729 staticpro (&QCdata);
23730 Qdisplay = intern ("display");
23731 staticpro (&Qdisplay);
23732 Qspace_width = intern ("space-width");
23733 staticpro (&Qspace_width);
23734 Qraise = intern ("raise");
23735 staticpro (&Qraise);
23736 Qslice = intern ("slice");
23737 staticpro (&Qslice);
23738 Qspace = intern ("space");
23739 staticpro (&Qspace);
23740 Qmargin = intern ("margin");
23741 staticpro (&Qmargin);
23742 Qpointer = intern ("pointer");
23743 staticpro (&Qpointer);
23744 Qleft_margin = intern ("left-margin");
23745 staticpro (&Qleft_margin);
23746 Qright_margin = intern ("right-margin");
23747 staticpro (&Qright_margin);
23748 Qcenter = intern ("center");
23749 staticpro (&Qcenter);
23750 Qline_height = intern ("line-height");
23751 staticpro (&Qline_height);
23752 QCalign_to = intern (":align-to");
23753 staticpro (&QCalign_to);
23754 QCrelative_width = intern (":relative-width");
23755 staticpro (&QCrelative_width);
23756 QCrelative_height = intern (":relative-height");
23757 staticpro (&QCrelative_height);
23758 QCeval = intern (":eval");
23759 staticpro (&QCeval);
23760 QCpropertize = intern (":propertize");
23761 staticpro (&QCpropertize);
23762 QCfile = intern (":file");
23763 staticpro (&QCfile);
23764 Qfontified = intern ("fontified");
23765 staticpro (&Qfontified);
23766 Qfontification_functions = intern ("fontification-functions");
23767 staticpro (&Qfontification_functions);
23768 Qtrailing_whitespace = intern ("trailing-whitespace");
23769 staticpro (&Qtrailing_whitespace);
23770 Qescape_glyph = intern ("escape-glyph");
23771 staticpro (&Qescape_glyph);
23772 Qnobreak_space = intern ("nobreak-space");
23773 staticpro (&Qnobreak_space);
23774 Qimage = intern ("image");
23775 staticpro (&Qimage);
23776 QCmap = intern (":map");
23777 staticpro (&QCmap);
23778 QCpointer = intern (":pointer");
23779 staticpro (&QCpointer);
23780 Qrect = intern ("rect");
23781 staticpro (&Qrect);
23782 Qcircle = intern ("circle");
23783 staticpro (&Qcircle);
23784 Qpoly = intern ("poly");
23785 staticpro (&Qpoly);
23786 Qmessage_truncate_lines = intern ("message-truncate-lines");
23787 staticpro (&Qmessage_truncate_lines);
23788 Qgrow_only = intern ("grow-only");
23789 staticpro (&Qgrow_only);
23790 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
23791 staticpro (&Qinhibit_menubar_update);
23792 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
23793 staticpro (&Qinhibit_eval_during_redisplay);
23794 Qposition = intern ("position");
23795 staticpro (&Qposition);
23796 Qbuffer_position = intern ("buffer-position");
23797 staticpro (&Qbuffer_position);
23798 Qobject = intern ("object");
23799 staticpro (&Qobject);
23800 Qbar = intern ("bar");
23801 staticpro (&Qbar);
23802 Qhbar = intern ("hbar");
23803 staticpro (&Qhbar);
23804 Qbox = intern ("box");
23805 staticpro (&Qbox);
23806 Qhollow = intern ("hollow");
23807 staticpro (&Qhollow);
23808 Qhand = intern ("hand");
23809 staticpro (&Qhand);
23810 Qarrow = intern ("arrow");
23811 staticpro (&Qarrow);
23812 Qtext = intern ("text");
23813 staticpro (&Qtext);
23814 Qrisky_local_variable = intern ("risky-local-variable");
23815 staticpro (&Qrisky_local_variable);
23816 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
23817 staticpro (&Qinhibit_free_realized_faces);
23818
23819 list_of_error = Fcons (Fcons (intern ("error"),
23820 Fcons (intern ("void-variable"), Qnil)),
23821 Qnil);
23822 staticpro (&list_of_error);
23823
23824 Qlast_arrow_position = intern ("last-arrow-position");
23825 staticpro (&Qlast_arrow_position);
23826 Qlast_arrow_string = intern ("last-arrow-string");
23827 staticpro (&Qlast_arrow_string);
23828
23829 Qoverlay_arrow_string = intern ("overlay-arrow-string");
23830 staticpro (&Qoverlay_arrow_string);
23831 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
23832 staticpro (&Qoverlay_arrow_bitmap);
23833
23834 echo_buffer[0] = echo_buffer[1] = Qnil;
23835 staticpro (&echo_buffer[0]);
23836 staticpro (&echo_buffer[1]);
23837
23838 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
23839 staticpro (&echo_area_buffer[0]);
23840 staticpro (&echo_area_buffer[1]);
23841
23842 Vmessages_buffer_name = build_string ("*Messages*");
23843 staticpro (&Vmessages_buffer_name);
23844
23845 mode_line_proptrans_alist = Qnil;
23846 staticpro (&mode_line_proptrans_alist);
23847 mode_line_string_list = Qnil;
23848 staticpro (&mode_line_string_list);
23849 mode_line_string_face = Qnil;
23850 staticpro (&mode_line_string_face);
23851 mode_line_string_face_prop = Qnil;
23852 staticpro (&mode_line_string_face_prop);
23853 Vmode_line_unwind_vector = Qnil;
23854 staticpro (&Vmode_line_unwind_vector);
23855
23856 help_echo_string = Qnil;
23857 staticpro (&help_echo_string);
23858 help_echo_object = Qnil;
23859 staticpro (&help_echo_object);
23860 help_echo_window = Qnil;
23861 staticpro (&help_echo_window);
23862 previous_help_echo_string = Qnil;
23863 staticpro (&previous_help_echo_string);
23864 help_echo_pos = -1;
23865
23866 #ifdef HAVE_WINDOW_SYSTEM
23867 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
23868 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
23869 For example, if a block cursor is over a tab, it will be drawn as
23870 wide as that tab on the display. */);
23871 x_stretch_cursor_p = 0;
23872 #endif
23873
23874 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
23875 doc: /* *Non-nil means highlight trailing whitespace.
23876 The face used for trailing whitespace is `trailing-whitespace'. */);
23877 Vshow_trailing_whitespace = Qnil;
23878
23879 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
23880 doc: /* *Control highlighting of nobreak space and soft hyphen.
23881 A value of t means highlight the character itself (for nobreak space,
23882 use face `nobreak-space').
23883 A value of nil means no highlighting.
23884 Other values mean display the escape glyph followed by an ordinary
23885 space or ordinary hyphen. */);
23886 Vnobreak_char_display = Qt;
23887
23888 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
23889 doc: /* *The pointer shape to show in void text areas.
23890 A value of nil means to show the text pointer. Other options are `arrow',
23891 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
23892 Vvoid_text_area_pointer = Qarrow;
23893
23894 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
23895 doc: /* Non-nil means don't actually do any redisplay.
23896 This is used for internal purposes. */);
23897 Vinhibit_redisplay = Qnil;
23898
23899 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
23900 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
23901 Vglobal_mode_string = Qnil;
23902
23903 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
23904 doc: /* Marker for where to display an arrow on top of the buffer text.
23905 This must be the beginning of a line in order to work.
23906 See also `overlay-arrow-string'. */);
23907 Voverlay_arrow_position = Qnil;
23908
23909 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
23910 doc: /* String to display as an arrow in non-window frames.
23911 See also `overlay-arrow-position'. */);
23912 Voverlay_arrow_string = build_string ("=>");
23913
23914 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
23915 doc: /* List of variables (symbols) which hold markers for overlay arrows.
23916 The symbols on this list are examined during redisplay to determine
23917 where to display overlay arrows. */);
23918 Voverlay_arrow_variable_list
23919 = Fcons (intern ("overlay-arrow-position"), Qnil);
23920
23921 DEFVAR_INT ("scroll-step", &scroll_step,
23922 doc: /* *The number of lines to try scrolling a window by when point moves out.
23923 If that fails to bring point back on frame, point is centered instead.
23924 If this is zero, point is always centered after it moves off frame.
23925 If you want scrolling to always be a line at a time, you should set
23926 `scroll-conservatively' to a large value rather than set this to 1. */);
23927
23928 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
23929 doc: /* *Scroll up to this many lines, to bring point back on screen.
23930 A value of zero means to scroll the text to center point vertically
23931 in the window. */);
23932 scroll_conservatively = 0;
23933
23934 DEFVAR_INT ("scroll-margin", &scroll_margin,
23935 doc: /* *Number of lines of margin at the top and bottom of a window.
23936 Recenter the window whenever point gets within this many lines
23937 of the top or bottom of the window. */);
23938 scroll_margin = 0;
23939
23940 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
23941 doc: /* Pixels per inch value for non-window system displays.
23942 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
23943 Vdisplay_pixels_per_inch = make_float (72.0);
23944
23945 #if GLYPH_DEBUG
23946 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
23947 #endif
23948
23949 DEFVAR_BOOL ("truncate-partial-width-windows",
23950 &truncate_partial_width_windows,
23951 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
23952 truncate_partial_width_windows = 1;
23953
23954 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
23955 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
23956 Any other value means to use the appropriate face, `mode-line',
23957 `header-line', or `menu' respectively. */);
23958 mode_line_inverse_video = 1;
23959
23960 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
23961 doc: /* *Maximum buffer size for which line number should be displayed.
23962 If the buffer is bigger than this, the line number does not appear
23963 in the mode line. A value of nil means no limit. */);
23964 Vline_number_display_limit = Qnil;
23965
23966 DEFVAR_INT ("line-number-display-limit-width",
23967 &line_number_display_limit_width,
23968 doc: /* *Maximum line width (in characters) for line number display.
23969 If the average length of the lines near point is bigger than this, then the
23970 line number may be omitted from the mode line. */);
23971 line_number_display_limit_width = 200;
23972
23973 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
23974 doc: /* *Non-nil means highlight region even in nonselected windows. */);
23975 highlight_nonselected_windows = 0;
23976
23977 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
23978 doc: /* Non-nil if more than one frame is visible on this display.
23979 Minibuffer-only frames don't count, but iconified frames do.
23980 This variable is not guaranteed to be accurate except while processing
23981 `frame-title-format' and `icon-title-format'. */);
23982
23983 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
23984 doc: /* Template for displaying the title bar of visible frames.
23985 \(Assuming the window manager supports this feature.)
23986 This variable has the same structure as `mode-line-format' (which see),
23987 and is used only on frames for which no explicit name has been set
23988 \(see `modify-frame-parameters'). */);
23989
23990 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
23991 doc: /* Template for displaying the title bar of an iconified frame.
23992 \(Assuming the window manager supports this feature.)
23993 This variable has the same structure as `mode-line-format' (which see),
23994 and is used only on frames for which no explicit name has been set
23995 \(see `modify-frame-parameters'). */);
23996 Vicon_title_format
23997 = Vframe_title_format
23998 = Fcons (intern ("multiple-frames"),
23999 Fcons (build_string ("%b"),
24000 Fcons (Fcons (empty_string,
24001 Fcons (intern ("invocation-name"),
24002 Fcons (build_string ("@"),
24003 Fcons (intern ("system-name"),
24004 Qnil)))),
24005 Qnil)));
24006
24007 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
24008 doc: /* Maximum number of lines to keep in the message log buffer.
24009 If nil, disable message logging. If t, log messages but don't truncate
24010 the buffer when it becomes large. */);
24011 Vmessage_log_max = make_number (50);
24012
24013 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
24014 doc: /* Functions called before redisplay, if window sizes have changed.
24015 The value should be a list of functions that take one argument.
24016 Just before redisplay, for each frame, if any of its windows have changed
24017 size since the last redisplay, or have been split or deleted,
24018 all the functions in the list are called, with the frame as argument. */);
24019 Vwindow_size_change_functions = Qnil;
24020
24021 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
24022 doc: /* List of functions to call before redisplaying a window with scrolling.
24023 Each function is called with two arguments, the window
24024 and its new display-start position. Note that the value of `window-end'
24025 is not valid when these functions are called. */);
24026 Vwindow_scroll_functions = Qnil;
24027
24028 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
24029 doc: /* Functions called when redisplay of a window reaches the end trigger.
24030 Each function is called with two arguments, the window and the end trigger value.
24031 See `set-window-redisplay-end-trigger'. */);
24032 Vredisplay_end_trigger_functions = Qnil;
24033
24034 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
24035 doc: /* *Non-nil means autoselect window with mouse pointer.
24036 If nil, do not autoselect windows.
24037 A positive number means delay autoselection by that many seconds: a
24038 window is autoselected only after the mouse has remained in that
24039 window for the duration of the delay.
24040 A negative number has a similar effect, but causes windows to be
24041 autoselected only after the mouse has stopped moving. \(Because of
24042 the way Emacs compares mouse events, you will occasionally wait twice
24043 that time before the window gets selected.\)
24044 Any other value means to autoselect window instantaneously when the
24045 mouse pointer enters it.
24046
24047 Autoselection selects the minibuffer only if it is active, and never
24048 unselects the minibuffer if it is active. */);
24049 Vmouse_autoselect_window = Qnil;
24050
24051 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
24052 doc: /* *Non-nil means automatically resize tool-bars.
24053 This increases a tool-bar's height if not all tool-bar items are visible.
24054 It decreases a tool-bar's height when it would display blank lines
24055 otherwise. */);
24056 auto_resize_tool_bars_p = 1;
24057
24058 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
24059 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
24060 auto_raise_tool_bar_buttons_p = 1;
24061
24062 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
24063 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
24064 make_cursor_line_fully_visible_p = 1;
24065
24066 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
24067 doc: /* *Border below tool-bar in pixels.
24068 If an integer, use it as the height of the border.
24069 If it is one of `internal-border-width' or `border-width', use the
24070 value of the corresponding frame parameter.
24071 Otherwise, no border is added below the tool-bar. */);
24072 Vtool_bar_border = Qinternal_border_width;
24073
24074 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
24075 doc: /* *Margin around tool-bar buttons in pixels.
24076 If an integer, use that for both horizontal and vertical margins.
24077 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
24078 HORZ specifying the horizontal margin, and VERT specifying the
24079 vertical margin. */);
24080 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
24081
24082 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
24083 doc: /* *Relief thickness of tool-bar buttons. */);
24084 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
24085
24086 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
24087 doc: /* List of functions to call to fontify regions of text.
24088 Each function is called with one argument POS. Functions must
24089 fontify a region starting at POS in the current buffer, and give
24090 fontified regions the property `fontified'. */);
24091 Vfontification_functions = Qnil;
24092 Fmake_variable_buffer_local (Qfontification_functions);
24093
24094 DEFVAR_BOOL ("unibyte-display-via-language-environment",
24095 &unibyte_display_via_language_environment,
24096 doc: /* *Non-nil means display unibyte text according to language environment.
24097 Specifically this means that unibyte non-ASCII characters
24098 are displayed by converting them to the equivalent multibyte characters
24099 according to the current language environment. As a result, they are
24100 displayed according to the current fontset. */);
24101 unibyte_display_via_language_environment = 0;
24102
24103 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
24104 doc: /* *Maximum height for resizing mini-windows.
24105 If a float, it specifies a fraction of the mini-window frame's height.
24106 If an integer, it specifies a number of lines. */);
24107 Vmax_mini_window_height = make_float (0.25);
24108
24109 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
24110 doc: /* *How to resize mini-windows.
24111 A value of nil means don't automatically resize mini-windows.
24112 A value of t means resize them to fit the text displayed in them.
24113 A value of `grow-only', the default, means let mini-windows grow
24114 only, until their display becomes empty, at which point the windows
24115 go back to their normal size. */);
24116 Vresize_mini_windows = Qgrow_only;
24117
24118 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
24119 doc: /* Alist specifying how to blink the cursor off.
24120 Each element has the form (ON-STATE . OFF-STATE). Whenever the
24121 `cursor-type' frame-parameter or variable equals ON-STATE,
24122 comparing using `equal', Emacs uses OFF-STATE to specify
24123 how to blink it off. ON-STATE and OFF-STATE are values for
24124 the `cursor-type' frame parameter.
24125
24126 If a frame's ON-STATE has no entry in this list,
24127 the frame's other specifications determine how to blink the cursor off. */);
24128 Vblink_cursor_alist = Qnil;
24129
24130 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
24131 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
24132 automatic_hscrolling_p = 1;
24133
24134 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
24135 doc: /* *How many columns away from the window edge point is allowed to get
24136 before automatic hscrolling will horizontally scroll the window. */);
24137 hscroll_margin = 5;
24138
24139 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
24140 doc: /* *How many columns to scroll the window when point gets too close to the edge.
24141 When point is less than `hscroll-margin' columns from the window
24142 edge, automatic hscrolling will scroll the window by the amount of columns
24143 determined by this variable. If its value is a positive integer, scroll that
24144 many columns. If it's a positive floating-point number, it specifies the
24145 fraction of the window's width to scroll. If it's nil or zero, point will be
24146 centered horizontally after the scroll. Any other value, including negative
24147 numbers, are treated as if the value were zero.
24148
24149 Automatic hscrolling always moves point outside the scroll margin, so if
24150 point was more than scroll step columns inside the margin, the window will
24151 scroll more than the value given by the scroll step.
24152
24153 Note that the lower bound for automatic hscrolling specified by `scroll-left'
24154 and `scroll-right' overrides this variable's effect. */);
24155 Vhscroll_step = make_number (0);
24156
24157 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
24158 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
24159 Bind this around calls to `message' to let it take effect. */);
24160 message_truncate_lines = 0;
24161
24162 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
24163 doc: /* Normal hook run to update the menu bar definitions.
24164 Redisplay runs this hook before it redisplays the menu bar.
24165 This is used to update submenus such as Buffers,
24166 whose contents depend on various data. */);
24167 Vmenu_bar_update_hook = Qnil;
24168
24169 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
24170 doc: /* Frame for which we are updating a menu.
24171 The enable predicate for a menu binding should check this variable. */);
24172 Vmenu_updating_frame = Qnil;
24173
24174 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
24175 doc: /* Non-nil means don't update menu bars. Internal use only. */);
24176 inhibit_menubar_update = 0;
24177
24178 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
24179 doc: /* Non-nil means don't eval Lisp during redisplay. */);
24180 inhibit_eval_during_redisplay = 0;
24181
24182 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
24183 doc: /* Non-nil means don't free realized faces. Internal use only. */);
24184 inhibit_free_realized_faces = 0;
24185
24186 #if GLYPH_DEBUG
24187 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
24188 doc: /* Inhibit try_window_id display optimization. */);
24189 inhibit_try_window_id = 0;
24190
24191 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
24192 doc: /* Inhibit try_window_reusing display optimization. */);
24193 inhibit_try_window_reusing = 0;
24194
24195 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
24196 doc: /* Inhibit try_cursor_movement display optimization. */);
24197 inhibit_try_cursor_movement = 0;
24198 #endif /* GLYPH_DEBUG */
24199
24200 DEFVAR_INT ("overline-margin", &overline_margin,
24201 doc: /* *Space between overline and text, in pixels.
24202 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
24203 margin to the caracter height. */);
24204 overline_margin = 2;
24205 }
24206
24207
24208 /* Initialize this module when Emacs starts. */
24209
24210 void
24211 init_xdisp ()
24212 {
24213 Lisp_Object root_window;
24214 struct window *mini_w;
24215
24216 current_header_line_height = current_mode_line_height = -1;
24217
24218 CHARPOS (this_line_start_pos) = 0;
24219
24220 mini_w = XWINDOW (minibuf_window);
24221 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
24222
24223 if (!noninteractive)
24224 {
24225 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
24226 int i;
24227
24228 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
24229 set_window_height (root_window,
24230 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
24231 0);
24232 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
24233 set_window_height (minibuf_window, 1, 0);
24234
24235 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
24236 mini_w->total_cols = make_number (FRAME_COLS (f));
24237
24238 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
24239 scratch_glyph_row.glyphs[TEXT_AREA + 1]
24240 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
24241
24242 /* The default ellipsis glyphs `...'. */
24243 for (i = 0; i < 3; ++i)
24244 default_invis_vector[i] = make_number ('.');
24245 }
24246
24247 {
24248 /* Allocate the buffer for frame titles.
24249 Also used for `format-mode-line'. */
24250 int size = 100;
24251 mode_line_noprop_buf = (char *) xmalloc (size);
24252 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
24253 mode_line_noprop_ptr = mode_line_noprop_buf;
24254 mode_line_target = MODE_LINE_DISPLAY;
24255 }
24256
24257 help_echo_showing_p = 0;
24258 }
24259
24260
24261 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
24262 (do not change this comment) */