Merge from emacs--devo--0
[bpt/emacs.git] / 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, 2007 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 3, 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 "character.h"
181 #include "charset.h"
182 #include "indent.h"
183 #include "commands.h"
184 #include "keymap.h"
185 #include "macros.h"
186 #include "disptab.h"
187 #include "termhooks.h"
188 #include "intervals.h"
189 #include "coding.h"
190 #include "process.h"
191 #include "region-cache.h"
192 #include "fontset.h"
193 #include "blockinput.h"
194
195 #ifdef HAVE_X_WINDOWS
196 #include "xterm.h"
197 #endif
198 #ifdef WINDOWSNT
199 #include "w32term.h"
200 #endif
201 #ifdef MAC_OS
202 #include "macterm.h"
203 #endif
204
205 #ifdef HAVE_WINDOW_SYSTEM
206 #ifdef USE_FONT_BACKEND
207 #include "font.h"
208 #endif /* USE_FONT_BACKEND */
209 #endif /* HAVE_WINDOW_SYSTEM */
210
211 #ifndef FRAME_X_OUTPUT
212 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
213 #endif
214
215 #define INFINITY 10000000
216
217 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
218 || defined (USE_GTK)
219 extern void set_frame_menubar P_ ((struct frame *f, int, int));
220 extern int pending_menu_activation;
221 #endif
222
223 extern int interrupt_input;
224 extern int command_loop_level;
225
226 extern Lisp_Object do_mouse_tracking;
227
228 extern int minibuffer_auto_raise;
229 extern Lisp_Object Vminibuffer_list;
230
231 extern Lisp_Object Qface;
232 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
233
234 extern Lisp_Object Voverriding_local_map;
235 extern Lisp_Object Voverriding_local_map_menu_flag;
236 extern Lisp_Object Qmenu_item;
237 extern Lisp_Object Qwhen;
238 extern Lisp_Object Qhelp_echo;
239
240 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
241 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
242 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
243 Lisp_Object Qinhibit_point_motion_hooks;
244 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
245 Lisp_Object Qfontified;
246 Lisp_Object Qgrow_only;
247 Lisp_Object Qinhibit_eval_during_redisplay;
248 Lisp_Object Qbuffer_position, Qposition, Qobject;
249
250 /* Cursor shapes */
251 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
252
253 /* Pointer shapes */
254 Lisp_Object Qarrow, Qhand, Qtext;
255
256 Lisp_Object Qrisky_local_variable;
257
258 /* Holds the list (error). */
259 Lisp_Object list_of_error;
260
261 /* Functions called to fontify regions of text. */
262
263 Lisp_Object Vfontification_functions;
264 Lisp_Object Qfontification_functions;
265
266 /* Non-nil means automatically select any window when the mouse
267 cursor moves into it. */
268 Lisp_Object Vmouse_autoselect_window;
269
270 /* Non-zero means draw tool bar buttons raised when the mouse moves
271 over them. */
272
273 int auto_raise_tool_bar_buttons_p;
274
275 /* Non-zero means to reposition window if cursor line is only partially visible. */
276
277 int make_cursor_line_fully_visible_p;
278
279 /* Margin below tool bar in pixels. 0 or nil means no margin.
280 If value is `internal-border-width' or `border-width',
281 the corresponding frame parameter is used. */
282
283 Lisp_Object Vtool_bar_border;
284
285 /* Margin around tool bar buttons in pixels. */
286
287 Lisp_Object Vtool_bar_button_margin;
288
289 /* Thickness of shadow to draw around tool bar buttons. */
290
291 EMACS_INT tool_bar_button_relief;
292
293 /* Non-nil means automatically resize tool-bars so that all tool-bar
294 items are visible, and no blank lines remain.
295
296 If value is `grow-only', only make tool-bar bigger. */
297
298 Lisp_Object Vauto_resize_tool_bars;
299
300 /* Non-zero means draw block and hollow cursor as wide as the glyph
301 under it. For example, if a block cursor is over a tab, it will be
302 drawn as wide as that tab on the display. */
303
304 int x_stretch_cursor_p;
305
306 /* Non-nil means don't actually do any redisplay. */
307
308 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
309
310 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
311
312 int inhibit_eval_during_redisplay;
313
314 /* Names of text properties relevant for redisplay. */
315
316 Lisp_Object Qdisplay;
317 extern Lisp_Object Qface, Qinvisible, Qwidth;
318
319 /* Symbols used in text property values. */
320
321 Lisp_Object Vdisplay_pixels_per_inch;
322 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
323 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
324 Lisp_Object Qslice;
325 Lisp_Object Qcenter;
326 Lisp_Object Qmargin, Qpointer;
327 Lisp_Object Qline_height;
328 extern Lisp_Object Qheight;
329 extern Lisp_Object QCwidth, QCheight, QCascent;
330 extern Lisp_Object Qscroll_bar;
331 extern Lisp_Object Qcursor;
332
333 /* Non-nil means highlight trailing whitespace. */
334
335 Lisp_Object Vshow_trailing_whitespace;
336
337 /* Non-nil means escape non-break space and hyphens. */
338
339 Lisp_Object Vnobreak_char_display;
340
341 #ifdef HAVE_WINDOW_SYSTEM
342 extern Lisp_Object Voverflow_newline_into_fringe;
343
344 /* Test if overflow newline into fringe. Called with iterator IT
345 at or past right window margin, and with IT->current_x set. */
346
347 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
348 (!NILP (Voverflow_newline_into_fringe) \
349 && FRAME_WINDOW_P (it->f) \
350 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
351 && it->current_x == it->last_visible_x)
352
353 #endif /* HAVE_WINDOW_SYSTEM */
354
355 /* Non-nil means show the text cursor in void text areas
356 i.e. in blank areas after eol and eob. This used to be
357 the default in 21.3. */
358
359 Lisp_Object Vvoid_text_area_pointer;
360
361 /* Name of the face used to highlight trailing whitespace. */
362
363 Lisp_Object Qtrailing_whitespace;
364
365 /* Name and number of the face used to highlight escape glyphs. */
366
367 Lisp_Object Qescape_glyph;
368
369 /* Name and number of the face used to highlight non-breaking spaces. */
370
371 Lisp_Object Qnobreak_space;
372
373 /* The symbol `image' which is the car of the lists used to represent
374 images in Lisp. */
375
376 Lisp_Object Qimage;
377
378 /* The image map types. */
379 Lisp_Object QCmap, QCpointer;
380 Lisp_Object Qrect, Qcircle, Qpoly;
381
382 /* Non-zero means print newline to stdout before next mini-buffer
383 message. */
384
385 int noninteractive_need_newline;
386
387 /* Non-zero means print newline to message log before next message. */
388
389 static int message_log_need_newline;
390
391 /* Three markers that message_dolog uses.
392 It could allocate them itself, but that causes trouble
393 in handling memory-full errors. */
394 static Lisp_Object message_dolog_marker1;
395 static Lisp_Object message_dolog_marker2;
396 static Lisp_Object message_dolog_marker3;
397 \f
398 /* The buffer position of the first character appearing entirely or
399 partially on the line of the selected window which contains the
400 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
401 redisplay optimization in redisplay_internal. */
402
403 static struct text_pos this_line_start_pos;
404
405 /* Number of characters past the end of the line above, including the
406 terminating newline. */
407
408 static struct text_pos this_line_end_pos;
409
410 /* The vertical positions and the height of this line. */
411
412 static int this_line_vpos;
413 static int this_line_y;
414 static int this_line_pixel_height;
415
416 /* X position at which this display line starts. Usually zero;
417 negative if first character is partially visible. */
418
419 static int this_line_start_x;
420
421 /* Buffer that this_line_.* variables are referring to. */
422
423 static struct buffer *this_line_buffer;
424
425 /* Nonzero means truncate lines in all windows less wide than the
426 frame. */
427
428 int truncate_partial_width_windows;
429
430 /* A flag to control how to display unibyte 8-bit character. */
431
432 int unibyte_display_via_language_environment;
433
434 /* Nonzero means we have more than one non-mini-buffer-only frame.
435 Not guaranteed to be accurate except while parsing
436 frame-title-format. */
437
438 int multiple_frames;
439
440 Lisp_Object Vglobal_mode_string;
441
442
443 /* List of variables (symbols) which hold markers for overlay arrows.
444 The symbols on this list are examined during redisplay to determine
445 where to display overlay arrows. */
446
447 Lisp_Object Voverlay_arrow_variable_list;
448
449 /* Marker for where to display an arrow on top of the buffer text. */
450
451 Lisp_Object Voverlay_arrow_position;
452
453 /* String to display for the arrow. Only used on terminal frames. */
454
455 Lisp_Object Voverlay_arrow_string;
456
457 /* Values of those variables at last redisplay are stored as
458 properties on `overlay-arrow-position' symbol. However, if
459 Voverlay_arrow_position is a marker, last-arrow-position is its
460 numerical position. */
461
462 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
463
464 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
465 properties on a symbol in overlay-arrow-variable-list. */
466
467 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
468
469 /* Like mode-line-format, but for the title bar on a visible frame. */
470
471 Lisp_Object Vframe_title_format;
472
473 /* Like mode-line-format, but for the title bar on an iconified frame. */
474
475 Lisp_Object Vicon_title_format;
476
477 /* List of functions to call when a window's size changes. These
478 functions get one arg, a frame on which one or more windows' sizes
479 have changed. */
480
481 static Lisp_Object Vwindow_size_change_functions;
482
483 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
484
485 /* Nonzero if an overlay arrow has been displayed in this window. */
486
487 static int overlay_arrow_seen;
488
489 /* Nonzero means highlight the region even in nonselected windows. */
490
491 int highlight_nonselected_windows;
492
493 /* If cursor motion alone moves point off frame, try scrolling this
494 many lines up or down if that will bring it back. */
495
496 static EMACS_INT scroll_step;
497
498 /* Nonzero means scroll just far enough to bring point back on the
499 screen, when appropriate. */
500
501 static EMACS_INT scroll_conservatively;
502
503 /* Recenter the window whenever point gets within this many lines of
504 the top or bottom of the window. This value is translated into a
505 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
506 that there is really a fixed pixel height scroll margin. */
507
508 EMACS_INT scroll_margin;
509
510 /* Number of windows showing the buffer of the selected window (or
511 another buffer with the same base buffer). keyboard.c refers to
512 this. */
513
514 int buffer_shared;
515
516 /* Vector containing glyphs for an ellipsis `...'. */
517
518 static Lisp_Object default_invis_vector[3];
519
520 /* Zero means display the mode-line/header-line/menu-bar in the default face
521 (this slightly odd definition is for compatibility with previous versions
522 of emacs), non-zero means display them using their respective faces.
523
524 This variable is deprecated. */
525
526 int mode_line_inverse_video;
527
528 /* Prompt to display in front of the mini-buffer contents. */
529
530 Lisp_Object minibuf_prompt;
531
532 /* Width of current mini-buffer prompt. Only set after display_line
533 of the line that contains the prompt. */
534
535 int minibuf_prompt_width;
536
537 /* This is the window where the echo area message was displayed. It
538 is always a mini-buffer window, but it may not be the same window
539 currently active as a mini-buffer. */
540
541 Lisp_Object echo_area_window;
542
543 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
544 pushes the current message and the value of
545 message_enable_multibyte on the stack, the function restore_message
546 pops the stack and displays MESSAGE again. */
547
548 Lisp_Object Vmessage_stack;
549
550 /* Nonzero means multibyte characters were enabled when the echo area
551 message was specified. */
552
553 int message_enable_multibyte;
554
555 /* Nonzero if we should redraw the mode lines on the next redisplay. */
556
557 int update_mode_lines;
558
559 /* Nonzero if window sizes or contents have changed since last
560 redisplay that finished. */
561
562 int windows_or_buffers_changed;
563
564 /* Nonzero means a frame's cursor type has been changed. */
565
566 int cursor_type_changed;
567
568 /* Nonzero after display_mode_line if %l was used and it displayed a
569 line number. */
570
571 int line_number_displayed;
572
573 /* Maximum buffer size for which to display line numbers. */
574
575 Lisp_Object Vline_number_display_limit;
576
577 /* Line width to consider when repositioning for line number display. */
578
579 static EMACS_INT line_number_display_limit_width;
580
581 /* Number of lines to keep in the message log buffer. t means
582 infinite. nil means don't log at all. */
583
584 Lisp_Object Vmessage_log_max;
585
586 /* The name of the *Messages* buffer, a string. */
587
588 static Lisp_Object Vmessages_buffer_name;
589
590 /* Current, index 0, and last displayed echo area message. Either
591 buffers from echo_buffers, or nil to indicate no message. */
592
593 Lisp_Object echo_area_buffer[2];
594
595 /* The buffers referenced from echo_area_buffer. */
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 static enum prop_handled handle_auto_composed_prop P_ ((struct it *));
755
756 /* Properties handled by iterators. */
757
758 static struct props it_props[] =
759 {
760 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
761 /* Handle `face' before `display' because some sub-properties of
762 `display' need to know the face. */
763 {&Qface, FACE_PROP_IDX, handle_face_prop},
764 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
765 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
766 {&Qauto_composed, AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
767 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
768 {NULL, 0, NULL}
769 };
770
771 /* Value is the position described by X. If X is a marker, value is
772 the marker_position of X. Otherwise, value is X. */
773
774 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
775
776 /* Enumeration returned by some move_it_.* functions internally. */
777
778 enum move_it_result
779 {
780 /* Not used. Undefined value. */
781 MOVE_UNDEFINED,
782
783 /* Move ended at the requested buffer position or ZV. */
784 MOVE_POS_MATCH_OR_ZV,
785
786 /* Move ended at the requested X pixel position. */
787 MOVE_X_REACHED,
788
789 /* Move within a line ended at the end of a line that must be
790 continued. */
791 MOVE_LINE_CONTINUED,
792
793 /* Move within a line ended at the end of a line that would
794 be displayed truncated. */
795 MOVE_LINE_TRUNCATED,
796
797 /* Move within a line ended at a line end. */
798 MOVE_NEWLINE_OR_CR
799 };
800
801 /* This counter is used to clear the face cache every once in a while
802 in redisplay_internal. It is incremented for each redisplay.
803 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
804 cleared. */
805
806 #define CLEAR_FACE_CACHE_COUNT 500
807 static int clear_face_cache_count;
808
809 /* Similarly for the image cache. */
810
811 #ifdef HAVE_WINDOW_SYSTEM
812 #define CLEAR_IMAGE_CACHE_COUNT 101
813 static int clear_image_cache_count;
814 #endif
815
816 /* Non-zero while redisplay_internal is in progress. */
817
818 int redisplaying_p;
819
820 /* Non-zero means don't free realized faces. Bound while freeing
821 realized faces is dangerous because glyph matrices might still
822 reference them. */
823
824 int inhibit_free_realized_faces;
825 Lisp_Object Qinhibit_free_realized_faces;
826
827 /* If a string, XTread_socket generates an event to display that string.
828 (The display is done in read_char.) */
829
830 Lisp_Object help_echo_string;
831 Lisp_Object help_echo_window;
832 Lisp_Object help_echo_object;
833 int help_echo_pos;
834
835 /* Temporary variable for XTread_socket. */
836
837 Lisp_Object previous_help_echo_string;
838
839 /* Null glyph slice */
840
841 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
842
843 \f
844 /* Function prototypes. */
845
846 static void setup_for_ellipsis P_ ((struct it *, int));
847 static void mark_window_display_accurate_1 P_ ((struct window *, int));
848 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
849 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
850 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
851 static int redisplay_mode_lines P_ ((Lisp_Object, int));
852 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
853
854 #if 0
855 static int invisible_text_between_p P_ ((struct it *, int, int));
856 #endif
857
858 static void pint2str P_ ((char *, int, int));
859 static void pint2hrstr P_ ((char *, int, int));
860 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
861 struct text_pos));
862 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
863 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
864 static void store_mode_line_noprop_char P_ ((char));
865 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
866 static void x_consider_frame_title P_ ((Lisp_Object));
867 static void handle_stop P_ ((struct it *));
868 static int tool_bar_lines_needed P_ ((struct frame *, int *));
869 static int single_display_spec_intangible_p P_ ((Lisp_Object));
870 static void ensure_echo_area_buffers P_ ((void));
871 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
872 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
873 static int with_echo_area_buffer P_ ((struct window *, int,
874 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
875 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
876 static void clear_garbaged_frames P_ ((void));
877 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
878 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
879 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
880 static int display_echo_area P_ ((struct window *));
881 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
882 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
883 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
884 static int string_char_and_length P_ ((const unsigned char *, int, int *));
885 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
886 struct text_pos));
887 static int compute_window_start_on_continuation_line P_ ((struct window *));
888 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
889 static void insert_left_trunc_glyphs P_ ((struct it *));
890 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
891 Lisp_Object));
892 static void extend_face_to_end_of_line P_ ((struct it *));
893 static int append_space_for_newline P_ ((struct it *, int));
894 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
895 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
896 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
897 static int trailing_whitespace_p P_ ((int));
898 static int message_log_check_duplicate P_ ((int, int, int, int));
899 static void push_it P_ ((struct it *));
900 static void pop_it P_ ((struct it *));
901 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
902 static void select_frame_for_redisplay P_ ((Lisp_Object));
903 static void redisplay_internal P_ ((int));
904 static int echo_area_display P_ ((int));
905 static void redisplay_windows P_ ((Lisp_Object));
906 static void redisplay_window P_ ((Lisp_Object, int));
907 static Lisp_Object redisplay_window_error ();
908 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
909 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
910 static int update_menu_bar P_ ((struct frame *, int, int));
911 static int try_window_reusing_current_matrix P_ ((struct window *));
912 static int try_window_id P_ ((struct window *));
913 static int display_line P_ ((struct it *));
914 static int display_mode_lines P_ ((struct window *));
915 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
916 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
917 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
918 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
919 static void display_menu_bar P_ ((struct window *));
920 static int display_count_lines P_ ((int, int, int, int, int *));
921 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
922 int, int, struct it *, int, int, int, int));
923 static void compute_line_metrics P_ ((struct it *));
924 static void run_redisplay_end_trigger_hook P_ ((struct it *));
925 static int get_overlay_strings P_ ((struct it *, int));
926 static int get_overlay_strings_1 P_ ((struct it *, int, int));
927 static void next_overlay_string P_ ((struct it *));
928 static void reseat P_ ((struct it *, struct text_pos, int));
929 static void reseat_1 P_ ((struct it *, struct text_pos, int));
930 static void back_to_previous_visible_line_start P_ ((struct it *));
931 void reseat_at_previous_visible_line_start P_ ((struct it *));
932 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
933 static int next_element_from_ellipsis P_ ((struct it *));
934 static int next_element_from_display_vector P_ ((struct it *));
935 static int next_element_from_string P_ ((struct it *));
936 static int next_element_from_c_string P_ ((struct it *));
937 static int next_element_from_buffer P_ ((struct it *));
938 static int next_element_from_composition P_ ((struct it *));
939 static int next_element_from_image P_ ((struct it *));
940 static int next_element_from_stretch P_ ((struct it *));
941 static void load_overlay_strings P_ ((struct it *, int));
942 static int init_from_display_pos P_ ((struct it *, struct window *,
943 struct display_pos *));
944 static void reseat_to_string P_ ((struct it *, unsigned char *,
945 Lisp_Object, int, int, int, int));
946 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
947 int, int, int));
948 void move_it_vertically_backward P_ ((struct it *, int));
949 static void init_to_row_start P_ ((struct it *, struct window *,
950 struct glyph_row *));
951 static int init_to_row_end P_ ((struct it *, struct window *,
952 struct glyph_row *));
953 static void back_to_previous_line_start P_ ((struct it *));
954 static int forward_to_next_line_start P_ ((struct it *, int *));
955 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
956 Lisp_Object, int));
957 static struct text_pos string_pos P_ ((int, Lisp_Object));
958 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
959 static int number_of_chars P_ ((unsigned char *, int));
960 static void compute_stop_pos P_ ((struct it *));
961 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
962 Lisp_Object));
963 static int face_before_or_after_it_pos P_ ((struct it *, int));
964 static int next_overlay_change P_ ((int));
965 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
966 Lisp_Object, struct text_pos *,
967 int));
968 static int underlying_face_id P_ ((struct it *));
969 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
970 struct window *));
971
972 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
973 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
974
975 #ifdef HAVE_WINDOW_SYSTEM
976
977 static void update_tool_bar P_ ((struct frame *, int));
978 static void build_desired_tool_bar_string P_ ((struct frame *f));
979 static int redisplay_tool_bar P_ ((struct frame *));
980 static void display_tool_bar_line P_ ((struct it *, int));
981 static void notice_overwritten_cursor P_ ((struct window *,
982 enum glyph_row_area,
983 int, int, int, int));
984
985
986
987 #endif /* HAVE_WINDOW_SYSTEM */
988
989 \f
990 /***********************************************************************
991 Window display dimensions
992 ***********************************************************************/
993
994 /* Return the bottom boundary y-position for text lines in window W.
995 This is the first y position at which a line cannot start.
996 It is relative to the top of the window.
997
998 This is the height of W minus the height of a mode line, if any. */
999
1000 INLINE int
1001 window_text_bottom_y (w)
1002 struct window *w;
1003 {
1004 int height = WINDOW_TOTAL_HEIGHT (w);
1005
1006 if (WINDOW_WANTS_MODELINE_P (w))
1007 height -= CURRENT_MODE_LINE_HEIGHT (w);
1008 return height;
1009 }
1010
1011 /* Return the pixel width of display area AREA of window W. AREA < 0
1012 means return the total width of W, not including fringes to
1013 the left and right of the window. */
1014
1015 INLINE int
1016 window_box_width (w, area)
1017 struct window *w;
1018 int area;
1019 {
1020 int cols = XFASTINT (w->total_cols);
1021 int pixels = 0;
1022
1023 if (!w->pseudo_window_p)
1024 {
1025 cols -= WINDOW_SCROLL_BAR_COLS (w);
1026
1027 if (area == TEXT_AREA)
1028 {
1029 if (INTEGERP (w->left_margin_cols))
1030 cols -= XFASTINT (w->left_margin_cols);
1031 if (INTEGERP (w->right_margin_cols))
1032 cols -= XFASTINT (w->right_margin_cols);
1033 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1034 }
1035 else if (area == LEFT_MARGIN_AREA)
1036 {
1037 cols = (INTEGERP (w->left_margin_cols)
1038 ? XFASTINT (w->left_margin_cols) : 0);
1039 pixels = 0;
1040 }
1041 else if (area == RIGHT_MARGIN_AREA)
1042 {
1043 cols = (INTEGERP (w->right_margin_cols)
1044 ? XFASTINT (w->right_margin_cols) : 0);
1045 pixels = 0;
1046 }
1047 }
1048
1049 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1050 }
1051
1052
1053 /* Return the pixel height of the display area of window W, not
1054 including mode lines of W, if any. */
1055
1056 INLINE int
1057 window_box_height (w)
1058 struct window *w;
1059 {
1060 struct frame *f = XFRAME (w->frame);
1061 int height = WINDOW_TOTAL_HEIGHT (w);
1062
1063 xassert (height >= 0);
1064
1065 /* Note: the code below that determines the mode-line/header-line
1066 height is essentially the same as that contained in the macro
1067 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1068 the appropriate glyph row has its `mode_line_p' flag set,
1069 and if it doesn't, uses estimate_mode_line_height instead. */
1070
1071 if (WINDOW_WANTS_MODELINE_P (w))
1072 {
1073 struct glyph_row *ml_row
1074 = (w->current_matrix && w->current_matrix->rows
1075 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1076 : 0);
1077 if (ml_row && ml_row->mode_line_p)
1078 height -= ml_row->height;
1079 else
1080 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1081 }
1082
1083 if (WINDOW_WANTS_HEADER_LINE_P (w))
1084 {
1085 struct glyph_row *hl_row
1086 = (w->current_matrix && w->current_matrix->rows
1087 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1088 : 0);
1089 if (hl_row && hl_row->mode_line_p)
1090 height -= hl_row->height;
1091 else
1092 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1093 }
1094
1095 /* With a very small font and a mode-line that's taller than
1096 default, we might end up with a negative height. */
1097 return max (0, height);
1098 }
1099
1100 /* Return the window-relative coordinate of the left edge of display
1101 area AREA of window W. AREA < 0 means return the left edge of the
1102 whole window, to the right of the left fringe of W. */
1103
1104 INLINE int
1105 window_box_left_offset (w, area)
1106 struct window *w;
1107 int area;
1108 {
1109 int x;
1110
1111 if (w->pseudo_window_p)
1112 return 0;
1113
1114 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1115
1116 if (area == TEXT_AREA)
1117 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1118 + window_box_width (w, LEFT_MARGIN_AREA));
1119 else if (area == RIGHT_MARGIN_AREA)
1120 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1121 + window_box_width (w, LEFT_MARGIN_AREA)
1122 + window_box_width (w, TEXT_AREA)
1123 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1124 ? 0
1125 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1126 else if (area == LEFT_MARGIN_AREA
1127 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1128 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1129
1130 return x;
1131 }
1132
1133
1134 /* Return the window-relative coordinate of the right edge of display
1135 area AREA of window W. AREA < 0 means return the left edge of the
1136 whole window, to the left of the right fringe of W. */
1137
1138 INLINE int
1139 window_box_right_offset (w, area)
1140 struct window *w;
1141 int area;
1142 {
1143 return window_box_left_offset (w, area) + window_box_width (w, area);
1144 }
1145
1146 /* Return the frame-relative coordinate of the left edge of display
1147 area AREA of window W. AREA < 0 means return the left edge of the
1148 whole window, to the right of the left fringe of W. */
1149
1150 INLINE int
1151 window_box_left (w, area)
1152 struct window *w;
1153 int area;
1154 {
1155 struct frame *f = XFRAME (w->frame);
1156 int x;
1157
1158 if (w->pseudo_window_p)
1159 return FRAME_INTERNAL_BORDER_WIDTH (f);
1160
1161 x = (WINDOW_LEFT_EDGE_X (w)
1162 + window_box_left_offset (w, area));
1163
1164 return x;
1165 }
1166
1167
1168 /* Return the frame-relative coordinate of the right edge of display
1169 area AREA of window W. AREA < 0 means return the left edge of the
1170 whole window, to the left of the right fringe of W. */
1171
1172 INLINE int
1173 window_box_right (w, area)
1174 struct window *w;
1175 int area;
1176 {
1177 return window_box_left (w, area) + window_box_width (w, area);
1178 }
1179
1180 /* Get the bounding box of the display area AREA of window W, without
1181 mode lines, in frame-relative coordinates. AREA < 0 means the
1182 whole window, not including the left and right fringes of
1183 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1184 coordinates of the upper-left corner of the box. Return in
1185 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1186
1187 INLINE void
1188 window_box (w, area, box_x, box_y, box_width, box_height)
1189 struct window *w;
1190 int area;
1191 int *box_x, *box_y, *box_width, *box_height;
1192 {
1193 if (box_width)
1194 *box_width = window_box_width (w, area);
1195 if (box_height)
1196 *box_height = window_box_height (w);
1197 if (box_x)
1198 *box_x = window_box_left (w, area);
1199 if (box_y)
1200 {
1201 *box_y = WINDOW_TOP_EDGE_Y (w);
1202 if (WINDOW_WANTS_HEADER_LINE_P (w))
1203 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1204 }
1205 }
1206
1207
1208 /* Get the bounding box of the display area AREA of window W, without
1209 mode lines. AREA < 0 means the whole window, not including the
1210 left and right fringe of the window. Return in *TOP_LEFT_X
1211 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1212 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1213 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1214 box. */
1215
1216 INLINE void
1217 window_box_edges (w, area, top_left_x, top_left_y,
1218 bottom_right_x, bottom_right_y)
1219 struct window *w;
1220 int area;
1221 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1222 {
1223 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1224 bottom_right_y);
1225 *bottom_right_x += *top_left_x;
1226 *bottom_right_y += *top_left_y;
1227 }
1228
1229
1230 \f
1231 /***********************************************************************
1232 Utilities
1233 ***********************************************************************/
1234
1235 /* Return the bottom y-position of the line the iterator IT is in.
1236 This can modify IT's settings. */
1237
1238 int
1239 line_bottom_y (it)
1240 struct it *it;
1241 {
1242 int line_height = it->max_ascent + it->max_descent;
1243 int line_top_y = it->current_y;
1244
1245 if (line_height == 0)
1246 {
1247 if (last_height)
1248 line_height = last_height;
1249 else if (IT_CHARPOS (*it) < ZV)
1250 {
1251 move_it_by_lines (it, 1, 1);
1252 line_height = (it->max_ascent || it->max_descent
1253 ? it->max_ascent + it->max_descent
1254 : last_height);
1255 }
1256 else
1257 {
1258 struct glyph_row *row = it->glyph_row;
1259
1260 /* Use the default character height. */
1261 it->glyph_row = NULL;
1262 it->what = IT_CHARACTER;
1263 it->c = ' ';
1264 it->len = 1;
1265 PRODUCE_GLYPHS (it);
1266 line_height = it->ascent + it->descent;
1267 it->glyph_row = row;
1268 }
1269 }
1270
1271 return line_top_y + line_height;
1272 }
1273
1274
1275 /* Return 1 if position CHARPOS is visible in window W.
1276 CHARPOS < 0 means return info about WINDOW_END position.
1277 If visible, set *X and *Y to pixel coordinates of top left corner.
1278 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1279 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1280
1281 int
1282 pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
1283 struct window *w;
1284 int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
1285 {
1286 struct it it;
1287 struct text_pos top;
1288 int visible_p = 0;
1289 struct buffer *old_buffer = NULL;
1290
1291 if (noninteractive)
1292 return visible_p;
1293
1294 if (XBUFFER (w->buffer) != current_buffer)
1295 {
1296 old_buffer = current_buffer;
1297 set_buffer_internal_1 (XBUFFER (w->buffer));
1298 }
1299
1300 SET_TEXT_POS_FROM_MARKER (top, w->start);
1301
1302 /* Compute exact mode line heights. */
1303 if (WINDOW_WANTS_MODELINE_P (w))
1304 current_mode_line_height
1305 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1306 current_buffer->mode_line_format);
1307
1308 if (WINDOW_WANTS_HEADER_LINE_P (w))
1309 current_header_line_height
1310 = display_mode_line (w, HEADER_LINE_FACE_ID,
1311 current_buffer->header_line_format);
1312
1313 start_display (&it, w, top);
1314 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1315 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1316
1317 /* Note that we may overshoot because of invisible text. */
1318 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1319 {
1320 int top_x = it.current_x;
1321 int top_y = it.current_y;
1322 int bottom_y = (last_height = 0, line_bottom_y (&it));
1323 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1324
1325 if (top_y < window_top_y)
1326 visible_p = bottom_y > window_top_y;
1327 else if (top_y < it.last_visible_y)
1328 visible_p = 1;
1329 if (visible_p)
1330 {
1331 *x = top_x;
1332 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1333 *rtop = max (0, window_top_y - top_y);
1334 *rbot = max (0, bottom_y - it.last_visible_y);
1335 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1336 - max (top_y, window_top_y)));
1337 *vpos = it.vpos;
1338 }
1339 }
1340 else
1341 {
1342 struct it it2;
1343
1344 it2 = it;
1345 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1346 move_it_by_lines (&it, 1, 0);
1347 if (charpos < IT_CHARPOS (it)
1348 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1349 {
1350 visible_p = 1;
1351 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1352 *x = it2.current_x;
1353 *y = it2.current_y + it2.max_ascent - it2.ascent;
1354 *rtop = max (0, -it2.current_y);
1355 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1356 - it.last_visible_y));
1357 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1358 it.last_visible_y)
1359 - max (it2.current_y,
1360 WINDOW_HEADER_LINE_HEIGHT (w))));
1361 *vpos = it2.vpos;
1362 }
1363 }
1364
1365 if (old_buffer)
1366 set_buffer_internal_1 (old_buffer);
1367
1368 current_header_line_height = current_mode_line_height = -1;
1369
1370 if (visible_p && XFASTINT (w->hscroll) > 0)
1371 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1372
1373 #if 0
1374 /* Debugging code. */
1375 if (visible_p)
1376 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1377 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1378 else
1379 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1380 #endif
1381
1382 return visible_p;
1383 }
1384
1385
1386 /* Return the next character from STR which is MAXLEN bytes long.
1387 Return in *LEN the length of the character. This is like
1388 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1389 we find one, we return a `?', but with the length of the invalid
1390 character. */
1391
1392 static INLINE int
1393 string_char_and_length (str, maxlen, len)
1394 const unsigned char *str;
1395 int maxlen, *len;
1396 {
1397 int c;
1398
1399 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1400 if (!CHAR_VALID_P (c, 1))
1401 /* We may not change the length here because other places in Emacs
1402 don't use this function, i.e. they silently accept invalid
1403 characters. */
1404 c = '?';
1405
1406 return c;
1407 }
1408
1409
1410
1411 /* Given a position POS containing a valid character and byte position
1412 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1413
1414 static struct text_pos
1415 string_pos_nchars_ahead (pos, string, nchars)
1416 struct text_pos pos;
1417 Lisp_Object string;
1418 int nchars;
1419 {
1420 xassert (STRINGP (string) && nchars >= 0);
1421
1422 if (STRING_MULTIBYTE (string))
1423 {
1424 int rest = SBYTES (string) - BYTEPOS (pos);
1425 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1426 int len;
1427
1428 while (nchars--)
1429 {
1430 string_char_and_length (p, rest, &len);
1431 p += len, rest -= len;
1432 xassert (rest >= 0);
1433 CHARPOS (pos) += 1;
1434 BYTEPOS (pos) += len;
1435 }
1436 }
1437 else
1438 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1439
1440 return pos;
1441 }
1442
1443
1444 /* Value is the text position, i.e. character and byte position,
1445 for character position CHARPOS in STRING. */
1446
1447 static INLINE struct text_pos
1448 string_pos (charpos, string)
1449 int charpos;
1450 Lisp_Object string;
1451 {
1452 struct text_pos pos;
1453 xassert (STRINGP (string));
1454 xassert (charpos >= 0);
1455 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1456 return pos;
1457 }
1458
1459
1460 /* Value is a text position, i.e. character and byte position, for
1461 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1462 means recognize multibyte characters. */
1463
1464 static struct text_pos
1465 c_string_pos (charpos, s, multibyte_p)
1466 int charpos;
1467 unsigned char *s;
1468 int multibyte_p;
1469 {
1470 struct text_pos pos;
1471
1472 xassert (s != NULL);
1473 xassert (charpos >= 0);
1474
1475 if (multibyte_p)
1476 {
1477 int rest = strlen (s), len;
1478
1479 SET_TEXT_POS (pos, 0, 0);
1480 while (charpos--)
1481 {
1482 string_char_and_length (s, rest, &len);
1483 s += len, rest -= len;
1484 xassert (rest >= 0);
1485 CHARPOS (pos) += 1;
1486 BYTEPOS (pos) += len;
1487 }
1488 }
1489 else
1490 SET_TEXT_POS (pos, charpos, charpos);
1491
1492 return pos;
1493 }
1494
1495
1496 /* Value is the number of characters in C string S. MULTIBYTE_P
1497 non-zero means recognize multibyte characters. */
1498
1499 static int
1500 number_of_chars (s, multibyte_p)
1501 unsigned char *s;
1502 int multibyte_p;
1503 {
1504 int nchars;
1505
1506 if (multibyte_p)
1507 {
1508 int rest = strlen (s), len;
1509 unsigned char *p = (unsigned char *) s;
1510
1511 for (nchars = 0; rest > 0; ++nchars)
1512 {
1513 string_char_and_length (p, rest, &len);
1514 rest -= len, p += len;
1515 }
1516 }
1517 else
1518 nchars = strlen (s);
1519
1520 return nchars;
1521 }
1522
1523
1524 /* Compute byte position NEWPOS->bytepos corresponding to
1525 NEWPOS->charpos. POS is a known position in string STRING.
1526 NEWPOS->charpos must be >= POS.charpos. */
1527
1528 static void
1529 compute_string_pos (newpos, pos, string)
1530 struct text_pos *newpos, pos;
1531 Lisp_Object string;
1532 {
1533 xassert (STRINGP (string));
1534 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1535
1536 if (STRING_MULTIBYTE (string))
1537 *newpos = string_pos_nchars_ahead (pos, string,
1538 CHARPOS (*newpos) - CHARPOS (pos));
1539 else
1540 BYTEPOS (*newpos) = CHARPOS (*newpos);
1541 }
1542
1543 /* EXPORT:
1544 Return an estimation of the pixel height of mode or top lines on
1545 frame F. FACE_ID specifies what line's height to estimate. */
1546
1547 int
1548 estimate_mode_line_height (f, face_id)
1549 struct frame *f;
1550 enum face_id face_id;
1551 {
1552 #ifdef HAVE_WINDOW_SYSTEM
1553 if (FRAME_WINDOW_P (f))
1554 {
1555 int height = FONT_HEIGHT (FRAME_FONT (f));
1556
1557 /* This function is called so early when Emacs starts that the face
1558 cache and mode line face are not yet initialized. */
1559 if (FRAME_FACE_CACHE (f))
1560 {
1561 struct face *face = FACE_FROM_ID (f, face_id);
1562 if (face)
1563 {
1564 if (face->font)
1565 height = FONT_HEIGHT (face->font);
1566 if (face->box_line_width > 0)
1567 height += 2 * face->box_line_width;
1568 }
1569 }
1570
1571 return height;
1572 }
1573 #endif
1574
1575 return 1;
1576 }
1577
1578 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1579 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1580 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1581 not force the value into range. */
1582
1583 void
1584 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1585 FRAME_PTR f;
1586 register int pix_x, pix_y;
1587 int *x, *y;
1588 NativeRectangle *bounds;
1589 int noclip;
1590 {
1591
1592 #ifdef HAVE_WINDOW_SYSTEM
1593 if (FRAME_WINDOW_P (f))
1594 {
1595 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1596 even for negative values. */
1597 if (pix_x < 0)
1598 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1599 if (pix_y < 0)
1600 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1601
1602 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1603 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1604
1605 if (bounds)
1606 STORE_NATIVE_RECT (*bounds,
1607 FRAME_COL_TO_PIXEL_X (f, pix_x),
1608 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1609 FRAME_COLUMN_WIDTH (f) - 1,
1610 FRAME_LINE_HEIGHT (f) - 1);
1611
1612 if (!noclip)
1613 {
1614 if (pix_x < 0)
1615 pix_x = 0;
1616 else if (pix_x > FRAME_TOTAL_COLS (f))
1617 pix_x = FRAME_TOTAL_COLS (f);
1618
1619 if (pix_y < 0)
1620 pix_y = 0;
1621 else if (pix_y > FRAME_LINES (f))
1622 pix_y = FRAME_LINES (f);
1623 }
1624 }
1625 #endif
1626
1627 *x = pix_x;
1628 *y = pix_y;
1629 }
1630
1631
1632 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1633 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1634 can't tell the positions because W's display is not up to date,
1635 return 0. */
1636
1637 int
1638 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1639 struct window *w;
1640 int hpos, vpos;
1641 int *frame_x, *frame_y;
1642 {
1643 #ifdef HAVE_WINDOW_SYSTEM
1644 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1645 {
1646 int success_p;
1647
1648 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1649 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1650
1651 if (display_completed)
1652 {
1653 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1654 struct glyph *glyph = row->glyphs[TEXT_AREA];
1655 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1656
1657 hpos = row->x;
1658 vpos = row->y;
1659 while (glyph < end)
1660 {
1661 hpos += glyph->pixel_width;
1662 ++glyph;
1663 }
1664
1665 /* If first glyph is partially visible, its first visible position is still 0. */
1666 if (hpos < 0)
1667 hpos = 0;
1668
1669 success_p = 1;
1670 }
1671 else
1672 {
1673 hpos = vpos = 0;
1674 success_p = 0;
1675 }
1676
1677 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1678 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1679 return success_p;
1680 }
1681 #endif
1682
1683 *frame_x = hpos;
1684 *frame_y = vpos;
1685 return 1;
1686 }
1687
1688
1689 #ifdef HAVE_WINDOW_SYSTEM
1690
1691 /* Find the glyph under window-relative coordinates X/Y in window W.
1692 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1693 strings. Return in *HPOS and *VPOS the row and column number of
1694 the glyph found. Return in *AREA the glyph area containing X.
1695 Value is a pointer to the glyph found or null if X/Y is not on
1696 text, or we can't tell because W's current matrix is not up to
1697 date. */
1698
1699 static struct glyph *
1700 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1701 struct window *w;
1702 int x, y;
1703 int *hpos, *vpos, *dx, *dy, *area;
1704 {
1705 struct glyph *glyph, *end;
1706 struct glyph_row *row = NULL;
1707 int x0, i;
1708
1709 /* Find row containing Y. Give up if some row is not enabled. */
1710 for (i = 0; i < w->current_matrix->nrows; ++i)
1711 {
1712 row = MATRIX_ROW (w->current_matrix, i);
1713 if (!row->enabled_p)
1714 return NULL;
1715 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1716 break;
1717 }
1718
1719 *vpos = i;
1720 *hpos = 0;
1721
1722 /* Give up if Y is not in the window. */
1723 if (i == w->current_matrix->nrows)
1724 return NULL;
1725
1726 /* Get the glyph area containing X. */
1727 if (w->pseudo_window_p)
1728 {
1729 *area = TEXT_AREA;
1730 x0 = 0;
1731 }
1732 else
1733 {
1734 if (x < window_box_left_offset (w, TEXT_AREA))
1735 {
1736 *area = LEFT_MARGIN_AREA;
1737 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1738 }
1739 else if (x < window_box_right_offset (w, TEXT_AREA))
1740 {
1741 *area = TEXT_AREA;
1742 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1743 }
1744 else
1745 {
1746 *area = RIGHT_MARGIN_AREA;
1747 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1748 }
1749 }
1750
1751 /* Find glyph containing X. */
1752 glyph = row->glyphs[*area];
1753 end = glyph + row->used[*area];
1754 x -= x0;
1755 while (glyph < end && x >= glyph->pixel_width)
1756 {
1757 x -= glyph->pixel_width;
1758 ++glyph;
1759 }
1760
1761 if (glyph == end)
1762 return NULL;
1763
1764 if (dx)
1765 {
1766 *dx = x;
1767 *dy = y - (row->y + row->ascent - glyph->ascent);
1768 }
1769
1770 *hpos = glyph - row->glyphs[*area];
1771 return glyph;
1772 }
1773
1774
1775 /* EXPORT:
1776 Convert frame-relative x/y to coordinates relative to window W.
1777 Takes pseudo-windows into account. */
1778
1779 void
1780 frame_to_window_pixel_xy (w, x, y)
1781 struct window *w;
1782 int *x, *y;
1783 {
1784 if (w->pseudo_window_p)
1785 {
1786 /* A pseudo-window is always full-width, and starts at the
1787 left edge of the frame, plus a frame border. */
1788 struct frame *f = XFRAME (w->frame);
1789 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1790 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1791 }
1792 else
1793 {
1794 *x -= WINDOW_LEFT_EDGE_X (w);
1795 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1796 }
1797 }
1798
1799 /* EXPORT:
1800 Return in RECTS[] at most N clipping rectangles for glyph string S.
1801 Return the number of stored rectangles. */
1802
1803 int
1804 get_glyph_string_clip_rects (s, rects, n)
1805 struct glyph_string *s;
1806 NativeRectangle *rects;
1807 int n;
1808 {
1809 XRectangle r;
1810
1811 if (n <= 0)
1812 return 0;
1813
1814 if (s->row->full_width_p)
1815 {
1816 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1817 r.x = WINDOW_LEFT_EDGE_X (s->w);
1818 r.width = WINDOW_TOTAL_WIDTH (s->w);
1819
1820 /* Unless displaying a mode or menu bar line, which are always
1821 fully visible, clip to the visible part of the row. */
1822 if (s->w->pseudo_window_p)
1823 r.height = s->row->visible_height;
1824 else
1825 r.height = s->height;
1826 }
1827 else
1828 {
1829 /* This is a text line that may be partially visible. */
1830 r.x = window_box_left (s->w, s->area);
1831 r.width = window_box_width (s->w, s->area);
1832 r.height = s->row->visible_height;
1833 }
1834
1835 if (s->clip_head)
1836 if (r.x < s->clip_head->x)
1837 {
1838 if (r.width >= s->clip_head->x - r.x)
1839 r.width -= s->clip_head->x - r.x;
1840 else
1841 r.width = 0;
1842 r.x = s->clip_head->x;
1843 }
1844 if (s->clip_tail)
1845 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1846 {
1847 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1848 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1849 else
1850 r.width = 0;
1851 }
1852
1853 /* If S draws overlapping rows, it's sufficient to use the top and
1854 bottom of the window for clipping because this glyph string
1855 intentionally draws over other lines. */
1856 if (s->for_overlaps)
1857 {
1858 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1859 r.height = window_text_bottom_y (s->w) - r.y;
1860
1861 /* Alas, the above simple strategy does not work for the
1862 environments with anti-aliased text: if the same text is
1863 drawn onto the same place multiple times, it gets thicker.
1864 If the overlap we are processing is for the erased cursor, we
1865 take the intersection with the rectagle of the cursor. */
1866 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1867 {
1868 XRectangle rc, r_save = r;
1869
1870 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1871 rc.y = s->w->phys_cursor.y;
1872 rc.width = s->w->phys_cursor_width;
1873 rc.height = s->w->phys_cursor_height;
1874
1875 x_intersect_rectangles (&r_save, &rc, &r);
1876 }
1877 }
1878 else
1879 {
1880 /* Don't use S->y for clipping because it doesn't take partially
1881 visible lines into account. For example, it can be negative for
1882 partially visible lines at the top of a window. */
1883 if (!s->row->full_width_p
1884 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1885 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1886 else
1887 r.y = max (0, s->row->y);
1888
1889 /* If drawing a tool-bar window, draw it over the internal border
1890 at the top of the window. */
1891 if (WINDOWP (s->f->tool_bar_window)
1892 && s->w == XWINDOW (s->f->tool_bar_window))
1893 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1894 }
1895
1896 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1897
1898 /* If drawing the cursor, don't let glyph draw outside its
1899 advertised boundaries. Cleartype does this under some circumstances. */
1900 if (s->hl == DRAW_CURSOR)
1901 {
1902 struct glyph *glyph = s->first_glyph;
1903 int height, max_y;
1904
1905 if (s->x > r.x)
1906 {
1907 r.width -= s->x - r.x;
1908 r.x = s->x;
1909 }
1910 r.width = min (r.width, glyph->pixel_width);
1911
1912 /* If r.y is below window bottom, ensure that we still see a cursor. */
1913 height = min (glyph->ascent + glyph->descent,
1914 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1915 max_y = window_text_bottom_y (s->w) - height;
1916 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1917 if (s->ybase - glyph->ascent > max_y)
1918 {
1919 r.y = max_y;
1920 r.height = height;
1921 }
1922 else
1923 {
1924 /* Don't draw cursor glyph taller than our actual glyph. */
1925 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1926 if (height < r.height)
1927 {
1928 max_y = r.y + r.height;
1929 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1930 r.height = min (max_y - r.y, height);
1931 }
1932 }
1933 }
1934
1935 if (s->row->clip)
1936 {
1937 XRectangle r_save = r;
1938
1939 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
1940 r.width = 0;
1941 }
1942
1943 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1944 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1945 {
1946 #ifdef CONVERT_FROM_XRECT
1947 CONVERT_FROM_XRECT (r, *rects);
1948 #else
1949 *rects = r;
1950 #endif
1951 return 1;
1952 }
1953 else
1954 {
1955 /* If we are processing overlapping and allowed to return
1956 multiple clipping rectangles, we exclude the row of the glyph
1957 string from the clipping rectangle. This is to avoid drawing
1958 the same text on the environment with anti-aliasing. */
1959 #ifdef CONVERT_FROM_XRECT
1960 XRectangle rs[2];
1961 #else
1962 XRectangle *rs = rects;
1963 #endif
1964 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1965
1966 if (s->for_overlaps & OVERLAPS_PRED)
1967 {
1968 rs[i] = r;
1969 if (r.y + r.height > row_y)
1970 {
1971 if (r.y < row_y)
1972 rs[i].height = row_y - r.y;
1973 else
1974 rs[i].height = 0;
1975 }
1976 i++;
1977 }
1978 if (s->for_overlaps & OVERLAPS_SUCC)
1979 {
1980 rs[i] = r;
1981 if (r.y < row_y + s->row->visible_height)
1982 {
1983 if (r.y + r.height > row_y + s->row->visible_height)
1984 {
1985 rs[i].y = row_y + s->row->visible_height;
1986 rs[i].height = r.y + r.height - rs[i].y;
1987 }
1988 else
1989 rs[i].height = 0;
1990 }
1991 i++;
1992 }
1993
1994 n = i;
1995 #ifdef CONVERT_FROM_XRECT
1996 for (i = 0; i < n; i++)
1997 CONVERT_FROM_XRECT (rs[i], rects[i]);
1998 #endif
1999 return n;
2000 }
2001 }
2002
2003 /* EXPORT:
2004 Return in *NR the clipping rectangle for glyph string S. */
2005
2006 void
2007 get_glyph_string_clip_rect (s, nr)
2008 struct glyph_string *s;
2009 NativeRectangle *nr;
2010 {
2011 get_glyph_string_clip_rects (s, nr, 1);
2012 }
2013
2014
2015 /* EXPORT:
2016 Return the position and height of the phys cursor in window W.
2017 Set w->phys_cursor_width to width of phys cursor.
2018 */
2019
2020 void
2021 get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
2022 struct window *w;
2023 struct glyph_row *row;
2024 struct glyph *glyph;
2025 int *xp, *yp, *heightp;
2026 {
2027 struct frame *f = XFRAME (WINDOW_FRAME (w));
2028 int x, y, wd, h, h0, y0;
2029
2030 /* Compute the width of the rectangle to draw. If on a stretch
2031 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2032 rectangle as wide as the glyph, but use a canonical character
2033 width instead. */
2034 wd = glyph->pixel_width - 1;
2035 #ifdef HAVE_NTGUI
2036 wd++; /* Why? */
2037 #endif
2038
2039 x = w->phys_cursor.x;
2040 if (x < 0)
2041 {
2042 wd += x;
2043 x = 0;
2044 }
2045
2046 if (glyph->type == STRETCH_GLYPH
2047 && !x_stretch_cursor_p)
2048 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2049 w->phys_cursor_width = wd;
2050
2051 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2052
2053 /* If y is below window bottom, ensure that we still see a cursor. */
2054 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2055
2056 h = max (h0, glyph->ascent + glyph->descent);
2057 h0 = min (h0, glyph->ascent + glyph->descent);
2058
2059 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2060 if (y < y0)
2061 {
2062 h = max (h - (y0 - y) + 1, h0);
2063 y = y0 - 1;
2064 }
2065 else
2066 {
2067 y0 = window_text_bottom_y (w) - h0;
2068 if (y > y0)
2069 {
2070 h += y - y0;
2071 y = y0;
2072 }
2073 }
2074
2075 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2076 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2077 *heightp = h;
2078 }
2079
2080 /*
2081 * Remember which glyph the mouse is over.
2082 */
2083
2084 void
2085 remember_mouse_glyph (f, gx, gy, rect)
2086 struct frame *f;
2087 int gx, gy;
2088 NativeRectangle *rect;
2089 {
2090 Lisp_Object window;
2091 struct window *w;
2092 struct glyph_row *r, *gr, *end_row;
2093 enum window_part part;
2094 enum glyph_row_area area;
2095 int x, y, width, height;
2096
2097 /* Try to determine frame pixel position and size of the glyph under
2098 frame pixel coordinates X/Y on frame F. */
2099
2100 if (!f->glyphs_initialized_p
2101 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2102 NILP (window)))
2103 {
2104 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2105 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2106 goto virtual_glyph;
2107 }
2108
2109 w = XWINDOW (window);
2110 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2111 height = WINDOW_FRAME_LINE_HEIGHT (w);
2112
2113 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2114 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2115
2116 if (w->pseudo_window_p)
2117 {
2118 area = TEXT_AREA;
2119 part = ON_MODE_LINE; /* Don't adjust margin. */
2120 goto text_glyph;
2121 }
2122
2123 switch (part)
2124 {
2125 case ON_LEFT_MARGIN:
2126 area = LEFT_MARGIN_AREA;
2127 goto text_glyph;
2128
2129 case ON_RIGHT_MARGIN:
2130 area = RIGHT_MARGIN_AREA;
2131 goto text_glyph;
2132
2133 case ON_HEADER_LINE:
2134 case ON_MODE_LINE:
2135 gr = (part == ON_HEADER_LINE
2136 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2137 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2138 gy = gr->y;
2139 area = TEXT_AREA;
2140 goto text_glyph_row_found;
2141
2142 case ON_TEXT:
2143 area = TEXT_AREA;
2144
2145 text_glyph:
2146 gr = 0; gy = 0;
2147 for (; r <= end_row && r->enabled_p; ++r)
2148 if (r->y + r->height > y)
2149 {
2150 gr = r; gy = r->y;
2151 break;
2152 }
2153
2154 text_glyph_row_found:
2155 if (gr && gy <= y)
2156 {
2157 struct glyph *g = gr->glyphs[area];
2158 struct glyph *end = g + gr->used[area];
2159
2160 height = gr->height;
2161 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2162 if (gx + g->pixel_width > x)
2163 break;
2164
2165 if (g < end)
2166 {
2167 if (g->type == IMAGE_GLYPH)
2168 {
2169 /* Don't remember when mouse is over image, as
2170 image may have hot-spots. */
2171 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2172 return;
2173 }
2174 width = g->pixel_width;
2175 }
2176 else
2177 {
2178 /* Use nominal char spacing at end of line. */
2179 x -= gx;
2180 gx += (x / width) * width;
2181 }
2182
2183 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2184 gx += window_box_left_offset (w, area);
2185 }
2186 else
2187 {
2188 /* Use nominal line height at end of window. */
2189 gx = (x / width) * width;
2190 y -= gy;
2191 gy += (y / height) * height;
2192 }
2193 break;
2194
2195 case ON_LEFT_FRINGE:
2196 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2197 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2198 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2199 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2200 goto row_glyph;
2201
2202 case ON_RIGHT_FRINGE:
2203 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2204 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2205 : window_box_right_offset (w, TEXT_AREA));
2206 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2207 goto row_glyph;
2208
2209 case ON_SCROLL_BAR:
2210 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2211 ? 0
2212 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2213 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2214 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2215 : 0)));
2216 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2217
2218 row_glyph:
2219 gr = 0, gy = 0;
2220 for (; r <= end_row && r->enabled_p; ++r)
2221 if (r->y + r->height > y)
2222 {
2223 gr = r; gy = r->y;
2224 break;
2225 }
2226
2227 if (gr && gy <= y)
2228 height = gr->height;
2229 else
2230 {
2231 /* Use nominal line height at end of window. */
2232 y -= gy;
2233 gy += (y / height) * height;
2234 }
2235 break;
2236
2237 default:
2238 ;
2239 virtual_glyph:
2240 /* If there is no glyph under the mouse, then we divide the screen
2241 into a grid of the smallest glyph in the frame, and use that
2242 as our "glyph". */
2243
2244 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2245 round down even for negative values. */
2246 if (gx < 0)
2247 gx -= width - 1;
2248 if (gy < 0)
2249 gy -= height - 1;
2250
2251 gx = (gx / width) * width;
2252 gy = (gy / height) * height;
2253
2254 goto store_rect;
2255 }
2256
2257 gx += WINDOW_LEFT_EDGE_X (w);
2258 gy += WINDOW_TOP_EDGE_Y (w);
2259
2260 store_rect:
2261 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2262
2263 /* Visible feedback for debugging. */
2264 #if 0
2265 #if HAVE_X_WINDOWS
2266 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2267 f->output_data.x->normal_gc,
2268 gx, gy, width, height);
2269 #endif
2270 #endif
2271 }
2272
2273
2274 #endif /* HAVE_WINDOW_SYSTEM */
2275
2276 \f
2277 /***********************************************************************
2278 Lisp form evaluation
2279 ***********************************************************************/
2280
2281 /* Error handler for safe_eval and safe_call. */
2282
2283 static Lisp_Object
2284 safe_eval_handler (arg)
2285 Lisp_Object arg;
2286 {
2287 add_to_log ("Error during redisplay: %s", arg, Qnil);
2288 return Qnil;
2289 }
2290
2291
2292 /* Evaluate SEXPR and return the result, or nil if something went
2293 wrong. Prevent redisplay during the evaluation. */
2294
2295 Lisp_Object
2296 safe_eval (sexpr)
2297 Lisp_Object sexpr;
2298 {
2299 Lisp_Object val;
2300
2301 if (inhibit_eval_during_redisplay)
2302 val = Qnil;
2303 else
2304 {
2305 int count = SPECPDL_INDEX ();
2306 struct gcpro gcpro1;
2307
2308 GCPRO1 (sexpr);
2309 specbind (Qinhibit_redisplay, Qt);
2310 /* Use Qt to ensure debugger does not run,
2311 so there is no possibility of wanting to redisplay. */
2312 val = internal_condition_case_1 (Feval, sexpr, Qt,
2313 safe_eval_handler);
2314 UNGCPRO;
2315 val = unbind_to (count, val);
2316 }
2317
2318 return val;
2319 }
2320
2321
2322 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2323 Return the result, or nil if something went wrong. Prevent
2324 redisplay during the evaluation. */
2325
2326 Lisp_Object
2327 safe_call (nargs, args)
2328 int nargs;
2329 Lisp_Object *args;
2330 {
2331 Lisp_Object val;
2332
2333 if (inhibit_eval_during_redisplay)
2334 val = Qnil;
2335 else
2336 {
2337 int count = SPECPDL_INDEX ();
2338 struct gcpro gcpro1;
2339
2340 GCPRO1 (args[0]);
2341 gcpro1.nvars = nargs;
2342 specbind (Qinhibit_redisplay, Qt);
2343 /* Use Qt to ensure debugger does not run,
2344 so there is no possibility of wanting to redisplay. */
2345 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2346 safe_eval_handler);
2347 UNGCPRO;
2348 val = unbind_to (count, val);
2349 }
2350
2351 return val;
2352 }
2353
2354
2355 /* Call function FN with one argument ARG.
2356 Return the result, or nil if something went wrong. */
2357
2358 Lisp_Object
2359 safe_call1 (fn, arg)
2360 Lisp_Object fn, arg;
2361 {
2362 Lisp_Object args[2];
2363 args[0] = fn;
2364 args[1] = arg;
2365 return safe_call (2, args);
2366 }
2367
2368
2369 \f
2370 /***********************************************************************
2371 Debugging
2372 ***********************************************************************/
2373
2374 #if 0
2375
2376 /* Define CHECK_IT to perform sanity checks on iterators.
2377 This is for debugging. It is too slow to do unconditionally. */
2378
2379 static void
2380 check_it (it)
2381 struct it *it;
2382 {
2383 if (it->method == GET_FROM_STRING)
2384 {
2385 xassert (STRINGP (it->string));
2386 xassert (IT_STRING_CHARPOS (*it) >= 0);
2387 }
2388 else
2389 {
2390 xassert (IT_STRING_CHARPOS (*it) < 0);
2391 if (it->method == GET_FROM_BUFFER)
2392 {
2393 /* Check that character and byte positions agree. */
2394 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2395 }
2396 }
2397
2398 if (it->dpvec)
2399 xassert (it->current.dpvec_index >= 0);
2400 else
2401 xassert (it->current.dpvec_index < 0);
2402 }
2403
2404 #define CHECK_IT(IT) check_it ((IT))
2405
2406 #else /* not 0 */
2407
2408 #define CHECK_IT(IT) (void) 0
2409
2410 #endif /* not 0 */
2411
2412
2413 #if GLYPH_DEBUG
2414
2415 /* Check that the window end of window W is what we expect it
2416 to be---the last row in the current matrix displaying text. */
2417
2418 static void
2419 check_window_end (w)
2420 struct window *w;
2421 {
2422 if (!MINI_WINDOW_P (w)
2423 && !NILP (w->window_end_valid))
2424 {
2425 struct glyph_row *row;
2426 xassert ((row = MATRIX_ROW (w->current_matrix,
2427 XFASTINT (w->window_end_vpos)),
2428 !row->enabled_p
2429 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2430 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2431 }
2432 }
2433
2434 #define CHECK_WINDOW_END(W) check_window_end ((W))
2435
2436 #else /* not GLYPH_DEBUG */
2437
2438 #define CHECK_WINDOW_END(W) (void) 0
2439
2440 #endif /* not GLYPH_DEBUG */
2441
2442
2443 \f
2444 /***********************************************************************
2445 Iterator initialization
2446 ***********************************************************************/
2447
2448 /* Initialize IT for displaying current_buffer in window W, starting
2449 at character position CHARPOS. CHARPOS < 0 means that no buffer
2450 position is specified which is useful when the iterator is assigned
2451 a position later. BYTEPOS is the byte position corresponding to
2452 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2453
2454 If ROW is not null, calls to produce_glyphs with IT as parameter
2455 will produce glyphs in that row.
2456
2457 BASE_FACE_ID is the id of a base face to use. It must be one of
2458 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2459 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2460 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2461
2462 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2463 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2464 will be initialized to use the corresponding mode line glyph row of
2465 the desired matrix of W. */
2466
2467 void
2468 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2469 struct it *it;
2470 struct window *w;
2471 int charpos, bytepos;
2472 struct glyph_row *row;
2473 enum face_id base_face_id;
2474 {
2475 int highlight_region_p;
2476
2477 /* Some precondition checks. */
2478 xassert (w != NULL && it != NULL);
2479 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2480 && charpos <= ZV));
2481
2482 /* If face attributes have been changed since the last redisplay,
2483 free realized faces now because they depend on face definitions
2484 that might have changed. Don't free faces while there might be
2485 desired matrices pending which reference these faces. */
2486 if (face_change_count && !inhibit_free_realized_faces)
2487 {
2488 face_change_count = 0;
2489 free_all_realized_faces (Qnil);
2490 }
2491
2492 /* Use one of the mode line rows of W's desired matrix if
2493 appropriate. */
2494 if (row == NULL)
2495 {
2496 if (base_face_id == MODE_LINE_FACE_ID
2497 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2498 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2499 else if (base_face_id == HEADER_LINE_FACE_ID)
2500 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2501 }
2502
2503 /* Clear IT. */
2504 bzero (it, sizeof *it);
2505 it->current.overlay_string_index = -1;
2506 it->current.dpvec_index = -1;
2507 it->base_face_id = base_face_id;
2508 it->string = Qnil;
2509 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2510
2511 /* The window in which we iterate over current_buffer: */
2512 XSETWINDOW (it->window, w);
2513 it->w = w;
2514 it->f = XFRAME (w->frame);
2515
2516 /* Extra space between lines (on window systems only). */
2517 if (base_face_id == DEFAULT_FACE_ID
2518 && FRAME_WINDOW_P (it->f))
2519 {
2520 if (NATNUMP (current_buffer->extra_line_spacing))
2521 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2522 else if (FLOATP (current_buffer->extra_line_spacing))
2523 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2524 * FRAME_LINE_HEIGHT (it->f));
2525 else if (it->f->extra_line_spacing > 0)
2526 it->extra_line_spacing = it->f->extra_line_spacing;
2527 it->max_extra_line_spacing = 0;
2528 }
2529
2530 /* If realized faces have been removed, e.g. because of face
2531 attribute changes of named faces, recompute them. When running
2532 in batch mode, the face cache of the initial frame is null. If
2533 we happen to get called, make a dummy face cache. */
2534 if (FRAME_FACE_CACHE (it->f) == NULL)
2535 init_frame_faces (it->f);
2536 if (FRAME_FACE_CACHE (it->f)->used == 0)
2537 recompute_basic_faces (it->f);
2538
2539 /* Current value of the `slice', `space-width', and 'height' properties. */
2540 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2541 it->space_width = Qnil;
2542 it->font_height = Qnil;
2543 it->override_ascent = -1;
2544
2545 /* Are control characters displayed as `^C'? */
2546 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2547
2548 /* -1 means everything between a CR and the following line end
2549 is invisible. >0 means lines indented more than this value are
2550 invisible. */
2551 it->selective = (INTEGERP (current_buffer->selective_display)
2552 ? XFASTINT (current_buffer->selective_display)
2553 : (!NILP (current_buffer->selective_display)
2554 ? -1 : 0));
2555 it->selective_display_ellipsis_p
2556 = !NILP (current_buffer->selective_display_ellipses);
2557
2558 /* Display table to use. */
2559 it->dp = window_display_table (w);
2560
2561 /* Are multibyte characters enabled in current_buffer? */
2562 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2563
2564 /* Non-zero if we should highlight the region. */
2565 highlight_region_p
2566 = (!NILP (Vtransient_mark_mode)
2567 && !NILP (current_buffer->mark_active)
2568 && XMARKER (current_buffer->mark)->buffer != 0);
2569
2570 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2571 start and end of a visible region in window IT->w. Set both to
2572 -1 to indicate no region. */
2573 if (highlight_region_p
2574 /* Maybe highlight only in selected window. */
2575 && (/* Either show region everywhere. */
2576 highlight_nonselected_windows
2577 /* Or show region in the selected window. */
2578 || w == XWINDOW (selected_window)
2579 /* Or show the region if we are in the mini-buffer and W is
2580 the window the mini-buffer refers to. */
2581 || (MINI_WINDOW_P (XWINDOW (selected_window))
2582 && WINDOWP (minibuf_selected_window)
2583 && w == XWINDOW (minibuf_selected_window))))
2584 {
2585 int charpos = marker_position (current_buffer->mark);
2586 it->region_beg_charpos = min (PT, charpos);
2587 it->region_end_charpos = max (PT, charpos);
2588 }
2589 else
2590 it->region_beg_charpos = it->region_end_charpos = -1;
2591
2592 /* Get the position at which the redisplay_end_trigger hook should
2593 be run, if it is to be run at all. */
2594 if (MARKERP (w->redisplay_end_trigger)
2595 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2596 it->redisplay_end_trigger_charpos
2597 = marker_position (w->redisplay_end_trigger);
2598 else if (INTEGERP (w->redisplay_end_trigger))
2599 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2600
2601 /* Correct bogus values of tab_width. */
2602 it->tab_width = XINT (current_buffer->tab_width);
2603 if (it->tab_width <= 0 || it->tab_width > 1000)
2604 it->tab_width = 8;
2605
2606 /* Are lines in the display truncated? */
2607 it->truncate_lines_p
2608 = (base_face_id != DEFAULT_FACE_ID
2609 || XINT (it->w->hscroll)
2610 || (truncate_partial_width_windows
2611 && !WINDOW_FULL_WIDTH_P (it->w))
2612 || !NILP (current_buffer->truncate_lines));
2613
2614 /* Get dimensions of truncation and continuation glyphs. These are
2615 displayed as fringe bitmaps under X, so we don't need them for such
2616 frames. */
2617 if (!FRAME_WINDOW_P (it->f))
2618 {
2619 if (it->truncate_lines_p)
2620 {
2621 /* We will need the truncation glyph. */
2622 xassert (it->glyph_row == NULL);
2623 produce_special_glyphs (it, IT_TRUNCATION);
2624 it->truncation_pixel_width = it->pixel_width;
2625 }
2626 else
2627 {
2628 /* We will need the continuation glyph. */
2629 xassert (it->glyph_row == NULL);
2630 produce_special_glyphs (it, IT_CONTINUATION);
2631 it->continuation_pixel_width = it->pixel_width;
2632 }
2633
2634 /* Reset these values to zero because the produce_special_glyphs
2635 above has changed them. */
2636 it->pixel_width = it->ascent = it->descent = 0;
2637 it->phys_ascent = it->phys_descent = 0;
2638 }
2639
2640 /* Set this after getting the dimensions of truncation and
2641 continuation glyphs, so that we don't produce glyphs when calling
2642 produce_special_glyphs, above. */
2643 it->glyph_row = row;
2644 it->area = TEXT_AREA;
2645
2646 /* Get the dimensions of the display area. The display area
2647 consists of the visible window area plus a horizontally scrolled
2648 part to the left of the window. All x-values are relative to the
2649 start of this total display area. */
2650 if (base_face_id != DEFAULT_FACE_ID)
2651 {
2652 /* Mode lines, menu bar in terminal frames. */
2653 it->first_visible_x = 0;
2654 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2655 }
2656 else
2657 {
2658 it->first_visible_x
2659 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2660 it->last_visible_x = (it->first_visible_x
2661 + window_box_width (w, TEXT_AREA));
2662
2663 /* If we truncate lines, leave room for the truncator glyph(s) at
2664 the right margin. Otherwise, leave room for the continuation
2665 glyph(s). Truncation and continuation glyphs are not inserted
2666 for window-based redisplay. */
2667 if (!FRAME_WINDOW_P (it->f))
2668 {
2669 if (it->truncate_lines_p)
2670 it->last_visible_x -= it->truncation_pixel_width;
2671 else
2672 it->last_visible_x -= it->continuation_pixel_width;
2673 }
2674
2675 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2676 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2677 }
2678
2679 /* Leave room for a border glyph. */
2680 if (!FRAME_WINDOW_P (it->f)
2681 && !WINDOW_RIGHTMOST_P (it->w))
2682 it->last_visible_x -= 1;
2683
2684 it->last_visible_y = window_text_bottom_y (w);
2685
2686 /* For mode lines and alike, arrange for the first glyph having a
2687 left box line if the face specifies a box. */
2688 if (base_face_id != DEFAULT_FACE_ID)
2689 {
2690 struct face *face;
2691
2692 it->face_id = base_face_id;
2693
2694 /* If we have a boxed mode line, make the first character appear
2695 with a left box line. */
2696 face = FACE_FROM_ID (it->f, base_face_id);
2697 if (face->box != FACE_NO_BOX)
2698 it->start_of_box_run_p = 1;
2699 }
2700
2701 /* If a buffer position was specified, set the iterator there,
2702 getting overlays and face properties from that position. */
2703 if (charpos >= BUF_BEG (current_buffer))
2704 {
2705 it->end_charpos = ZV;
2706 it->face_id = -1;
2707 IT_CHARPOS (*it) = charpos;
2708
2709 /* Compute byte position if not specified. */
2710 if (bytepos < charpos)
2711 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2712 else
2713 IT_BYTEPOS (*it) = bytepos;
2714
2715 it->start = it->current;
2716
2717 /* Compute faces etc. */
2718 reseat (it, it->current.pos, 1);
2719 }
2720
2721 CHECK_IT (it);
2722 }
2723
2724
2725 /* Initialize IT for the display of window W with window start POS. */
2726
2727 void
2728 start_display (it, w, pos)
2729 struct it *it;
2730 struct window *w;
2731 struct text_pos pos;
2732 {
2733 struct glyph_row *row;
2734 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2735
2736 row = w->desired_matrix->rows + first_vpos;
2737 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2738 it->first_vpos = first_vpos;
2739
2740 /* Don't reseat to previous visible line start if current start
2741 position is in a string or image. */
2742 if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p)
2743 {
2744 int start_at_line_beg_p;
2745 int first_y = it->current_y;
2746
2747 /* If window start is not at a line start, skip forward to POS to
2748 get the correct continuation lines width. */
2749 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2750 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2751 if (!start_at_line_beg_p)
2752 {
2753 int new_x;
2754
2755 reseat_at_previous_visible_line_start (it);
2756 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2757
2758 new_x = it->current_x + it->pixel_width;
2759
2760 /* If lines are continued, this line may end in the middle
2761 of a multi-glyph character (e.g. a control character
2762 displayed as \003, or in the middle of an overlay
2763 string). In this case move_it_to above will not have
2764 taken us to the start of the continuation line but to the
2765 end of the continued line. */
2766 if (it->current_x > 0
2767 && !it->truncate_lines_p /* Lines are continued. */
2768 && (/* And glyph doesn't fit on the line. */
2769 new_x > it->last_visible_x
2770 /* Or it fits exactly and we're on a window
2771 system frame. */
2772 || (new_x == it->last_visible_x
2773 && FRAME_WINDOW_P (it->f))))
2774 {
2775 if (it->current.dpvec_index >= 0
2776 || it->current.overlay_string_index >= 0)
2777 {
2778 set_iterator_to_next (it, 1);
2779 move_it_in_display_line_to (it, -1, -1, 0);
2780 }
2781
2782 it->continuation_lines_width += it->current_x;
2783 }
2784
2785 /* We're starting a new display line, not affected by the
2786 height of the continued line, so clear the appropriate
2787 fields in the iterator structure. */
2788 it->max_ascent = it->max_descent = 0;
2789 it->max_phys_ascent = it->max_phys_descent = 0;
2790
2791 it->current_y = first_y;
2792 it->vpos = 0;
2793 it->current_x = it->hpos = 0;
2794 }
2795 }
2796
2797 #if 0 /* Don't assert the following because start_display is sometimes
2798 called intentionally with a window start that is not at a
2799 line start. Please leave this code in as a comment. */
2800
2801 /* Window start should be on a line start, now. */
2802 xassert (it->continuation_lines_width
2803 || IT_CHARPOS (it) == BEGV
2804 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2805 #endif /* 0 */
2806 }
2807
2808
2809 /* Return 1 if POS is a position in ellipses displayed for invisible
2810 text. W is the window we display, for text property lookup. */
2811
2812 static int
2813 in_ellipses_for_invisible_text_p (pos, w)
2814 struct display_pos *pos;
2815 struct window *w;
2816 {
2817 Lisp_Object prop, window;
2818 int ellipses_p = 0;
2819 int charpos = CHARPOS (pos->pos);
2820
2821 /* If POS specifies a position in a display vector, this might
2822 be for an ellipsis displayed for invisible text. We won't
2823 get the iterator set up for delivering that ellipsis unless
2824 we make sure that it gets aware of the invisible text. */
2825 if (pos->dpvec_index >= 0
2826 && pos->overlay_string_index < 0
2827 && CHARPOS (pos->string_pos) < 0
2828 && charpos > BEGV
2829 && (XSETWINDOW (window, w),
2830 prop = Fget_char_property (make_number (charpos),
2831 Qinvisible, window),
2832 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2833 {
2834 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2835 window);
2836 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2837 }
2838
2839 return ellipses_p;
2840 }
2841
2842
2843 /* Initialize IT for stepping through current_buffer in window W,
2844 starting at position POS that includes overlay string and display
2845 vector/ control character translation position information. Value
2846 is zero if there are overlay strings with newlines at POS. */
2847
2848 static int
2849 init_from_display_pos (it, w, pos)
2850 struct it *it;
2851 struct window *w;
2852 struct display_pos *pos;
2853 {
2854 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2855 int i, overlay_strings_with_newlines = 0;
2856
2857 /* If POS specifies a position in a display vector, this might
2858 be for an ellipsis displayed for invisible text. We won't
2859 get the iterator set up for delivering that ellipsis unless
2860 we make sure that it gets aware of the invisible text. */
2861 if (in_ellipses_for_invisible_text_p (pos, w))
2862 {
2863 --charpos;
2864 bytepos = 0;
2865 }
2866
2867 /* Keep in mind: the call to reseat in init_iterator skips invisible
2868 text, so we might end up at a position different from POS. This
2869 is only a problem when POS is a row start after a newline and an
2870 overlay starts there with an after-string, and the overlay has an
2871 invisible property. Since we don't skip invisible text in
2872 display_line and elsewhere immediately after consuming the
2873 newline before the row start, such a POS will not be in a string,
2874 but the call to init_iterator below will move us to the
2875 after-string. */
2876 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2877
2878 /* This only scans the current chunk -- it should scan all chunks.
2879 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2880 to 16 in 22.1 to make this a lesser problem. */
2881 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2882 {
2883 const char *s = SDATA (it->overlay_strings[i]);
2884 const char *e = s + SBYTES (it->overlay_strings[i]);
2885
2886 while (s < e && *s != '\n')
2887 ++s;
2888
2889 if (s < e)
2890 {
2891 overlay_strings_with_newlines = 1;
2892 break;
2893 }
2894 }
2895
2896 /* If position is within an overlay string, set up IT to the right
2897 overlay string. */
2898 if (pos->overlay_string_index >= 0)
2899 {
2900 int relative_index;
2901
2902 /* If the first overlay string happens to have a `display'
2903 property for an image, the iterator will be set up for that
2904 image, and we have to undo that setup first before we can
2905 correct the overlay string index. */
2906 if (it->method == GET_FROM_IMAGE)
2907 pop_it (it);
2908
2909 /* We already have the first chunk of overlay strings in
2910 IT->overlay_strings. Load more until the one for
2911 pos->overlay_string_index is in IT->overlay_strings. */
2912 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2913 {
2914 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2915 it->current.overlay_string_index = 0;
2916 while (n--)
2917 {
2918 load_overlay_strings (it, 0);
2919 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2920 }
2921 }
2922
2923 it->current.overlay_string_index = pos->overlay_string_index;
2924 relative_index = (it->current.overlay_string_index
2925 % OVERLAY_STRING_CHUNK_SIZE);
2926 it->string = it->overlay_strings[relative_index];
2927 xassert (STRINGP (it->string));
2928 it->current.string_pos = pos->string_pos;
2929 it->method = GET_FROM_STRING;
2930 }
2931
2932 #if 0 /* This is bogus because POS not having an overlay string
2933 position does not mean it's after the string. Example: A
2934 line starting with a before-string and initialization of IT
2935 to the previous row's end position. */
2936 else if (it->current.overlay_string_index >= 0)
2937 {
2938 /* If POS says we're already after an overlay string ending at
2939 POS, make sure to pop the iterator because it will be in
2940 front of that overlay string. When POS is ZV, we've thereby
2941 also ``processed'' overlay strings at ZV. */
2942 while (it->sp)
2943 pop_it (it);
2944 xassert (it->current.overlay_string_index == -1);
2945 xassert (it->method == GET_FROM_BUFFER);
2946 if (CHARPOS (pos->pos) == ZV)
2947 it->overlay_strings_at_end_processed_p = 1;
2948 }
2949 #endif /* 0 */
2950
2951 if (CHARPOS (pos->string_pos) >= 0)
2952 {
2953 /* Recorded position is not in an overlay string, but in another
2954 string. This can only be a string from a `display' property.
2955 IT should already be filled with that string. */
2956 it->current.string_pos = pos->string_pos;
2957 xassert (STRINGP (it->string));
2958 }
2959
2960 /* Restore position in display vector translations, control
2961 character translations or ellipses. */
2962 if (pos->dpvec_index >= 0)
2963 {
2964 if (it->dpvec == NULL)
2965 get_next_display_element (it);
2966 xassert (it->dpvec && it->current.dpvec_index == 0);
2967 it->current.dpvec_index = pos->dpvec_index;
2968 }
2969
2970 CHECK_IT (it);
2971 return !overlay_strings_with_newlines;
2972 }
2973
2974
2975 /* Initialize IT for stepping through current_buffer in window W
2976 starting at ROW->start. */
2977
2978 static void
2979 init_to_row_start (it, w, row)
2980 struct it *it;
2981 struct window *w;
2982 struct glyph_row *row;
2983 {
2984 init_from_display_pos (it, w, &row->start);
2985 it->start = row->start;
2986 it->continuation_lines_width = row->continuation_lines_width;
2987 CHECK_IT (it);
2988 }
2989
2990
2991 /* Initialize IT for stepping through current_buffer in window W
2992 starting in the line following ROW, i.e. starting at ROW->end.
2993 Value is zero if there are overlay strings with newlines at ROW's
2994 end position. */
2995
2996 static int
2997 init_to_row_end (it, w, row)
2998 struct it *it;
2999 struct window *w;
3000 struct glyph_row *row;
3001 {
3002 int success = 0;
3003
3004 if (init_from_display_pos (it, w, &row->end))
3005 {
3006 if (row->continued_p)
3007 it->continuation_lines_width
3008 = row->continuation_lines_width + row->pixel_width;
3009 CHECK_IT (it);
3010 success = 1;
3011 }
3012
3013 return success;
3014 }
3015
3016
3017
3018 \f
3019 /***********************************************************************
3020 Text properties
3021 ***********************************************************************/
3022
3023 /* Called when IT reaches IT->stop_charpos. Handle text property and
3024 overlay changes. Set IT->stop_charpos to the next position where
3025 to stop. */
3026
3027 static void
3028 handle_stop (it)
3029 struct it *it;
3030 {
3031 enum prop_handled handled;
3032 int handle_overlay_change_p;
3033 struct props *p;
3034
3035 it->dpvec = NULL;
3036 it->current.dpvec_index = -1;
3037 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3038 it->ignore_overlay_strings_at_pos_p = 0;
3039
3040 /* Use face of preceding text for ellipsis (if invisible) */
3041 if (it->selective_display_ellipsis_p)
3042 it->saved_face_id = it->face_id;
3043
3044 do
3045 {
3046 handled = HANDLED_NORMALLY;
3047
3048 /* Call text property handlers. */
3049 for (p = it_props; p->handler; ++p)
3050 {
3051 handled = p->handler (it);
3052
3053 if (handled == HANDLED_RECOMPUTE_PROPS)
3054 break;
3055 else if (handled == HANDLED_RETURN)
3056 {
3057 /* We still want to show before and after strings from
3058 overlays even if the actual buffer text is replaced. */
3059 if (!handle_overlay_change_p || it->sp > 1)
3060 return;
3061 if (!get_overlay_strings_1 (it, 0, 0))
3062 return;
3063 it->ignore_overlay_strings_at_pos_p = 1;
3064 it->string_from_display_prop_p = 0;
3065 handle_overlay_change_p = 0;
3066 handled = HANDLED_RECOMPUTE_PROPS;
3067 break;
3068 }
3069 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3070 handle_overlay_change_p = 0;
3071 }
3072
3073 if (handled != HANDLED_RECOMPUTE_PROPS)
3074 {
3075 /* Don't check for overlay strings below when set to deliver
3076 characters from a display vector. */
3077 if (it->method == GET_FROM_DISPLAY_VECTOR)
3078 handle_overlay_change_p = 0;
3079
3080 /* Handle overlay changes. */
3081 if (handle_overlay_change_p)
3082 handled = handle_overlay_change (it);
3083
3084 /* Determine where to stop next. */
3085 if (handled == HANDLED_NORMALLY)
3086 compute_stop_pos (it);
3087 }
3088 }
3089 while (handled == HANDLED_RECOMPUTE_PROPS);
3090 }
3091
3092
3093 /* Compute IT->stop_charpos from text property and overlay change
3094 information for IT's current position. */
3095
3096 static void
3097 compute_stop_pos (it)
3098 struct it *it;
3099 {
3100 register INTERVAL iv, next_iv;
3101 Lisp_Object object, limit, position;
3102
3103 /* If nowhere else, stop at the end. */
3104 it->stop_charpos = it->end_charpos;
3105
3106 if (STRINGP (it->string))
3107 {
3108 /* Strings are usually short, so don't limit the search for
3109 properties. */
3110 object = it->string;
3111 limit = Qnil;
3112 position = make_number (IT_STRING_CHARPOS (*it));
3113 }
3114 else
3115 {
3116 int charpos;
3117
3118 /* If next overlay change is in front of the current stop pos
3119 (which is IT->end_charpos), stop there. Note: value of
3120 next_overlay_change is point-max if no overlay change
3121 follows. */
3122 charpos = next_overlay_change (IT_CHARPOS (*it));
3123 if (charpos < it->stop_charpos)
3124 it->stop_charpos = charpos;
3125
3126 /* If showing the region, we have to stop at the region
3127 start or end because the face might change there. */
3128 if (it->region_beg_charpos > 0)
3129 {
3130 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3131 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3132 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3133 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3134 }
3135
3136 /* Set up variables for computing the stop position from text
3137 property changes. */
3138 XSETBUFFER (object, current_buffer);
3139 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3140 position = make_number (IT_CHARPOS (*it));
3141
3142 }
3143
3144 /* Get the interval containing IT's position. Value is a null
3145 interval if there isn't such an interval. */
3146 iv = validate_interval_range (object, &position, &position, 0);
3147 if (!NULL_INTERVAL_P (iv))
3148 {
3149 Lisp_Object values_here[LAST_PROP_IDX];
3150 struct props *p;
3151
3152 /* Get properties here. */
3153 for (p = it_props; p->handler; ++p)
3154 values_here[p->idx] = textget (iv->plist, *p->name);
3155
3156 /* Look for an interval following iv that has different
3157 properties. */
3158 for (next_iv = next_interval (iv);
3159 (!NULL_INTERVAL_P (next_iv)
3160 && (NILP (limit)
3161 || XFASTINT (limit) > next_iv->position));
3162 next_iv = next_interval (next_iv))
3163 {
3164 for (p = it_props; p->handler; ++p)
3165 {
3166 Lisp_Object new_value;
3167
3168 new_value = textget (next_iv->plist, *p->name);
3169 if (!EQ (values_here[p->idx], new_value))
3170 break;
3171 }
3172
3173 if (p->handler)
3174 break;
3175 }
3176
3177 if (!NULL_INTERVAL_P (next_iv))
3178 {
3179 if (INTEGERP (limit)
3180 && next_iv->position >= XFASTINT (limit))
3181 /* No text property change up to limit. */
3182 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3183 else
3184 /* Text properties change in next_iv. */
3185 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3186 }
3187 }
3188
3189 xassert (STRINGP (it->string)
3190 || (it->stop_charpos >= BEGV
3191 && it->stop_charpos >= IT_CHARPOS (*it)));
3192 }
3193
3194
3195 /* Return the position of the next overlay change after POS in
3196 current_buffer. Value is point-max if no overlay change
3197 follows. This is like `next-overlay-change' but doesn't use
3198 xmalloc. */
3199
3200 static int
3201 next_overlay_change (pos)
3202 int pos;
3203 {
3204 int noverlays;
3205 int endpos;
3206 Lisp_Object *overlays;
3207 int i;
3208
3209 /* Get all overlays at the given position. */
3210 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3211
3212 /* If any of these overlays ends before endpos,
3213 use its ending point instead. */
3214 for (i = 0; i < noverlays; ++i)
3215 {
3216 Lisp_Object oend;
3217 int oendpos;
3218
3219 oend = OVERLAY_END (overlays[i]);
3220 oendpos = OVERLAY_POSITION (oend);
3221 endpos = min (endpos, oendpos);
3222 }
3223
3224 return endpos;
3225 }
3226
3227
3228 \f
3229 /***********************************************************************
3230 Fontification
3231 ***********************************************************************/
3232
3233 /* Handle changes in the `fontified' property of the current buffer by
3234 calling hook functions from Qfontification_functions to fontify
3235 regions of text. */
3236
3237 static enum prop_handled
3238 handle_fontified_prop (it)
3239 struct it *it;
3240 {
3241 Lisp_Object prop, pos;
3242 enum prop_handled handled = HANDLED_NORMALLY;
3243
3244 if (!NILP (Vmemory_full))
3245 return handled;
3246
3247 /* Get the value of the `fontified' property at IT's current buffer
3248 position. (The `fontified' property doesn't have a special
3249 meaning in strings.) If the value is nil, call functions from
3250 Qfontification_functions. */
3251 if (!STRINGP (it->string)
3252 && it->s == NULL
3253 && !NILP (Vfontification_functions)
3254 && !NILP (Vrun_hooks)
3255 && (pos = make_number (IT_CHARPOS (*it)),
3256 prop = Fget_char_property (pos, Qfontified, Qnil),
3257 /* Ignore the special cased nil value always present at EOB since
3258 no amount of fontifying will be able to change it. */
3259 NILP (prop) && IT_CHARPOS (*it) < Z))
3260 {
3261 int count = SPECPDL_INDEX ();
3262 Lisp_Object val;
3263
3264 val = Vfontification_functions;
3265 specbind (Qfontification_functions, Qnil);
3266
3267 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3268 safe_call1 (val, pos);
3269 else
3270 {
3271 Lisp_Object globals, fn;
3272 struct gcpro gcpro1, gcpro2;
3273
3274 globals = Qnil;
3275 GCPRO2 (val, globals);
3276
3277 for (; CONSP (val); val = XCDR (val))
3278 {
3279 fn = XCAR (val);
3280
3281 if (EQ (fn, Qt))
3282 {
3283 /* A value of t indicates this hook has a local
3284 binding; it means to run the global binding too.
3285 In a global value, t should not occur. If it
3286 does, we must ignore it to avoid an endless
3287 loop. */
3288 for (globals = Fdefault_value (Qfontification_functions);
3289 CONSP (globals);
3290 globals = XCDR (globals))
3291 {
3292 fn = XCAR (globals);
3293 if (!EQ (fn, Qt))
3294 safe_call1 (fn, pos);
3295 }
3296 }
3297 else
3298 safe_call1 (fn, pos);
3299 }
3300
3301 UNGCPRO;
3302 }
3303
3304 unbind_to (count, Qnil);
3305
3306 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3307 something. This avoids an endless loop if they failed to
3308 fontify the text for which reason ever. */
3309 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3310 handled = HANDLED_RECOMPUTE_PROPS;
3311 }
3312
3313 return handled;
3314 }
3315
3316
3317 \f
3318 /***********************************************************************
3319 Faces
3320 ***********************************************************************/
3321
3322 /* Set up iterator IT from face properties at its current position.
3323 Called from handle_stop. */
3324
3325 static enum prop_handled
3326 handle_face_prop (it)
3327 struct it *it;
3328 {
3329 int new_face_id, next_stop;
3330
3331 if (!STRINGP (it->string))
3332 {
3333 new_face_id
3334 = face_at_buffer_position (it->w,
3335 IT_CHARPOS (*it),
3336 it->region_beg_charpos,
3337 it->region_end_charpos,
3338 &next_stop,
3339 (IT_CHARPOS (*it)
3340 + TEXT_PROP_DISTANCE_LIMIT),
3341 0);
3342
3343 /* Is this a start of a run of characters with box face?
3344 Caveat: this can be called for a freshly initialized
3345 iterator; face_id is -1 in this case. We know that the new
3346 face will not change until limit, i.e. if the new face has a
3347 box, all characters up to limit will have one. But, as
3348 usual, we don't know whether limit is really the end. */
3349 if (new_face_id != it->face_id)
3350 {
3351 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3352
3353 /* If new face has a box but old face has not, this is
3354 the start of a run of characters with box, i.e. it has
3355 a shadow on the left side. The value of face_id of the
3356 iterator will be -1 if this is the initial call that gets
3357 the face. In this case, we have to look in front of IT's
3358 position and see whether there is a face != new_face_id. */
3359 it->start_of_box_run_p
3360 = (new_face->box != FACE_NO_BOX
3361 && (it->face_id >= 0
3362 || IT_CHARPOS (*it) == BEG
3363 || new_face_id != face_before_it_pos (it)));
3364 it->face_box_p = new_face->box != FACE_NO_BOX;
3365 }
3366 }
3367 else
3368 {
3369 int base_face_id, bufpos;
3370
3371 if (it->current.overlay_string_index >= 0)
3372 bufpos = IT_CHARPOS (*it);
3373 else
3374 bufpos = 0;
3375
3376 /* For strings from a buffer, i.e. overlay strings or strings
3377 from a `display' property, use the face at IT's current
3378 buffer position as the base face to merge with, so that
3379 overlay strings appear in the same face as surrounding
3380 text, unless they specify their own faces. */
3381 base_face_id = underlying_face_id (it);
3382
3383 new_face_id = face_at_string_position (it->w,
3384 it->string,
3385 IT_STRING_CHARPOS (*it),
3386 bufpos,
3387 it->region_beg_charpos,
3388 it->region_end_charpos,
3389 &next_stop,
3390 base_face_id, 0);
3391
3392 #if 0 /* This shouldn't be neccessary. Let's check it. */
3393 /* If IT is used to display a mode line we would really like to
3394 use the mode line face instead of the frame's default face. */
3395 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3396 && new_face_id == DEFAULT_FACE_ID)
3397 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3398 #endif
3399
3400 /* Is this a start of a run of characters with box? Caveat:
3401 this can be called for a freshly allocated iterator; face_id
3402 is -1 is this case. We know that the new face will not
3403 change until the next check pos, i.e. if the new face has a
3404 box, all characters up to that position will have a
3405 box. But, as usual, we don't know whether that position
3406 is really the end. */
3407 if (new_face_id != it->face_id)
3408 {
3409 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3410 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3411
3412 /* If new face has a box but old face hasn't, this is the
3413 start of a run of characters with box, i.e. it has a
3414 shadow on the left side. */
3415 it->start_of_box_run_p
3416 = new_face->box && (old_face == NULL || !old_face->box);
3417 it->face_box_p = new_face->box != FACE_NO_BOX;
3418 }
3419 }
3420
3421 it->face_id = new_face_id;
3422 return HANDLED_NORMALLY;
3423 }
3424
3425
3426 /* Return the ID of the face ``underlying'' IT's current position,
3427 which is in a string. If the iterator is associated with a
3428 buffer, return the face at IT's current buffer position.
3429 Otherwise, use the iterator's base_face_id. */
3430
3431 static int
3432 underlying_face_id (it)
3433 struct it *it;
3434 {
3435 int face_id = it->base_face_id, i;
3436
3437 xassert (STRINGP (it->string));
3438
3439 for (i = it->sp - 1; i >= 0; --i)
3440 if (NILP (it->stack[i].string))
3441 face_id = it->stack[i].face_id;
3442
3443 return face_id;
3444 }
3445
3446
3447 /* Compute the face one character before or after the current position
3448 of IT. BEFORE_P non-zero means get the face in front of IT's
3449 position. Value is the id of the face. */
3450
3451 static int
3452 face_before_or_after_it_pos (it, before_p)
3453 struct it *it;
3454 int before_p;
3455 {
3456 int face_id, limit;
3457 int next_check_charpos;
3458 struct text_pos pos;
3459
3460 xassert (it->s == NULL);
3461
3462 if (STRINGP (it->string))
3463 {
3464 int bufpos, base_face_id;
3465
3466 /* No face change past the end of the string (for the case
3467 we are padding with spaces). No face change before the
3468 string start. */
3469 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3470 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3471 return it->face_id;
3472
3473 /* Set pos to the position before or after IT's current position. */
3474 if (before_p)
3475 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3476 else
3477 /* For composition, we must check the character after the
3478 composition. */
3479 pos = (it->what == IT_COMPOSITION
3480 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3481 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3482
3483 if (it->current.overlay_string_index >= 0)
3484 bufpos = IT_CHARPOS (*it);
3485 else
3486 bufpos = 0;
3487
3488 base_face_id = underlying_face_id (it);
3489
3490 /* Get the face for ASCII, or unibyte. */
3491 face_id = face_at_string_position (it->w,
3492 it->string,
3493 CHARPOS (pos),
3494 bufpos,
3495 it->region_beg_charpos,
3496 it->region_end_charpos,
3497 &next_check_charpos,
3498 base_face_id, 0);
3499
3500 /* Correct the face for charsets different from ASCII. Do it
3501 for the multibyte case only. The face returned above is
3502 suitable for unibyte text if IT->string is unibyte. */
3503 if (STRING_MULTIBYTE (it->string))
3504 {
3505 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3506 int rest = SBYTES (it->string) - BYTEPOS (pos);
3507 int c, len;
3508 struct face *face = FACE_FROM_ID (it->f, face_id);
3509
3510 c = string_char_and_length (p, rest, &len);
3511 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3512 }
3513 }
3514 else
3515 {
3516 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3517 || (IT_CHARPOS (*it) <= BEGV && before_p))
3518 return it->face_id;
3519
3520 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3521 pos = it->current.pos;
3522
3523 if (before_p)
3524 DEC_TEXT_POS (pos, it->multibyte_p);
3525 else
3526 {
3527 if (it->what == IT_COMPOSITION)
3528 /* For composition, we must check the position after the
3529 composition. */
3530 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3531 else
3532 INC_TEXT_POS (pos, it->multibyte_p);
3533 }
3534
3535 /* Determine face for CHARSET_ASCII, or unibyte. */
3536 face_id = face_at_buffer_position (it->w,
3537 CHARPOS (pos),
3538 it->region_beg_charpos,
3539 it->region_end_charpos,
3540 &next_check_charpos,
3541 limit, 0);
3542
3543 /* Correct the face for charsets different from ASCII. Do it
3544 for the multibyte case only. The face returned above is
3545 suitable for unibyte text if current_buffer is unibyte. */
3546 if (it->multibyte_p)
3547 {
3548 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3549 struct face *face = FACE_FROM_ID (it->f, face_id);
3550 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3551 }
3552 }
3553
3554 return face_id;
3555 }
3556
3557
3558 \f
3559 /***********************************************************************
3560 Invisible text
3561 ***********************************************************************/
3562
3563 /* Set up iterator IT from invisible properties at its current
3564 position. Called from handle_stop. */
3565
3566 static enum prop_handled
3567 handle_invisible_prop (it)
3568 struct it *it;
3569 {
3570 enum prop_handled handled = HANDLED_NORMALLY;
3571
3572 if (STRINGP (it->string))
3573 {
3574 extern Lisp_Object Qinvisible;
3575 Lisp_Object prop, end_charpos, limit, charpos;
3576
3577 /* Get the value of the invisible text property at the
3578 current position. Value will be nil if there is no such
3579 property. */
3580 charpos = make_number (IT_STRING_CHARPOS (*it));
3581 prop = Fget_text_property (charpos, Qinvisible, it->string);
3582
3583 if (!NILP (prop)
3584 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3585 {
3586 handled = HANDLED_RECOMPUTE_PROPS;
3587
3588 /* Get the position at which the next change of the
3589 invisible text property can be found in IT->string.
3590 Value will be nil if the property value is the same for
3591 all the rest of IT->string. */
3592 XSETINT (limit, SCHARS (it->string));
3593 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3594 it->string, limit);
3595
3596 /* Text at current position is invisible. The next
3597 change in the property is at position end_charpos.
3598 Move IT's current position to that position. */
3599 if (INTEGERP (end_charpos)
3600 && XFASTINT (end_charpos) < XFASTINT (limit))
3601 {
3602 struct text_pos old;
3603 old = it->current.string_pos;
3604 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3605 compute_string_pos (&it->current.string_pos, old, it->string);
3606 }
3607 else
3608 {
3609 /* The rest of the string is invisible. If this is an
3610 overlay string, proceed with the next overlay string
3611 or whatever comes and return a character from there. */
3612 if (it->current.overlay_string_index >= 0)
3613 {
3614 next_overlay_string (it);
3615 /* Don't check for overlay strings when we just
3616 finished processing them. */
3617 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3618 }
3619 else
3620 {
3621 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3622 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3623 }
3624 }
3625 }
3626 }
3627 else
3628 {
3629 int invis_p;
3630 EMACS_INT newpos, next_stop, start_charpos;
3631 Lisp_Object pos, prop, overlay;
3632
3633 /* First of all, is there invisible text at this position? */
3634 start_charpos = IT_CHARPOS (*it);
3635 pos = make_number (IT_CHARPOS (*it));
3636 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3637 &overlay);
3638 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3639
3640 /* If we are on invisible text, skip over it. */
3641 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3642 {
3643 /* Record whether we have to display an ellipsis for the
3644 invisible text. */
3645 int display_ellipsis_p = invis_p == 2;
3646
3647 handled = HANDLED_RECOMPUTE_PROPS;
3648
3649 /* Loop skipping over invisible text. The loop is left at
3650 ZV or with IT on the first char being visible again. */
3651 do
3652 {
3653 /* Try to skip some invisible text. Return value is the
3654 position reached which can be equal to IT's position
3655 if there is nothing invisible here. This skips both
3656 over invisible text properties and overlays with
3657 invisible property. */
3658 newpos = skip_invisible (IT_CHARPOS (*it),
3659 &next_stop, ZV, it->window);
3660
3661 /* If we skipped nothing at all we weren't at invisible
3662 text in the first place. If everything to the end of
3663 the buffer was skipped, end the loop. */
3664 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3665 invis_p = 0;
3666 else
3667 {
3668 /* We skipped some characters but not necessarily
3669 all there are. Check if we ended up on visible
3670 text. Fget_char_property returns the property of
3671 the char before the given position, i.e. if we
3672 get invis_p = 0, this means that the char at
3673 newpos is visible. */
3674 pos = make_number (newpos);
3675 prop = Fget_char_property (pos, Qinvisible, it->window);
3676 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3677 }
3678
3679 /* If we ended up on invisible text, proceed to
3680 skip starting with next_stop. */
3681 if (invis_p)
3682 IT_CHARPOS (*it) = next_stop;
3683
3684 /* If there are adjacent invisible texts, don't lose the
3685 second one's ellipsis. */
3686 if (invis_p == 2)
3687 display_ellipsis_p = 1;
3688 }
3689 while (invis_p);
3690
3691 /* The position newpos is now either ZV or on visible text. */
3692 IT_CHARPOS (*it) = newpos;
3693 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3694
3695 /* If there are before-strings at the start of invisible
3696 text, and the text is invisible because of a text
3697 property, arrange to show before-strings because 20.x did
3698 it that way. (If the text is invisible because of an
3699 overlay property instead of a text property, this is
3700 already handled in the overlay code.) */
3701 if (NILP (overlay)
3702 && get_overlay_strings (it, start_charpos))
3703 {
3704 handled = HANDLED_RECOMPUTE_PROPS;
3705 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3706 }
3707 else if (display_ellipsis_p)
3708 {
3709 /* Make sure that the glyphs of the ellipsis will get
3710 correct `charpos' values. If we would not update
3711 it->position here, the glyphs would belong to the
3712 last visible character _before_ the invisible
3713 text, which confuses `set_cursor_from_row'.
3714
3715 We use the last invisible position instead of the
3716 first because this way the cursor is always drawn on
3717 the first "." of the ellipsis, whenever PT is inside
3718 the invisible text. Otherwise the cursor would be
3719 placed _after_ the ellipsis when the point is after the
3720 first invisible character. */
3721 if (!STRINGP (it->object))
3722 {
3723 it->position.charpos = IT_CHARPOS (*it) - 1;
3724 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3725 }
3726 setup_for_ellipsis (it, 0);
3727 }
3728 }
3729 }
3730
3731 return handled;
3732 }
3733
3734
3735 /* Make iterator IT return `...' next.
3736 Replaces LEN characters from buffer. */
3737
3738 static void
3739 setup_for_ellipsis (it, len)
3740 struct it *it;
3741 int len;
3742 {
3743 /* Use the display table definition for `...'. Invalid glyphs
3744 will be handled by the method returning elements from dpvec. */
3745 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3746 {
3747 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3748 it->dpvec = v->contents;
3749 it->dpend = v->contents + v->size;
3750 }
3751 else
3752 {
3753 /* Default `...'. */
3754 it->dpvec = default_invis_vector;
3755 it->dpend = default_invis_vector + 3;
3756 }
3757
3758 it->dpvec_char_len = len;
3759 it->current.dpvec_index = 0;
3760 it->dpvec_face_id = -1;
3761
3762 /* Remember the current face id in case glyphs specify faces.
3763 IT's face is restored in set_iterator_to_next.
3764 saved_face_id was set to preceding char's face in handle_stop. */
3765 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3766 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3767
3768 it->method = GET_FROM_DISPLAY_VECTOR;
3769 it->ellipsis_p = 1;
3770 }
3771
3772
3773 \f
3774 /***********************************************************************
3775 'display' property
3776 ***********************************************************************/
3777
3778 /* Set up iterator IT from `display' property at its current position.
3779 Called from handle_stop.
3780 We return HANDLED_RETURN if some part of the display property
3781 overrides the display of the buffer text itself.
3782 Otherwise we return HANDLED_NORMALLY. */
3783
3784 static enum prop_handled
3785 handle_display_prop (it)
3786 struct it *it;
3787 {
3788 Lisp_Object prop, object;
3789 struct text_pos *position;
3790 /* Nonzero if some property replaces the display of the text itself. */
3791 int display_replaced_p = 0;
3792
3793 if (STRINGP (it->string))
3794 {
3795 object = it->string;
3796 position = &it->current.string_pos;
3797 }
3798 else
3799 {
3800 XSETWINDOW (object, it->w);
3801 position = &it->current.pos;
3802 }
3803
3804 /* Reset those iterator values set from display property values. */
3805 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3806 it->space_width = Qnil;
3807 it->font_height = Qnil;
3808 it->voffset = 0;
3809
3810 /* We don't support recursive `display' properties, i.e. string
3811 values that have a string `display' property, that have a string
3812 `display' property etc. */
3813 if (!it->string_from_display_prop_p)
3814 it->area = TEXT_AREA;
3815
3816 prop = Fget_char_property (make_number (position->charpos),
3817 Qdisplay, object);
3818 if (NILP (prop))
3819 return HANDLED_NORMALLY;
3820
3821 if (!STRINGP (it->string))
3822 object = it->w->buffer;
3823
3824 if (CONSP (prop)
3825 /* Simple properties. */
3826 && !EQ (XCAR (prop), Qimage)
3827 && !EQ (XCAR (prop), Qspace)
3828 && !EQ (XCAR (prop), Qwhen)
3829 && !EQ (XCAR (prop), Qslice)
3830 && !EQ (XCAR (prop), Qspace_width)
3831 && !EQ (XCAR (prop), Qheight)
3832 && !EQ (XCAR (prop), Qraise)
3833 /* Marginal area specifications. */
3834 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3835 && !EQ (XCAR (prop), Qleft_fringe)
3836 && !EQ (XCAR (prop), Qright_fringe)
3837 && !NILP (XCAR (prop)))
3838 {
3839 for (; CONSP (prop); prop = XCDR (prop))
3840 {
3841 if (handle_single_display_spec (it, XCAR (prop), object,
3842 position, display_replaced_p))
3843 display_replaced_p = 1;
3844 }
3845 }
3846 else if (VECTORP (prop))
3847 {
3848 int i;
3849 for (i = 0; i < ASIZE (prop); ++i)
3850 if (handle_single_display_spec (it, AREF (prop, i), object,
3851 position, display_replaced_p))
3852 display_replaced_p = 1;
3853 }
3854 else
3855 {
3856 int ret = handle_single_display_spec (it, prop, object, position, 0);
3857 if (ret < 0) /* Replaced by "", i.e. nothing. */
3858 return HANDLED_RECOMPUTE_PROPS;
3859 if (ret)
3860 display_replaced_p = 1;
3861 }
3862
3863 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3864 }
3865
3866
3867 /* Value is the position of the end of the `display' property starting
3868 at START_POS in OBJECT. */
3869
3870 static struct text_pos
3871 display_prop_end (it, object, start_pos)
3872 struct it *it;
3873 Lisp_Object object;
3874 struct text_pos start_pos;
3875 {
3876 Lisp_Object end;
3877 struct text_pos end_pos;
3878
3879 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3880 Qdisplay, object, Qnil);
3881 CHARPOS (end_pos) = XFASTINT (end);
3882 if (STRINGP (object))
3883 compute_string_pos (&end_pos, start_pos, it->string);
3884 else
3885 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3886
3887 return end_pos;
3888 }
3889
3890
3891 /* Set up IT from a single `display' specification PROP. OBJECT
3892 is the object in which the `display' property was found. *POSITION
3893 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3894 means that we previously saw a display specification which already
3895 replaced text display with something else, for example an image;
3896 we ignore such properties after the first one has been processed.
3897
3898 If PROP is a `space' or `image' specification, and in some other
3899 cases too, set *POSITION to the position where the `display'
3900 property ends.
3901
3902 Value is non-zero if something was found which replaces the display
3903 of buffer or string text. Specifically, the value is -1 if that
3904 "something" is "nothing". */
3905
3906 static int
3907 handle_single_display_spec (it, spec, object, position,
3908 display_replaced_before_p)
3909 struct it *it;
3910 Lisp_Object spec;
3911 Lisp_Object object;
3912 struct text_pos *position;
3913 int display_replaced_before_p;
3914 {
3915 Lisp_Object form;
3916 Lisp_Object location, value;
3917 struct text_pos start_pos, save_pos;
3918 int valid_p;
3919
3920 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3921 If the result is non-nil, use VALUE instead of SPEC. */
3922 form = Qt;
3923 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3924 {
3925 spec = XCDR (spec);
3926 if (!CONSP (spec))
3927 return 0;
3928 form = XCAR (spec);
3929 spec = XCDR (spec);
3930 }
3931
3932 if (!NILP (form) && !EQ (form, Qt))
3933 {
3934 int count = SPECPDL_INDEX ();
3935 struct gcpro gcpro1;
3936
3937 /* Bind `object' to the object having the `display' property, a
3938 buffer or string. Bind `position' to the position in the
3939 object where the property was found, and `buffer-position'
3940 to the current position in the buffer. */
3941 specbind (Qobject, object);
3942 specbind (Qposition, make_number (CHARPOS (*position)));
3943 specbind (Qbuffer_position,
3944 make_number (STRINGP (object)
3945 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3946 GCPRO1 (form);
3947 form = safe_eval (form);
3948 UNGCPRO;
3949 unbind_to (count, Qnil);
3950 }
3951
3952 if (NILP (form))
3953 return 0;
3954
3955 /* Handle `(height HEIGHT)' specifications. */
3956 if (CONSP (spec)
3957 && EQ (XCAR (spec), Qheight)
3958 && CONSP (XCDR (spec)))
3959 {
3960 if (!FRAME_WINDOW_P (it->f))
3961 return 0;
3962
3963 it->font_height = XCAR (XCDR (spec));
3964 if (!NILP (it->font_height))
3965 {
3966 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3967 int new_height = -1;
3968
3969 if (CONSP (it->font_height)
3970 && (EQ (XCAR (it->font_height), Qplus)
3971 || EQ (XCAR (it->font_height), Qminus))
3972 && CONSP (XCDR (it->font_height))
3973 && INTEGERP (XCAR (XCDR (it->font_height))))
3974 {
3975 /* `(+ N)' or `(- N)' where N is an integer. */
3976 int steps = XINT (XCAR (XCDR (it->font_height)));
3977 if (EQ (XCAR (it->font_height), Qplus))
3978 steps = - steps;
3979 it->face_id = smaller_face (it->f, it->face_id, steps);
3980 }
3981 else if (FUNCTIONP (it->font_height))
3982 {
3983 /* Call function with current height as argument.
3984 Value is the new height. */
3985 Lisp_Object height;
3986 height = safe_call1 (it->font_height,
3987 face->lface[LFACE_HEIGHT_INDEX]);
3988 if (NUMBERP (height))
3989 new_height = XFLOATINT (height);
3990 }
3991 else if (NUMBERP (it->font_height))
3992 {
3993 /* Value is a multiple of the canonical char height. */
3994 struct face *face;
3995
3996 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3997 new_height = (XFLOATINT (it->font_height)
3998 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3999 }
4000 else
4001 {
4002 /* Evaluate IT->font_height with `height' bound to the
4003 current specified height to get the new height. */
4004 int count = SPECPDL_INDEX ();
4005
4006 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4007 value = safe_eval (it->font_height);
4008 unbind_to (count, Qnil);
4009
4010 if (NUMBERP (value))
4011 new_height = XFLOATINT (value);
4012 }
4013
4014 if (new_height > 0)
4015 it->face_id = face_with_height (it->f, it->face_id, new_height);
4016 }
4017
4018 return 0;
4019 }
4020
4021 /* Handle `(space_width WIDTH)'. */
4022 if (CONSP (spec)
4023 && EQ (XCAR (spec), Qspace_width)
4024 && CONSP (XCDR (spec)))
4025 {
4026 if (!FRAME_WINDOW_P (it->f))
4027 return 0;
4028
4029 value = XCAR (XCDR (spec));
4030 if (NUMBERP (value) && XFLOATINT (value) > 0)
4031 it->space_width = value;
4032
4033 return 0;
4034 }
4035
4036 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4037 if (CONSP (spec)
4038 && EQ (XCAR (spec), Qslice))
4039 {
4040 Lisp_Object tem;
4041
4042 if (!FRAME_WINDOW_P (it->f))
4043 return 0;
4044
4045 if (tem = XCDR (spec), CONSP (tem))
4046 {
4047 it->slice.x = XCAR (tem);
4048 if (tem = XCDR (tem), CONSP (tem))
4049 {
4050 it->slice.y = XCAR (tem);
4051 if (tem = XCDR (tem), CONSP (tem))
4052 {
4053 it->slice.width = XCAR (tem);
4054 if (tem = XCDR (tem), CONSP (tem))
4055 it->slice.height = XCAR (tem);
4056 }
4057 }
4058 }
4059
4060 return 0;
4061 }
4062
4063 /* Handle `(raise FACTOR)'. */
4064 if (CONSP (spec)
4065 && EQ (XCAR (spec), Qraise)
4066 && CONSP (XCDR (spec)))
4067 {
4068 if (!FRAME_WINDOW_P (it->f))
4069 return 0;
4070
4071 #ifdef HAVE_WINDOW_SYSTEM
4072 value = XCAR (XCDR (spec));
4073 if (NUMBERP (value))
4074 {
4075 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4076 it->voffset = - (XFLOATINT (value)
4077 * (FONT_HEIGHT (face->font)));
4078 }
4079 #endif /* HAVE_WINDOW_SYSTEM */
4080
4081 return 0;
4082 }
4083
4084 /* Don't handle the other kinds of display specifications
4085 inside a string that we got from a `display' property. */
4086 if (it->string_from_display_prop_p)
4087 return 0;
4088
4089 /* Characters having this form of property are not displayed, so
4090 we have to find the end of the property. */
4091 start_pos = *position;
4092 *position = display_prop_end (it, object, start_pos);
4093 value = Qnil;
4094
4095 /* Stop the scan at that end position--we assume that all
4096 text properties change there. */
4097 it->stop_charpos = position->charpos;
4098
4099 /* Handle `(left-fringe BITMAP [FACE])'
4100 and `(right-fringe BITMAP [FACE])'. */
4101 if (CONSP (spec)
4102 && (EQ (XCAR (spec), Qleft_fringe)
4103 || EQ (XCAR (spec), Qright_fringe))
4104 && CONSP (XCDR (spec)))
4105 {
4106 int face_id = DEFAULT_FACE_ID;
4107 int fringe_bitmap;
4108
4109 if (!FRAME_WINDOW_P (it->f))
4110 /* If we return here, POSITION has been advanced
4111 across the text with this property. */
4112 return 0;
4113
4114 #ifdef HAVE_WINDOW_SYSTEM
4115 value = XCAR (XCDR (spec));
4116 if (!SYMBOLP (value)
4117 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4118 /* If we return here, POSITION has been advanced
4119 across the text with this property. */
4120 return 0;
4121
4122 if (CONSP (XCDR (XCDR (spec))))
4123 {
4124 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4125 int face_id2 = lookup_derived_face (it->f, face_name,
4126 FRINGE_FACE_ID, 0);
4127 if (face_id2 >= 0)
4128 face_id = face_id2;
4129 }
4130
4131 /* Save current settings of IT so that we can restore them
4132 when we are finished with the glyph property value. */
4133
4134 save_pos = it->position;
4135 it->position = *position;
4136 push_it (it);
4137 it->position = save_pos;
4138
4139 it->area = TEXT_AREA;
4140 it->what = IT_IMAGE;
4141 it->image_id = -1; /* no image */
4142 it->position = start_pos;
4143 it->object = NILP (object) ? it->w->buffer : object;
4144 it->method = GET_FROM_IMAGE;
4145 it->face_id = face_id;
4146
4147 /* Say that we haven't consumed the characters with
4148 `display' property yet. The call to pop_it in
4149 set_iterator_to_next will clean this up. */
4150 *position = start_pos;
4151
4152 if (EQ (XCAR (spec), Qleft_fringe))
4153 {
4154 it->left_user_fringe_bitmap = fringe_bitmap;
4155 it->left_user_fringe_face_id = face_id;
4156 }
4157 else
4158 {
4159 it->right_user_fringe_bitmap = fringe_bitmap;
4160 it->right_user_fringe_face_id = face_id;
4161 }
4162 #endif /* HAVE_WINDOW_SYSTEM */
4163 return 1;
4164 }
4165
4166 /* Prepare to handle `((margin left-margin) ...)',
4167 `((margin right-margin) ...)' and `((margin nil) ...)'
4168 prefixes for display specifications. */
4169 location = Qunbound;
4170 if (CONSP (spec) && CONSP (XCAR (spec)))
4171 {
4172 Lisp_Object tem;
4173
4174 value = XCDR (spec);
4175 if (CONSP (value))
4176 value = XCAR (value);
4177
4178 tem = XCAR (spec);
4179 if (EQ (XCAR (tem), Qmargin)
4180 && (tem = XCDR (tem),
4181 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4182 (NILP (tem)
4183 || EQ (tem, Qleft_margin)
4184 || EQ (tem, Qright_margin))))
4185 location = tem;
4186 }
4187
4188 if (EQ (location, Qunbound))
4189 {
4190 location = Qnil;
4191 value = spec;
4192 }
4193
4194 /* After this point, VALUE is the property after any
4195 margin prefix has been stripped. It must be a string,
4196 an image specification, or `(space ...)'.
4197
4198 LOCATION specifies where to display: `left-margin',
4199 `right-margin' or nil. */
4200
4201 valid_p = (STRINGP (value)
4202 #ifdef HAVE_WINDOW_SYSTEM
4203 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4204 #endif /* not HAVE_WINDOW_SYSTEM */
4205 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4206
4207 if (valid_p && !display_replaced_before_p)
4208 {
4209 /* Save current settings of IT so that we can restore them
4210 when we are finished with the glyph property value. */
4211 save_pos = it->position;
4212 it->position = *position;
4213 push_it (it);
4214 it->position = save_pos;
4215
4216 if (NILP (location))
4217 it->area = TEXT_AREA;
4218 else if (EQ (location, Qleft_margin))
4219 it->area = LEFT_MARGIN_AREA;
4220 else
4221 it->area = RIGHT_MARGIN_AREA;
4222
4223 if (STRINGP (value))
4224 {
4225 if (SCHARS (value) == 0)
4226 {
4227 pop_it (it);
4228 return -1; /* Replaced by "", i.e. nothing. */
4229 }
4230 it->string = value;
4231 it->multibyte_p = STRING_MULTIBYTE (it->string);
4232 it->current.overlay_string_index = -1;
4233 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4234 it->end_charpos = it->string_nchars = SCHARS (it->string);
4235 it->method = GET_FROM_STRING;
4236 it->stop_charpos = 0;
4237 it->string_from_display_prop_p = 1;
4238 /* Say that we haven't consumed the characters with
4239 `display' property yet. The call to pop_it in
4240 set_iterator_to_next will clean this up. */
4241 *position = start_pos;
4242 }
4243 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4244 {
4245 it->method = GET_FROM_STRETCH;
4246 it->object = value;
4247 *position = it->position = start_pos;
4248 }
4249 #ifdef HAVE_WINDOW_SYSTEM
4250 else
4251 {
4252 it->what = IT_IMAGE;
4253 it->image_id = lookup_image (it->f, value);
4254 it->position = start_pos;
4255 it->object = NILP (object) ? it->w->buffer : object;
4256 it->method = GET_FROM_IMAGE;
4257
4258 /* Say that we haven't consumed the characters with
4259 `display' property yet. The call to pop_it in
4260 set_iterator_to_next will clean this up. */
4261 *position = start_pos;
4262 }
4263 #endif /* HAVE_WINDOW_SYSTEM */
4264
4265 return 1;
4266 }
4267
4268 /* Invalid property or property not supported. Restore
4269 POSITION to what it was before. */
4270 *position = start_pos;
4271 return 0;
4272 }
4273
4274
4275 /* Check if SPEC is a display sub-property value whose text should be
4276 treated as intangible. */
4277
4278 static int
4279 single_display_spec_intangible_p (prop)
4280 Lisp_Object prop;
4281 {
4282 /* Skip over `when FORM'. */
4283 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4284 {
4285 prop = XCDR (prop);
4286 if (!CONSP (prop))
4287 return 0;
4288 prop = XCDR (prop);
4289 }
4290
4291 if (STRINGP (prop))
4292 return 1;
4293
4294 if (!CONSP (prop))
4295 return 0;
4296
4297 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4298 we don't need to treat text as intangible. */
4299 if (EQ (XCAR (prop), Qmargin))
4300 {
4301 prop = XCDR (prop);
4302 if (!CONSP (prop))
4303 return 0;
4304
4305 prop = XCDR (prop);
4306 if (!CONSP (prop)
4307 || EQ (XCAR (prop), Qleft_margin)
4308 || EQ (XCAR (prop), Qright_margin))
4309 return 0;
4310 }
4311
4312 return (CONSP (prop)
4313 && (EQ (XCAR (prop), Qimage)
4314 || EQ (XCAR (prop), Qspace)));
4315 }
4316
4317
4318 /* Check if PROP is a display property value whose text should be
4319 treated as intangible. */
4320
4321 int
4322 display_prop_intangible_p (prop)
4323 Lisp_Object prop;
4324 {
4325 if (CONSP (prop)
4326 && CONSP (XCAR (prop))
4327 && !EQ (Qmargin, XCAR (XCAR (prop))))
4328 {
4329 /* A list of sub-properties. */
4330 while (CONSP (prop))
4331 {
4332 if (single_display_spec_intangible_p (XCAR (prop)))
4333 return 1;
4334 prop = XCDR (prop);
4335 }
4336 }
4337 else if (VECTORP (prop))
4338 {
4339 /* A vector of sub-properties. */
4340 int i;
4341 for (i = 0; i < ASIZE (prop); ++i)
4342 if (single_display_spec_intangible_p (AREF (prop, i)))
4343 return 1;
4344 }
4345 else
4346 return single_display_spec_intangible_p (prop);
4347
4348 return 0;
4349 }
4350
4351
4352 /* Return 1 if PROP is a display sub-property value containing STRING. */
4353
4354 static int
4355 single_display_spec_string_p (prop, string)
4356 Lisp_Object prop, string;
4357 {
4358 if (EQ (string, prop))
4359 return 1;
4360
4361 /* Skip over `when FORM'. */
4362 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4363 {
4364 prop = XCDR (prop);
4365 if (!CONSP (prop))
4366 return 0;
4367 prop = XCDR (prop);
4368 }
4369
4370 if (CONSP (prop))
4371 /* Skip over `margin LOCATION'. */
4372 if (EQ (XCAR (prop), Qmargin))
4373 {
4374 prop = XCDR (prop);
4375 if (!CONSP (prop))
4376 return 0;
4377
4378 prop = XCDR (prop);
4379 if (!CONSP (prop))
4380 return 0;
4381 }
4382
4383 return CONSP (prop) && EQ (XCAR (prop), string);
4384 }
4385
4386
4387 /* Return 1 if STRING appears in the `display' property PROP. */
4388
4389 static int
4390 display_prop_string_p (prop, string)
4391 Lisp_Object prop, string;
4392 {
4393 if (CONSP (prop)
4394 && CONSP (XCAR (prop))
4395 && !EQ (Qmargin, XCAR (XCAR (prop))))
4396 {
4397 /* A list of sub-properties. */
4398 while (CONSP (prop))
4399 {
4400 if (single_display_spec_string_p (XCAR (prop), string))
4401 return 1;
4402 prop = XCDR (prop);
4403 }
4404 }
4405 else if (VECTORP (prop))
4406 {
4407 /* A vector of sub-properties. */
4408 int i;
4409 for (i = 0; i < ASIZE (prop); ++i)
4410 if (single_display_spec_string_p (AREF (prop, i), string))
4411 return 1;
4412 }
4413 else
4414 return single_display_spec_string_p (prop, string);
4415
4416 return 0;
4417 }
4418
4419
4420 /* Determine from which buffer position in W's buffer STRING comes
4421 from. AROUND_CHARPOS is an approximate position where it could
4422 be from. Value is the buffer position or 0 if it couldn't be
4423 determined.
4424
4425 W's buffer must be current.
4426
4427 This function is necessary because we don't record buffer positions
4428 in glyphs generated from strings (to keep struct glyph small).
4429 This function may only use code that doesn't eval because it is
4430 called asynchronously from note_mouse_highlight. */
4431
4432 int
4433 string_buffer_position (w, string, around_charpos)
4434 struct window *w;
4435 Lisp_Object string;
4436 int around_charpos;
4437 {
4438 Lisp_Object limit, prop, pos;
4439 const int MAX_DISTANCE = 1000;
4440 int found = 0;
4441
4442 pos = make_number (around_charpos);
4443 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4444 while (!found && !EQ (pos, limit))
4445 {
4446 prop = Fget_char_property (pos, Qdisplay, Qnil);
4447 if (!NILP (prop) && display_prop_string_p (prop, string))
4448 found = 1;
4449 else
4450 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4451 }
4452
4453 if (!found)
4454 {
4455 pos = make_number (around_charpos);
4456 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4457 while (!found && !EQ (pos, limit))
4458 {
4459 prop = Fget_char_property (pos, Qdisplay, Qnil);
4460 if (!NILP (prop) && display_prop_string_p (prop, string))
4461 found = 1;
4462 else
4463 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4464 limit);
4465 }
4466 }
4467
4468 return found ? XINT (pos) : 0;
4469 }
4470
4471
4472 \f
4473 /***********************************************************************
4474 `composition' property
4475 ***********************************************************************/
4476
4477 static enum prop_handled
4478 handle_auto_composed_prop (it)
4479 struct it *it;
4480 {
4481 enum prop_handled handled = HANDLED_NORMALLY;
4482
4483 if (FUNCTIONP (Vauto_composition_function))
4484 {
4485 Lisp_Object val;
4486 EMACS_INT pos, this_pos;
4487
4488 if (STRINGP (it->string))
4489 pos = IT_STRING_CHARPOS (*it);
4490 else
4491 pos = IT_CHARPOS (*it);
4492 this_pos = pos;
4493
4494 val =Fget_char_property (make_number (pos), Qauto_composed, it->string);
4495 if (! NILP (val))
4496 {
4497 Lisp_Object limit = Qnil, next;
4498
4499 /* As Fnext_single_char_property_change is very slow, we
4500 limit the search to the current line. */
4501 if (STRINGP (it->string))
4502 limit = make_number (SCHARS (it->string));
4503 else
4504 limit = make_number (find_next_newline_no_quit (pos, 1));
4505
4506 next = (Fnext_single_property_change
4507 (make_number (pos), Qauto_composed, it->string, limit));
4508 if (XINT (next) < XINT (limit))
4509 {
4510 /* The current point is auto-composed, but there exist
4511 characters not yet composed beyond the auto-composed
4512 region. There's a possiblity that the last
4513 characters in the region may be newly composed. */
4514 int charpos = XINT (next) - 1, bytepos, c;
4515
4516 if (STRINGP (it->string))
4517 {
4518 bytepos = string_char_to_byte (it->string, charpos);
4519 c = SDATA (it->string)[bytepos];
4520 }
4521 else
4522 {
4523 bytepos = CHAR_TO_BYTE (charpos);
4524 c = FETCH_BYTE (bytepos);
4525 }
4526 if (c != '\n')
4527 /* If the last character is not newline, it may be
4528 composed with the following characters. */
4529 val = Qnil, pos = charpos + 1;
4530 }
4531 }
4532 if (NILP (val))
4533 {
4534 int count = SPECPDL_INDEX ();
4535 Lisp_Object args[4];
4536
4537 args[0] = Vauto_composition_function;
4538 specbind (Qauto_composition_function, Qnil);
4539 args[1] = make_number (pos);
4540 args[2] = it->string;
4541 #ifdef USE_FONT_BACKEND
4542 if (enable_font_backend)
4543 {
4544 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4545 int c;
4546
4547 if (STRINGP (it->string))
4548 {
4549 EMACS_INT pos_byte = IT_STRING_BYTEPOS (*it);
4550 const unsigned char *s = SDATA (it->string) + pos_byte;
4551
4552 if (STRING_MULTIBYTE (it->string))
4553 it->c = STRING_CHAR (s, 0);
4554 else
4555 it->c = *s;
4556 }
4557 else
4558 {
4559 EMACS_INT pos_byte = IT_BYTEPOS (*it);
4560
4561 it->c = FETCH_CHAR (pos_byte);
4562 }
4563 args[3] = font_at (it->c, this_pos, face, it->w, it->string);
4564 }
4565 else
4566 #endif /* USE_FONT_BACKEND */
4567 args[3] = Qnil;
4568 safe_call (4, args);
4569 unbind_to (count, Qnil);
4570
4571 if (this_pos == pos)
4572 {
4573 val = Fget_char_property (args[1], Qauto_composed, it->string);
4574 /* Return HANDLED_RECOMPUTE_PROPS only if function composed
4575 something. This avoids an endless loop if they failed to
4576 fontify the text for which reason ever. */
4577 if (! NILP (val))
4578 handled = HANDLED_RECOMPUTE_PROPS;
4579 }
4580 else
4581 handled = HANDLED_RECOMPUTE_PROPS;
4582 }
4583 }
4584
4585 return handled;
4586 }
4587
4588 /* Set up iterator IT from `composition' property at its current
4589 position. Called from handle_stop. */
4590
4591 static enum prop_handled
4592 handle_composition_prop (it)
4593 struct it *it;
4594 {
4595 Lisp_Object prop, string;
4596 EMACS_INT pos, pos_byte, start, end;
4597 enum prop_handled handled = HANDLED_NORMALLY;
4598
4599 if (STRINGP (it->string))
4600 {
4601 pos = IT_STRING_CHARPOS (*it);
4602 pos_byte = IT_STRING_BYTEPOS (*it);
4603 string = it->string;
4604 }
4605 else
4606 {
4607 pos = IT_CHARPOS (*it);
4608 pos_byte = IT_BYTEPOS (*it);
4609 string = Qnil;
4610 }
4611
4612 /* If there's a valid composition and point is not inside of the
4613 composition (in the case that the composition is from the current
4614 buffer), draw a glyph composed from the composition components. */
4615 if (find_composition (pos, -1, &start, &end, &prop, string)
4616 && COMPOSITION_VALID_P (start, end, prop)
4617 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4618 {
4619 int id;
4620
4621 if (start != pos)
4622 {
4623 if (STRINGP (it->string))
4624 pos_byte = string_char_to_byte (it->string, start);
4625 else
4626 pos_byte = CHAR_TO_BYTE (start);
4627 }
4628 id = get_composition_id (start, pos_byte, end - start, prop, string);
4629
4630 if (id >= 0)
4631 {
4632 struct composition *cmp = composition_table[id];
4633
4634 if (cmp->glyph_len == 0)
4635 {
4636 /* No glyph. */
4637 if (STRINGP (it->string))
4638 {
4639 IT_STRING_CHARPOS (*it) = end;
4640 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string,
4641 end);
4642 }
4643 else
4644 {
4645 IT_CHARPOS (*it) = end;
4646 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end);
4647 }
4648 return HANDLED_RECOMPUTE_PROPS;
4649 }
4650
4651 it->stop_charpos = end;
4652 push_it (it);
4653
4654 it->method = GET_FROM_COMPOSITION;
4655 it->cmp_id = id;
4656 it->cmp_len = COMPOSITION_LENGTH (prop);
4657 /* For a terminal, draw only the first (non-TAB) character
4658 of the components. */
4659 #ifdef USE_FONT_BACKEND
4660 if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
4661 {
4662 Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
4663 ->key_and_value,
4664 cmp->hash_index * 2);
4665
4666 it->c = XINT (LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, 0)));
4667 }
4668 else
4669 #endif /* USE_FONT_BACKEND */
4670 {
4671 int i;
4672
4673 for (i = 0; i < cmp->glyph_len; i++)
4674 if ((it->c = COMPOSITION_GLYPH (composition_table[id], i))
4675 != '\t')
4676 break;
4677 }
4678 if (it->c == '\t')
4679 it->c = ' ';
4680 it->len = (STRINGP (it->string)
4681 ? string_char_to_byte (it->string, end)
4682 : CHAR_TO_BYTE (end)) - pos_byte;
4683 handled = HANDLED_RETURN;
4684 }
4685 }
4686
4687 return handled;
4688 }
4689
4690
4691 \f
4692 /***********************************************************************
4693 Overlay strings
4694 ***********************************************************************/
4695
4696 /* The following structure is used to record overlay strings for
4697 later sorting in load_overlay_strings. */
4698
4699 struct overlay_entry
4700 {
4701 Lisp_Object overlay;
4702 Lisp_Object string;
4703 int priority;
4704 int after_string_p;
4705 };
4706
4707
4708 /* Set up iterator IT from overlay strings at its current position.
4709 Called from handle_stop. */
4710
4711 static enum prop_handled
4712 handle_overlay_change (it)
4713 struct it *it;
4714 {
4715 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4716 return HANDLED_RECOMPUTE_PROPS;
4717 else
4718 return HANDLED_NORMALLY;
4719 }
4720
4721
4722 /* Set up the next overlay string for delivery by IT, if there is an
4723 overlay string to deliver. Called by set_iterator_to_next when the
4724 end of the current overlay string is reached. If there are more
4725 overlay strings to display, IT->string and
4726 IT->current.overlay_string_index are set appropriately here.
4727 Otherwise IT->string is set to nil. */
4728
4729 static void
4730 next_overlay_string (it)
4731 struct it *it;
4732 {
4733 ++it->current.overlay_string_index;
4734 if (it->current.overlay_string_index == it->n_overlay_strings)
4735 {
4736 /* No more overlay strings. Restore IT's settings to what
4737 they were before overlay strings were processed, and
4738 continue to deliver from current_buffer. */
4739 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4740
4741 pop_it (it);
4742 xassert (it->sp > 0
4743 || it->method == GET_FROM_COMPOSITION
4744 || (NILP (it->string)
4745 && it->method == GET_FROM_BUFFER
4746 && it->stop_charpos >= BEGV
4747 && it->stop_charpos <= it->end_charpos));
4748 it->current.overlay_string_index = -1;
4749 it->n_overlay_strings = 0;
4750
4751 /* If we're at the end of the buffer, record that we have
4752 processed the overlay strings there already, so that
4753 next_element_from_buffer doesn't try it again. */
4754 if (IT_CHARPOS (*it) >= it->end_charpos)
4755 it->overlay_strings_at_end_processed_p = 1;
4756
4757 /* If we have to display `...' for invisible text, set
4758 the iterator up for that. */
4759 if (display_ellipsis_p)
4760 setup_for_ellipsis (it, 0);
4761 }
4762 else
4763 {
4764 /* There are more overlay strings to process. If
4765 IT->current.overlay_string_index has advanced to a position
4766 where we must load IT->overlay_strings with more strings, do
4767 it. */
4768 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4769
4770 if (it->current.overlay_string_index && i == 0)
4771 load_overlay_strings (it, 0);
4772
4773 /* Initialize IT to deliver display elements from the overlay
4774 string. */
4775 it->string = it->overlay_strings[i];
4776 it->multibyte_p = STRING_MULTIBYTE (it->string);
4777 SET_TEXT_POS (it->current.string_pos, 0, 0);
4778 it->method = GET_FROM_STRING;
4779 it->stop_charpos = 0;
4780 }
4781
4782 CHECK_IT (it);
4783 }
4784
4785
4786 /* Compare two overlay_entry structures E1 and E2. Used as a
4787 comparison function for qsort in load_overlay_strings. Overlay
4788 strings for the same position are sorted so that
4789
4790 1. All after-strings come in front of before-strings, except
4791 when they come from the same overlay.
4792
4793 2. Within after-strings, strings are sorted so that overlay strings
4794 from overlays with higher priorities come first.
4795
4796 2. Within before-strings, strings are sorted so that overlay
4797 strings from overlays with higher priorities come last.
4798
4799 Value is analogous to strcmp. */
4800
4801
4802 static int
4803 compare_overlay_entries (e1, e2)
4804 void *e1, *e2;
4805 {
4806 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4807 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4808 int result;
4809
4810 if (entry1->after_string_p != entry2->after_string_p)
4811 {
4812 /* Let after-strings appear in front of before-strings if
4813 they come from different overlays. */
4814 if (EQ (entry1->overlay, entry2->overlay))
4815 result = entry1->after_string_p ? 1 : -1;
4816 else
4817 result = entry1->after_string_p ? -1 : 1;
4818 }
4819 else if (entry1->after_string_p)
4820 /* After-strings sorted in order of decreasing priority. */
4821 result = entry2->priority - entry1->priority;
4822 else
4823 /* Before-strings sorted in order of increasing priority. */
4824 result = entry1->priority - entry2->priority;
4825
4826 return result;
4827 }
4828
4829
4830 /* Load the vector IT->overlay_strings with overlay strings from IT's
4831 current buffer position, or from CHARPOS if that is > 0. Set
4832 IT->n_overlays to the total number of overlay strings found.
4833
4834 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4835 a time. On entry into load_overlay_strings,
4836 IT->current.overlay_string_index gives the number of overlay
4837 strings that have already been loaded by previous calls to this
4838 function.
4839
4840 IT->add_overlay_start contains an additional overlay start
4841 position to consider for taking overlay strings from, if non-zero.
4842 This position comes into play when the overlay has an `invisible'
4843 property, and both before and after-strings. When we've skipped to
4844 the end of the overlay, because of its `invisible' property, we
4845 nevertheless want its before-string to appear.
4846 IT->add_overlay_start will contain the overlay start position
4847 in this case.
4848
4849 Overlay strings are sorted so that after-string strings come in
4850 front of before-string strings. Within before and after-strings,
4851 strings are sorted by overlay priority. See also function
4852 compare_overlay_entries. */
4853
4854 static void
4855 load_overlay_strings (it, charpos)
4856 struct it *it;
4857 int charpos;
4858 {
4859 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4860 Lisp_Object overlay, window, str, invisible;
4861 struct Lisp_Overlay *ov;
4862 int start, end;
4863 int size = 20;
4864 int n = 0, i, j, invis_p;
4865 struct overlay_entry *entries
4866 = (struct overlay_entry *) alloca (size * sizeof *entries);
4867
4868 if (charpos <= 0)
4869 charpos = IT_CHARPOS (*it);
4870
4871 /* Append the overlay string STRING of overlay OVERLAY to vector
4872 `entries' which has size `size' and currently contains `n'
4873 elements. AFTER_P non-zero means STRING is an after-string of
4874 OVERLAY. */
4875 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4876 do \
4877 { \
4878 Lisp_Object priority; \
4879 \
4880 if (n == size) \
4881 { \
4882 int new_size = 2 * size; \
4883 struct overlay_entry *old = entries; \
4884 entries = \
4885 (struct overlay_entry *) alloca (new_size \
4886 * sizeof *entries); \
4887 bcopy (old, entries, size * sizeof *entries); \
4888 size = new_size; \
4889 } \
4890 \
4891 entries[n].string = (STRING); \
4892 entries[n].overlay = (OVERLAY); \
4893 priority = Foverlay_get ((OVERLAY), Qpriority); \
4894 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4895 entries[n].after_string_p = (AFTER_P); \
4896 ++n; \
4897 } \
4898 while (0)
4899
4900 /* Process overlay before the overlay center. */
4901 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4902 {
4903 XSETMISC (overlay, ov);
4904 xassert (OVERLAYP (overlay));
4905 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4906 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4907
4908 if (end < charpos)
4909 break;
4910
4911 /* Skip this overlay if it doesn't start or end at IT's current
4912 position. */
4913 if (end != charpos && start != charpos)
4914 continue;
4915
4916 /* Skip this overlay if it doesn't apply to IT->w. */
4917 window = Foverlay_get (overlay, Qwindow);
4918 if (WINDOWP (window) && XWINDOW (window) != it->w)
4919 continue;
4920
4921 /* If the text ``under'' the overlay is invisible, both before-
4922 and after-strings from this overlay are visible; start and
4923 end position are indistinguishable. */
4924 invisible = Foverlay_get (overlay, Qinvisible);
4925 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4926
4927 /* If overlay has a non-empty before-string, record it. */
4928 if ((start == charpos || (end == charpos && invis_p))
4929 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4930 && SCHARS (str))
4931 RECORD_OVERLAY_STRING (overlay, str, 0);
4932
4933 /* If overlay has a non-empty after-string, record it. */
4934 if ((end == charpos || (start == charpos && invis_p))
4935 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4936 && SCHARS (str))
4937 RECORD_OVERLAY_STRING (overlay, str, 1);
4938 }
4939
4940 /* Process overlays after the overlay center. */
4941 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4942 {
4943 XSETMISC (overlay, ov);
4944 xassert (OVERLAYP (overlay));
4945 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4946 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4947
4948 if (start > charpos)
4949 break;
4950
4951 /* Skip this overlay if it doesn't start or end at IT's current
4952 position. */
4953 if (end != charpos && start != charpos)
4954 continue;
4955
4956 /* Skip this overlay if it doesn't apply to IT->w. */
4957 window = Foverlay_get (overlay, Qwindow);
4958 if (WINDOWP (window) && XWINDOW (window) != it->w)
4959 continue;
4960
4961 /* If the text ``under'' the overlay is invisible, it has a zero
4962 dimension, and both before- and after-strings apply. */
4963 invisible = Foverlay_get (overlay, Qinvisible);
4964 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4965
4966 /* If overlay has a non-empty before-string, record it. */
4967 if ((start == charpos || (end == charpos && invis_p))
4968 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4969 && SCHARS (str))
4970 RECORD_OVERLAY_STRING (overlay, str, 0);
4971
4972 /* If overlay has a non-empty after-string, record it. */
4973 if ((end == charpos || (start == charpos && invis_p))
4974 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4975 && SCHARS (str))
4976 RECORD_OVERLAY_STRING (overlay, str, 1);
4977 }
4978
4979 #undef RECORD_OVERLAY_STRING
4980
4981 /* Sort entries. */
4982 if (n > 1)
4983 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4984
4985 /* Record the total number of strings to process. */
4986 it->n_overlay_strings = n;
4987
4988 /* IT->current.overlay_string_index is the number of overlay strings
4989 that have already been consumed by IT. Copy some of the
4990 remaining overlay strings to IT->overlay_strings. */
4991 i = 0;
4992 j = it->current.overlay_string_index;
4993 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4994 it->overlay_strings[i++] = entries[j++].string;
4995
4996 CHECK_IT (it);
4997 }
4998
4999
5000 /* Get the first chunk of overlay strings at IT's current buffer
5001 position, or at CHARPOS if that is > 0. Value is non-zero if at
5002 least one overlay string was found. */
5003
5004 static int
5005 get_overlay_strings_1 (it, charpos, compute_stop_p)
5006 struct it *it;
5007 int charpos;
5008 {
5009 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5010 process. This fills IT->overlay_strings with strings, and sets
5011 IT->n_overlay_strings to the total number of strings to process.
5012 IT->pos.overlay_string_index has to be set temporarily to zero
5013 because load_overlay_strings needs this; it must be set to -1
5014 when no overlay strings are found because a zero value would
5015 indicate a position in the first overlay string. */
5016 it->current.overlay_string_index = 0;
5017 load_overlay_strings (it, charpos);
5018
5019 /* If we found overlay strings, set up IT to deliver display
5020 elements from the first one. Otherwise set up IT to deliver
5021 from current_buffer. */
5022 if (it->n_overlay_strings)
5023 {
5024 /* Make sure we know settings in current_buffer, so that we can
5025 restore meaningful values when we're done with the overlay
5026 strings. */
5027 if (compute_stop_p)
5028 compute_stop_pos (it);
5029 xassert (it->face_id >= 0);
5030
5031 /* Save IT's settings. They are restored after all overlay
5032 strings have been processed. */
5033 xassert (!compute_stop_p || it->sp == 0);
5034 push_it (it);
5035
5036 /* Set up IT to deliver display elements from the first overlay
5037 string. */
5038 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5039 it->string = it->overlay_strings[0];
5040 it->stop_charpos = 0;
5041 xassert (STRINGP (it->string));
5042 it->end_charpos = SCHARS (it->string);
5043 it->multibyte_p = STRING_MULTIBYTE (it->string);
5044 it->method = GET_FROM_STRING;
5045 return 1;
5046 }
5047
5048 it->current.overlay_string_index = -1;
5049 return 0;
5050 }
5051
5052 static int
5053 get_overlay_strings (it, charpos)
5054 struct it *it;
5055 int charpos;
5056 {
5057 it->string = Qnil;
5058 it->method = GET_FROM_BUFFER;
5059
5060 (void) get_overlay_strings_1 (it, charpos, 1);
5061
5062 CHECK_IT (it);
5063
5064 /* Value is non-zero if we found at least one overlay string. */
5065 return STRINGP (it->string);
5066 }
5067
5068
5069 \f
5070 /***********************************************************************
5071 Saving and restoring state
5072 ***********************************************************************/
5073
5074 /* Save current settings of IT on IT->stack. Called, for example,
5075 before setting up IT for an overlay string, to be able to restore
5076 IT's settings to what they were after the overlay string has been
5077 processed. */
5078
5079 static void
5080 push_it (it)
5081 struct it *it;
5082 {
5083 struct iterator_stack_entry *p;
5084
5085 xassert (it->sp < IT_STACK_SIZE);
5086 p = it->stack + it->sp;
5087
5088 p->stop_charpos = it->stop_charpos;
5089 xassert (it->face_id >= 0);
5090 p->face_id = it->face_id;
5091 p->string = it->string;
5092 p->method = it->method;
5093 switch (p->method)
5094 {
5095 case GET_FROM_IMAGE:
5096 p->u.image.object = it->object;
5097 p->u.image.image_id = it->image_id;
5098 p->u.image.slice = it->slice;
5099 break;
5100 case GET_FROM_COMPOSITION:
5101 p->u.comp.object = it->object;
5102 p->u.comp.c = it->c;
5103 p->u.comp.len = it->len;
5104 p->u.comp.cmp_id = it->cmp_id;
5105 p->u.comp.cmp_len = it->cmp_len;
5106 break;
5107 case GET_FROM_STRETCH:
5108 p->u.stretch.object = it->object;
5109 break;
5110 }
5111 p->position = it->position;
5112 p->current = it->current;
5113 p->end_charpos = it->end_charpos;
5114 p->string_nchars = it->string_nchars;
5115 p->area = it->area;
5116 p->multibyte_p = it->multibyte_p;
5117 p->space_width = it->space_width;
5118 p->font_height = it->font_height;
5119 p->voffset = it->voffset;
5120 p->string_from_display_prop_p = it->string_from_display_prop_p;
5121 p->display_ellipsis_p = 0;
5122 ++it->sp;
5123 }
5124
5125
5126 /* Restore IT's settings from IT->stack. Called, for example, when no
5127 more overlay strings must be processed, and we return to delivering
5128 display elements from a buffer, or when the end of a string from a
5129 `display' property is reached and we return to delivering display
5130 elements from an overlay string, or from a buffer. */
5131
5132 static void
5133 pop_it (it)
5134 struct it *it;
5135 {
5136 struct iterator_stack_entry *p;
5137
5138 xassert (it->sp > 0);
5139 --it->sp;
5140 p = it->stack + it->sp;
5141 it->stop_charpos = p->stop_charpos;
5142 it->face_id = p->face_id;
5143 it->current = p->current;
5144 it->position = p->position;
5145 it->string = p->string;
5146 if (NILP (it->string))
5147 SET_TEXT_POS (it->current.string_pos, -1, -1);
5148 it->method = p->method;
5149 switch (it->method)
5150 {
5151 case GET_FROM_IMAGE:
5152 it->image_id = p->u.image.image_id;
5153 it->object = p->u.image.object;
5154 it->slice = p->u.image.slice;
5155 break;
5156 case GET_FROM_COMPOSITION:
5157 it->object = p->u.comp.object;
5158 it->c = p->u.comp.c;
5159 it->len = p->u.comp.len;
5160 it->cmp_id = p->u.comp.cmp_id;
5161 it->cmp_len = p->u.comp.cmp_len;
5162 break;
5163 case GET_FROM_STRETCH:
5164 it->object = p->u.comp.object;
5165 break;
5166 case GET_FROM_BUFFER:
5167 it->object = it->w->buffer;
5168 break;
5169 case GET_FROM_STRING:
5170 it->object = it->string;
5171 break;
5172 }
5173 it->end_charpos = p->end_charpos;
5174 it->string_nchars = p->string_nchars;
5175 it->area = p->area;
5176 it->multibyte_p = p->multibyte_p;
5177 it->space_width = p->space_width;
5178 it->font_height = p->font_height;
5179 it->voffset = p->voffset;
5180 it->string_from_display_prop_p = p->string_from_display_prop_p;
5181 }
5182
5183
5184 \f
5185 /***********************************************************************
5186 Moving over lines
5187 ***********************************************************************/
5188
5189 /* Set IT's current position to the previous line start. */
5190
5191 static void
5192 back_to_previous_line_start (it)
5193 struct it *it;
5194 {
5195 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5196 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5197 }
5198
5199
5200 /* Move IT to the next line start.
5201
5202 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5203 we skipped over part of the text (as opposed to moving the iterator
5204 continuously over the text). Otherwise, don't change the value
5205 of *SKIPPED_P.
5206
5207 Newlines may come from buffer text, overlay strings, or strings
5208 displayed via the `display' property. That's the reason we can't
5209 simply use find_next_newline_no_quit.
5210
5211 Note that this function may not skip over invisible text that is so
5212 because of text properties and immediately follows a newline. If
5213 it would, function reseat_at_next_visible_line_start, when called
5214 from set_iterator_to_next, would effectively make invisible
5215 characters following a newline part of the wrong glyph row, which
5216 leads to wrong cursor motion. */
5217
5218 static int
5219 forward_to_next_line_start (it, skipped_p)
5220 struct it *it;
5221 int *skipped_p;
5222 {
5223 int old_selective, newline_found_p, n;
5224 const int MAX_NEWLINE_DISTANCE = 500;
5225
5226 /* If already on a newline, just consume it to avoid unintended
5227 skipping over invisible text below. */
5228 if (it->what == IT_CHARACTER
5229 && it->c == '\n'
5230 && CHARPOS (it->position) == IT_CHARPOS (*it))
5231 {
5232 set_iterator_to_next (it, 0);
5233 it->c = 0;
5234 return 1;
5235 }
5236
5237 /* Don't handle selective display in the following. It's (a)
5238 unnecessary because it's done by the caller, and (b) leads to an
5239 infinite recursion because next_element_from_ellipsis indirectly
5240 calls this function. */
5241 old_selective = it->selective;
5242 it->selective = 0;
5243
5244 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5245 from buffer text. */
5246 for (n = newline_found_p = 0;
5247 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5248 n += STRINGP (it->string) ? 0 : 1)
5249 {
5250 if (!get_next_display_element (it))
5251 return 0;
5252 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5253 set_iterator_to_next (it, 0);
5254 }
5255
5256 /* If we didn't find a newline near enough, see if we can use a
5257 short-cut. */
5258 if (!newline_found_p)
5259 {
5260 int start = IT_CHARPOS (*it);
5261 int limit = find_next_newline_no_quit (start, 1);
5262 Lisp_Object pos;
5263
5264 xassert (!STRINGP (it->string));
5265
5266 /* If there isn't any `display' property in sight, and no
5267 overlays, we can just use the position of the newline in
5268 buffer text. */
5269 if (it->stop_charpos >= limit
5270 || ((pos = Fnext_single_property_change (make_number (start),
5271 Qdisplay,
5272 Qnil, make_number (limit)),
5273 NILP (pos))
5274 && next_overlay_change (start) == ZV))
5275 {
5276 IT_CHARPOS (*it) = limit;
5277 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5278 *skipped_p = newline_found_p = 1;
5279 }
5280 else
5281 {
5282 while (get_next_display_element (it)
5283 && !newline_found_p)
5284 {
5285 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5286 set_iterator_to_next (it, 0);
5287 }
5288 }
5289 }
5290
5291 it->selective = old_selective;
5292 return newline_found_p;
5293 }
5294
5295
5296 /* Set IT's current position to the previous visible line start. Skip
5297 invisible text that is so either due to text properties or due to
5298 selective display. Caution: this does not change IT->current_x and
5299 IT->hpos. */
5300
5301 static void
5302 back_to_previous_visible_line_start (it)
5303 struct it *it;
5304 {
5305 while (IT_CHARPOS (*it) > BEGV)
5306 {
5307 back_to_previous_line_start (it);
5308
5309 if (IT_CHARPOS (*it) <= BEGV)
5310 break;
5311
5312 /* If selective > 0, then lines indented more than that values
5313 are invisible. */
5314 if (it->selective > 0
5315 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5316 (double) it->selective)) /* iftc */
5317 continue;
5318
5319 /* Check the newline before point for invisibility. */
5320 {
5321 Lisp_Object prop;
5322 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5323 Qinvisible, it->window);
5324 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5325 continue;
5326 }
5327
5328 if (IT_CHARPOS (*it) <= BEGV)
5329 break;
5330
5331 {
5332 struct it it2;
5333 int pos;
5334 int beg, end;
5335 Lisp_Object val, overlay;
5336
5337 /* If newline is part of a composition, continue from start of composition */
5338 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5339 && beg < IT_CHARPOS (*it))
5340 goto replaced;
5341
5342 /* If newline is replaced by a display property, find start of overlay
5343 or interval and continue search from that point. */
5344 it2 = *it;
5345 pos = --IT_CHARPOS (it2);
5346 --IT_BYTEPOS (it2);
5347 it2.sp = 0;
5348 if (handle_display_prop (&it2) == HANDLED_RETURN
5349 && !NILP (val = get_char_property_and_overlay
5350 (make_number (pos), Qdisplay, Qnil, &overlay))
5351 && (OVERLAYP (overlay)
5352 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5353 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5354 goto replaced;
5355
5356 /* Newline is not replaced by anything -- so we are done. */
5357 break;
5358
5359 replaced:
5360 if (beg < BEGV)
5361 beg = BEGV;
5362 IT_CHARPOS (*it) = beg;
5363 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5364 }
5365 }
5366
5367 it->continuation_lines_width = 0;
5368
5369 xassert (IT_CHARPOS (*it) >= BEGV);
5370 xassert (IT_CHARPOS (*it) == BEGV
5371 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5372 CHECK_IT (it);
5373 }
5374
5375
5376 /* Reseat iterator IT at the previous visible line start. Skip
5377 invisible text that is so either due to text properties or due to
5378 selective display. At the end, update IT's overlay information,
5379 face information etc. */
5380
5381 void
5382 reseat_at_previous_visible_line_start (it)
5383 struct it *it;
5384 {
5385 back_to_previous_visible_line_start (it);
5386 reseat (it, it->current.pos, 1);
5387 CHECK_IT (it);
5388 }
5389
5390
5391 /* Reseat iterator IT on the next visible line start in the current
5392 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5393 preceding the line start. Skip over invisible text that is so
5394 because of selective display. Compute faces, overlays etc at the
5395 new position. Note that this function does not skip over text that
5396 is invisible because of text properties. */
5397
5398 static void
5399 reseat_at_next_visible_line_start (it, on_newline_p)
5400 struct it *it;
5401 int on_newline_p;
5402 {
5403 int newline_found_p, skipped_p = 0;
5404
5405 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5406
5407 /* Skip over lines that are invisible because they are indented
5408 more than the value of IT->selective. */
5409 if (it->selective > 0)
5410 while (IT_CHARPOS (*it) < ZV
5411 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5412 (double) it->selective)) /* iftc */
5413 {
5414 xassert (IT_BYTEPOS (*it) == BEGV
5415 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5416 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5417 }
5418
5419 /* Position on the newline if that's what's requested. */
5420 if (on_newline_p && newline_found_p)
5421 {
5422 if (STRINGP (it->string))
5423 {
5424 if (IT_STRING_CHARPOS (*it) > 0)
5425 {
5426 --IT_STRING_CHARPOS (*it);
5427 --IT_STRING_BYTEPOS (*it);
5428 }
5429 }
5430 else if (IT_CHARPOS (*it) > BEGV)
5431 {
5432 --IT_CHARPOS (*it);
5433 --IT_BYTEPOS (*it);
5434 reseat (it, it->current.pos, 0);
5435 }
5436 }
5437 else if (skipped_p)
5438 reseat (it, it->current.pos, 0);
5439
5440 CHECK_IT (it);
5441 }
5442
5443
5444 \f
5445 /***********************************************************************
5446 Changing an iterator's position
5447 ***********************************************************************/
5448
5449 /* Change IT's current position to POS in current_buffer. If FORCE_P
5450 is non-zero, always check for text properties at the new position.
5451 Otherwise, text properties are only looked up if POS >=
5452 IT->check_charpos of a property. */
5453
5454 static void
5455 reseat (it, pos, force_p)
5456 struct it *it;
5457 struct text_pos pos;
5458 int force_p;
5459 {
5460 int original_pos = IT_CHARPOS (*it);
5461
5462 reseat_1 (it, pos, 0);
5463
5464 /* Determine where to check text properties. Avoid doing it
5465 where possible because text property lookup is very expensive. */
5466 if (force_p
5467 || CHARPOS (pos) > it->stop_charpos
5468 || CHARPOS (pos) < original_pos)
5469 handle_stop (it);
5470
5471 CHECK_IT (it);
5472 }
5473
5474
5475 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5476 IT->stop_pos to POS, also. */
5477
5478 static void
5479 reseat_1 (it, pos, set_stop_p)
5480 struct it *it;
5481 struct text_pos pos;
5482 int set_stop_p;
5483 {
5484 /* Don't call this function when scanning a C string. */
5485 xassert (it->s == NULL);
5486
5487 /* POS must be a reasonable value. */
5488 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5489
5490 it->current.pos = it->position = pos;
5491 it->end_charpos = ZV;
5492 it->dpvec = NULL;
5493 it->current.dpvec_index = -1;
5494 it->current.overlay_string_index = -1;
5495 IT_STRING_CHARPOS (*it) = -1;
5496 IT_STRING_BYTEPOS (*it) = -1;
5497 it->string = Qnil;
5498 it->method = GET_FROM_BUFFER;
5499 it->object = it->w->buffer;
5500 it->area = TEXT_AREA;
5501 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5502 it->sp = 0;
5503 it->string_from_display_prop_p = 0;
5504 it->face_before_selective_p = 0;
5505
5506 if (set_stop_p)
5507 it->stop_charpos = CHARPOS (pos);
5508 }
5509
5510
5511 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5512 If S is non-null, it is a C string to iterate over. Otherwise,
5513 STRING gives a Lisp string to iterate over.
5514
5515 If PRECISION > 0, don't return more then PRECISION number of
5516 characters from the string.
5517
5518 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5519 characters have been returned. FIELD_WIDTH < 0 means an infinite
5520 field width.
5521
5522 MULTIBYTE = 0 means disable processing of multibyte characters,
5523 MULTIBYTE > 0 means enable it,
5524 MULTIBYTE < 0 means use IT->multibyte_p.
5525
5526 IT must be initialized via a prior call to init_iterator before
5527 calling this function. */
5528
5529 static void
5530 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5531 struct it *it;
5532 unsigned char *s;
5533 Lisp_Object string;
5534 int charpos;
5535 int precision, field_width, multibyte;
5536 {
5537 /* No region in strings. */
5538 it->region_beg_charpos = it->region_end_charpos = -1;
5539
5540 /* No text property checks performed by default, but see below. */
5541 it->stop_charpos = -1;
5542
5543 /* Set iterator position and end position. */
5544 bzero (&it->current, sizeof it->current);
5545 it->current.overlay_string_index = -1;
5546 it->current.dpvec_index = -1;
5547 xassert (charpos >= 0);
5548
5549 /* If STRING is specified, use its multibyteness, otherwise use the
5550 setting of MULTIBYTE, if specified. */
5551 if (multibyte >= 0)
5552 it->multibyte_p = multibyte > 0;
5553
5554 if (s == NULL)
5555 {
5556 xassert (STRINGP (string));
5557 it->string = string;
5558 it->s = NULL;
5559 it->end_charpos = it->string_nchars = SCHARS (string);
5560 it->method = GET_FROM_STRING;
5561 it->current.string_pos = string_pos (charpos, string);
5562 }
5563 else
5564 {
5565 it->s = s;
5566 it->string = Qnil;
5567
5568 /* Note that we use IT->current.pos, not it->current.string_pos,
5569 for displaying C strings. */
5570 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5571 if (it->multibyte_p)
5572 {
5573 it->current.pos = c_string_pos (charpos, s, 1);
5574 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5575 }
5576 else
5577 {
5578 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5579 it->end_charpos = it->string_nchars = strlen (s);
5580 }
5581
5582 it->method = GET_FROM_C_STRING;
5583 }
5584
5585 /* PRECISION > 0 means don't return more than PRECISION characters
5586 from the string. */
5587 if (precision > 0 && it->end_charpos - charpos > precision)
5588 it->end_charpos = it->string_nchars = charpos + precision;
5589
5590 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5591 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5592 FIELD_WIDTH < 0 means infinite field width. This is useful for
5593 padding with `-' at the end of a mode line. */
5594 if (field_width < 0)
5595 field_width = INFINITY;
5596 if (field_width > it->end_charpos - charpos)
5597 it->end_charpos = charpos + field_width;
5598
5599 /* Use the standard display table for displaying strings. */
5600 if (DISP_TABLE_P (Vstandard_display_table))
5601 it->dp = XCHAR_TABLE (Vstandard_display_table);
5602
5603 it->stop_charpos = charpos;
5604 CHECK_IT (it);
5605 }
5606
5607
5608 \f
5609 /***********************************************************************
5610 Iteration
5611 ***********************************************************************/
5612
5613 /* Map enum it_method value to corresponding next_element_from_* function. */
5614
5615 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5616 {
5617 next_element_from_buffer,
5618 next_element_from_display_vector,
5619 next_element_from_composition,
5620 next_element_from_string,
5621 next_element_from_c_string,
5622 next_element_from_image,
5623 next_element_from_stretch
5624 };
5625
5626
5627 /* Load IT's display element fields with information about the next
5628 display element from the current position of IT. Value is zero if
5629 end of buffer (or C string) is reached. */
5630
5631 static struct frame *last_escape_glyph_frame = NULL;
5632 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5633 static int last_escape_glyph_merged_face_id = 0;
5634
5635 int
5636 get_next_display_element (it)
5637 struct it *it;
5638 {
5639 /* Non-zero means that we found a display element. Zero means that
5640 we hit the end of what we iterate over. Performance note: the
5641 function pointer `method' used here turns out to be faster than
5642 using a sequence of if-statements. */
5643 int success_p;
5644
5645 get_next:
5646 success_p = (*get_next_element[it->method]) (it);
5647
5648 if (it->what == IT_CHARACTER)
5649 {
5650 /* Map via display table or translate control characters.
5651 IT->c, IT->len etc. have been set to the next character by
5652 the function call above. If we have a display table, and it
5653 contains an entry for IT->c, translate it. Don't do this if
5654 IT->c itself comes from a display table, otherwise we could
5655 end up in an infinite recursion. (An alternative could be to
5656 count the recursion depth of this function and signal an
5657 error when a certain maximum depth is reached.) Is it worth
5658 it? */
5659 if (success_p && it->dpvec == NULL)
5660 {
5661 Lisp_Object dv;
5662
5663 if (it->dp
5664 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5665 VECTORP (dv)))
5666 {
5667 struct Lisp_Vector *v = XVECTOR (dv);
5668
5669 /* Return the first character from the display table
5670 entry, if not empty. If empty, don't display the
5671 current character. */
5672 if (v->size)
5673 {
5674 it->dpvec_char_len = it->len;
5675 it->dpvec = v->contents;
5676 it->dpend = v->contents + v->size;
5677 it->current.dpvec_index = 0;
5678 it->dpvec_face_id = -1;
5679 it->saved_face_id = it->face_id;
5680 it->method = GET_FROM_DISPLAY_VECTOR;
5681 it->ellipsis_p = 0;
5682 }
5683 else
5684 {
5685 set_iterator_to_next (it, 0);
5686 }
5687 goto get_next;
5688 }
5689
5690 /* Translate control characters into `\003' or `^C' form.
5691 Control characters coming from a display table entry are
5692 currently not translated because we use IT->dpvec to hold
5693 the translation. This could easily be changed but I
5694 don't believe that it is worth doing.
5695
5696 If it->multibyte_p is nonzero, non-printable non-ASCII
5697 characters are also translated to octal form.
5698
5699 If it->multibyte_p is zero, eight-bit characters that
5700 don't have corresponding multibyte char code are also
5701 translated to octal form. */
5702 else if ((it->c < ' '
5703 ? (it->area != TEXT_AREA
5704 /* In mode line, treat \n, \t like other crl chars. */
5705 || (it->c != '\t'
5706 && it->glyph_row && it->glyph_row->mode_line_p)
5707 || (it->c != '\n' && it->c != '\t'))
5708 : (it->multibyte_p
5709 ? (!CHAR_PRINTABLE_P (it->c)
5710 || (!NILP (Vnobreak_char_display)
5711 && (it->c == 0xA0 /* NO-BREAK SPACE */
5712 || it->c == 0xAD /* SOFT HYPHEN */)))
5713 : (it->c >= 127
5714 && (! unibyte_display_via_language_environment
5715 || (UNIBYTE_CHAR_HAS_MULTIBYTE_P (it->c)))))))
5716 {
5717 /* IT->c is a control character which must be displayed
5718 either as '\003' or as `^C' where the '\\' and '^'
5719 can be defined in the display table. Fill
5720 IT->ctl_chars with glyphs for what we have to
5721 display. Then, set IT->dpvec to these glyphs. */
5722 GLYPH g;
5723 int ctl_len;
5724 int face_id, lface_id = 0 ;
5725 GLYPH escape_glyph;
5726
5727 /* Handle control characters with ^. */
5728
5729 if (it->c < 128 && it->ctl_arrow_p)
5730 {
5731 g = '^'; /* default glyph for Control */
5732 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5733 if (it->dp
5734 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5735 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5736 {
5737 g = XINT (DISP_CTRL_GLYPH (it->dp));
5738 lface_id = FAST_GLYPH_FACE (g);
5739 }
5740 if (lface_id)
5741 {
5742 g = FAST_GLYPH_CHAR (g);
5743 face_id = merge_faces (it->f, Qt, lface_id,
5744 it->face_id);
5745 }
5746 else if (it->f == last_escape_glyph_frame
5747 && it->face_id == last_escape_glyph_face_id)
5748 {
5749 face_id = last_escape_glyph_merged_face_id;
5750 }
5751 else
5752 {
5753 /* Merge the escape-glyph face into the current face. */
5754 face_id = merge_faces (it->f, Qescape_glyph, 0,
5755 it->face_id);
5756 last_escape_glyph_frame = it->f;
5757 last_escape_glyph_face_id = it->face_id;
5758 last_escape_glyph_merged_face_id = face_id;
5759 }
5760
5761 XSETINT (it->ctl_chars[0], g);
5762 g = it->c ^ 0100;
5763 XSETINT (it->ctl_chars[1], g);
5764 ctl_len = 2;
5765 goto display_control;
5766 }
5767
5768 /* Handle non-break space in the mode where it only gets
5769 highlighting. */
5770
5771 if (EQ (Vnobreak_char_display, Qt)
5772 && it->c == 0xA0)
5773 {
5774 /* Merge the no-break-space face into the current face. */
5775 face_id = merge_faces (it->f, Qnobreak_space, 0,
5776 it->face_id);
5777
5778 g = it->c = ' ';
5779 XSETINT (it->ctl_chars[0], g);
5780 ctl_len = 1;
5781 goto display_control;
5782 }
5783
5784 /* Handle sequences that start with the "escape glyph". */
5785
5786 /* the default escape glyph is \. */
5787 escape_glyph = '\\';
5788
5789 if (it->dp
5790 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5791 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5792 {
5793 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5794 lface_id = FAST_GLYPH_FACE (escape_glyph);
5795 }
5796 if (lface_id)
5797 {
5798 /* The display table specified a face.
5799 Merge it into face_id and also into escape_glyph. */
5800 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5801 face_id = merge_faces (it->f, Qt, lface_id,
5802 it->face_id);
5803 }
5804 else if (it->f == last_escape_glyph_frame
5805 && it->face_id == last_escape_glyph_face_id)
5806 {
5807 face_id = last_escape_glyph_merged_face_id;
5808 }
5809 else
5810 {
5811 /* Merge the escape-glyph face into the current face. */
5812 face_id = merge_faces (it->f, Qescape_glyph, 0,
5813 it->face_id);
5814 last_escape_glyph_frame = it->f;
5815 last_escape_glyph_face_id = it->face_id;
5816 last_escape_glyph_merged_face_id = face_id;
5817 }
5818
5819 /* Handle soft hyphens in the mode where they only get
5820 highlighting. */
5821
5822 if (EQ (Vnobreak_char_display, Qt)
5823 && it->c == 0xAD)
5824 {
5825 g = it->c = '-';
5826 XSETINT (it->ctl_chars[0], g);
5827 ctl_len = 1;
5828 goto display_control;
5829 }
5830
5831 /* Handle non-break space and soft hyphen
5832 with the escape glyph. */
5833
5834 if (it->c == 0xA0 || it->c == 0xAD)
5835 {
5836 XSETINT (it->ctl_chars[0], escape_glyph);
5837 g = it->c = (it->c == 0xA0 ? ' ' : '-');
5838 XSETINT (it->ctl_chars[1], g);
5839 ctl_len = 2;
5840 goto display_control;
5841 }
5842
5843 {
5844 unsigned char str[MAX_MULTIBYTE_LENGTH];
5845 int len;
5846 int i;
5847
5848 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5849 if (CHAR_BYTE8_P (it->c))
5850 {
5851 str[0] = CHAR_TO_BYTE8 (it->c);
5852 len = 1;
5853 }
5854 else if (it->c < 256)
5855 {
5856 str[0] = it->c;
5857 len = 1;
5858 }
5859 else
5860 {
5861 /* It's an invalid character, which shouldn't
5862 happen actually, but due to bugs it may
5863 happen. Let's print the char as is, there's
5864 not much meaningful we can do with it. */
5865 str[0] = it->c;
5866 str[1] = it->c >> 8;
5867 str[2] = it->c >> 16;
5868 str[3] = it->c >> 24;
5869 len = 4;
5870 }
5871
5872 for (i = 0; i < len; i++)
5873 {
5874 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5875 /* Insert three more glyphs into IT->ctl_chars for
5876 the octal display of the character. */
5877 g = ((str[i] >> 6) & 7) + '0';
5878 XSETINT (it->ctl_chars[i * 4 + 1], g);
5879 g = ((str[i] >> 3) & 7) + '0';
5880 XSETINT (it->ctl_chars[i * 4 + 2], g);
5881 g = (str[i] & 7) + '0';
5882 XSETINT (it->ctl_chars[i * 4 + 3], g);
5883 }
5884 ctl_len = len * 4;
5885 }
5886
5887 display_control:
5888 /* Set up IT->dpvec and return first character from it. */
5889 it->dpvec_char_len = it->len;
5890 it->dpvec = it->ctl_chars;
5891 it->dpend = it->dpvec + ctl_len;
5892 it->current.dpvec_index = 0;
5893 it->dpvec_face_id = face_id;
5894 it->saved_face_id = it->face_id;
5895 it->method = GET_FROM_DISPLAY_VECTOR;
5896 it->ellipsis_p = 0;
5897 goto get_next;
5898 }
5899 }
5900 }
5901
5902 /* Adjust face id for a multibyte character. There are no multibyte
5903 character in unibyte text. */
5904 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
5905 && it->multibyte_p
5906 && success_p
5907 && FRAME_WINDOW_P (it->f))
5908 {
5909 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5910 int pos = (it->s ? -1
5911 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
5912 : IT_CHARPOS (*it));
5913
5914 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
5915 }
5916
5917 /* Is this character the last one of a run of characters with
5918 box? If yes, set IT->end_of_box_run_p to 1. */
5919 if (it->face_box_p
5920 && it->s == NULL)
5921 {
5922 int face_id;
5923 struct face *face;
5924
5925 it->end_of_box_run_p
5926 = ((face_id = face_after_it_pos (it),
5927 face_id != it->face_id)
5928 && (face = FACE_FROM_ID (it->f, face_id),
5929 face->box == FACE_NO_BOX));
5930 }
5931
5932 /* Value is 0 if end of buffer or string reached. */
5933 return success_p;
5934 }
5935
5936
5937 /* Move IT to the next display element.
5938
5939 RESEAT_P non-zero means if called on a newline in buffer text,
5940 skip to the next visible line start.
5941
5942 Functions get_next_display_element and set_iterator_to_next are
5943 separate because I find this arrangement easier to handle than a
5944 get_next_display_element function that also increments IT's
5945 position. The way it is we can first look at an iterator's current
5946 display element, decide whether it fits on a line, and if it does,
5947 increment the iterator position. The other way around we probably
5948 would either need a flag indicating whether the iterator has to be
5949 incremented the next time, or we would have to implement a
5950 decrement position function which would not be easy to write. */
5951
5952 void
5953 set_iterator_to_next (it, reseat_p)
5954 struct it *it;
5955 int reseat_p;
5956 {
5957 /* Reset flags indicating start and end of a sequence of characters
5958 with box. Reset them at the start of this function because
5959 moving the iterator to a new position might set them. */
5960 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5961
5962 switch (it->method)
5963 {
5964 case GET_FROM_BUFFER:
5965 /* The current display element of IT is a character from
5966 current_buffer. Advance in the buffer, and maybe skip over
5967 invisible lines that are so because of selective display. */
5968 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5969 reseat_at_next_visible_line_start (it, 0);
5970 else
5971 {
5972 xassert (it->len != 0);
5973 IT_BYTEPOS (*it) += it->len;
5974 IT_CHARPOS (*it) += 1;
5975 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5976 }
5977 break;
5978
5979 case GET_FROM_COMPOSITION:
5980 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5981 xassert (it->sp > 0);
5982 pop_it (it);
5983 if (it->method == GET_FROM_STRING)
5984 {
5985 IT_STRING_BYTEPOS (*it) += it->len;
5986 IT_STRING_CHARPOS (*it) += it->cmp_len;
5987 goto consider_string_end;
5988 }
5989 else if (it->method == GET_FROM_BUFFER)
5990 {
5991 IT_BYTEPOS (*it) += it->len;
5992 IT_CHARPOS (*it) += it->cmp_len;
5993 }
5994 break;
5995
5996 case GET_FROM_C_STRING:
5997 /* Current display element of IT is from a C string. */
5998 IT_BYTEPOS (*it) += it->len;
5999 IT_CHARPOS (*it) += 1;
6000 break;
6001
6002 case GET_FROM_DISPLAY_VECTOR:
6003 /* Current display element of IT is from a display table entry.
6004 Advance in the display table definition. Reset it to null if
6005 end reached, and continue with characters from buffers/
6006 strings. */
6007 ++it->current.dpvec_index;
6008
6009 /* Restore face of the iterator to what they were before the
6010 display vector entry (these entries may contain faces). */
6011 it->face_id = it->saved_face_id;
6012
6013 if (it->dpvec + it->current.dpvec_index == it->dpend)
6014 {
6015 int recheck_faces = it->ellipsis_p;
6016
6017 if (it->s)
6018 it->method = GET_FROM_C_STRING;
6019 else if (STRINGP (it->string))
6020 it->method = GET_FROM_STRING;
6021 else
6022 {
6023 it->method = GET_FROM_BUFFER;
6024 it->object = it->w->buffer;
6025 }
6026
6027 it->dpvec = NULL;
6028 it->current.dpvec_index = -1;
6029
6030 /* Skip over characters which were displayed via IT->dpvec. */
6031 if (it->dpvec_char_len < 0)
6032 reseat_at_next_visible_line_start (it, 1);
6033 else if (it->dpvec_char_len > 0)
6034 {
6035 if (it->method == GET_FROM_STRING
6036 && it->n_overlay_strings > 0)
6037 it->ignore_overlay_strings_at_pos_p = 1;
6038 it->len = it->dpvec_char_len;
6039 set_iterator_to_next (it, reseat_p);
6040 }
6041
6042 /* Maybe recheck faces after display vector */
6043 if (recheck_faces)
6044 it->stop_charpos = IT_CHARPOS (*it);
6045 }
6046 break;
6047
6048 case GET_FROM_STRING:
6049 /* Current display element is a character from a Lisp string. */
6050 xassert (it->s == NULL && STRINGP (it->string));
6051 IT_STRING_BYTEPOS (*it) += it->len;
6052 IT_STRING_CHARPOS (*it) += 1;
6053
6054 consider_string_end:
6055
6056 if (it->current.overlay_string_index >= 0)
6057 {
6058 /* IT->string is an overlay string. Advance to the
6059 next, if there is one. */
6060 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6061 next_overlay_string (it);
6062 }
6063 else
6064 {
6065 /* IT->string is not an overlay string. If we reached
6066 its end, and there is something on IT->stack, proceed
6067 with what is on the stack. This can be either another
6068 string, this time an overlay string, or a buffer. */
6069 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6070 && it->sp > 0)
6071 {
6072 pop_it (it);
6073 if (it->method == GET_FROM_STRING)
6074 goto consider_string_end;
6075 }
6076 }
6077 break;
6078
6079 case GET_FROM_IMAGE:
6080 case GET_FROM_STRETCH:
6081 /* The position etc with which we have to proceed are on
6082 the stack. The position may be at the end of a string,
6083 if the `display' property takes up the whole string. */
6084 xassert (it->sp > 0);
6085 pop_it (it);
6086 if (it->method == GET_FROM_STRING)
6087 goto consider_string_end;
6088 break;
6089
6090 default:
6091 /* There are no other methods defined, so this should be a bug. */
6092 abort ();
6093 }
6094
6095 xassert (it->method != GET_FROM_STRING
6096 || (STRINGP (it->string)
6097 && IT_STRING_CHARPOS (*it) >= 0));
6098 }
6099
6100 /* Load IT's display element fields with information about the next
6101 display element which comes from a display table entry or from the
6102 result of translating a control character to one of the forms `^C'
6103 or `\003'.
6104
6105 IT->dpvec holds the glyphs to return as characters.
6106 IT->saved_face_id holds the face id before the display vector--
6107 it is restored into IT->face_idin set_iterator_to_next. */
6108
6109 static int
6110 next_element_from_display_vector (it)
6111 struct it *it;
6112 {
6113 /* Precondition. */
6114 xassert (it->dpvec && it->current.dpvec_index >= 0);
6115
6116 it->face_id = it->saved_face_id;
6117
6118 if (INTEGERP (*it->dpvec)
6119 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
6120 {
6121 GLYPH g;
6122
6123 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
6124 it->c = FAST_GLYPH_CHAR (g);
6125 it->len = CHAR_BYTES (it->c);
6126
6127 /* The entry may contain a face id to use. Such a face id is
6128 the id of a Lisp face, not a realized face. A face id of
6129 zero means no face is specified. */
6130 if (it->dpvec_face_id >= 0)
6131 it->face_id = it->dpvec_face_id;
6132 else
6133 {
6134 int lface_id = FAST_GLYPH_FACE (g);
6135 if (lface_id > 0)
6136 it->face_id = merge_faces (it->f, Qt, lface_id,
6137 it->saved_face_id);
6138 }
6139 }
6140 else
6141 /* Display table entry is invalid. Return a space. */
6142 it->c = ' ', it->len = 1;
6143
6144 /* Don't change position and object of the iterator here. They are
6145 still the values of the character that had this display table
6146 entry or was translated, and that's what we want. */
6147 it->what = IT_CHARACTER;
6148 return 1;
6149 }
6150
6151
6152 /* Load IT with the next display element from Lisp string IT->string.
6153 IT->current.string_pos is the current position within the string.
6154 If IT->current.overlay_string_index >= 0, the Lisp string is an
6155 overlay string. */
6156
6157 static int
6158 next_element_from_string (it)
6159 struct it *it;
6160 {
6161 struct text_pos position;
6162
6163 xassert (STRINGP (it->string));
6164 xassert (IT_STRING_CHARPOS (*it) >= 0);
6165 position = it->current.string_pos;
6166
6167 /* Time to check for invisible text? */
6168 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6169 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6170 {
6171 handle_stop (it);
6172
6173 /* Since a handler may have changed IT->method, we must
6174 recurse here. */
6175 return get_next_display_element (it);
6176 }
6177
6178 if (it->current.overlay_string_index >= 0)
6179 {
6180 /* Get the next character from an overlay string. In overlay
6181 strings, There is no field width or padding with spaces to
6182 do. */
6183 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6184 {
6185 it->what = IT_EOB;
6186 return 0;
6187 }
6188 else if (STRING_MULTIBYTE (it->string))
6189 {
6190 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6191 const unsigned char *s = (SDATA (it->string)
6192 + IT_STRING_BYTEPOS (*it));
6193 it->c = string_char_and_length (s, remaining, &it->len);
6194 }
6195 else
6196 {
6197 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6198 it->len = 1;
6199 }
6200 }
6201 else
6202 {
6203 /* Get the next character from a Lisp string that is not an
6204 overlay string. Such strings come from the mode line, for
6205 example. We may have to pad with spaces, or truncate the
6206 string. See also next_element_from_c_string. */
6207 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6208 {
6209 it->what = IT_EOB;
6210 return 0;
6211 }
6212 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6213 {
6214 /* Pad with spaces. */
6215 it->c = ' ', it->len = 1;
6216 CHARPOS (position) = BYTEPOS (position) = -1;
6217 }
6218 else if (STRING_MULTIBYTE (it->string))
6219 {
6220 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6221 const unsigned char *s = (SDATA (it->string)
6222 + IT_STRING_BYTEPOS (*it));
6223 it->c = string_char_and_length (s, maxlen, &it->len);
6224 }
6225 else
6226 {
6227 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6228 it->len = 1;
6229 }
6230 }
6231
6232 /* Record what we have and where it came from. */
6233 it->what = IT_CHARACTER;
6234 it->object = it->string;
6235 it->position = position;
6236 return 1;
6237 }
6238
6239
6240 /* Load IT with next display element from C string IT->s.
6241 IT->string_nchars is the maximum number of characters to return
6242 from the string. IT->end_charpos may be greater than
6243 IT->string_nchars when this function is called, in which case we
6244 may have to return padding spaces. Value is zero if end of string
6245 reached, including padding spaces. */
6246
6247 static int
6248 next_element_from_c_string (it)
6249 struct it *it;
6250 {
6251 int success_p = 1;
6252
6253 xassert (it->s);
6254 it->what = IT_CHARACTER;
6255 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6256 it->object = Qnil;
6257
6258 /* IT's position can be greater IT->string_nchars in case a field
6259 width or precision has been specified when the iterator was
6260 initialized. */
6261 if (IT_CHARPOS (*it) >= it->end_charpos)
6262 {
6263 /* End of the game. */
6264 it->what = IT_EOB;
6265 success_p = 0;
6266 }
6267 else if (IT_CHARPOS (*it) >= it->string_nchars)
6268 {
6269 /* Pad with spaces. */
6270 it->c = ' ', it->len = 1;
6271 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6272 }
6273 else if (it->multibyte_p)
6274 {
6275 /* Implementation note: The calls to strlen apparently aren't a
6276 performance problem because there is no noticeable performance
6277 difference between Emacs running in unibyte or multibyte mode. */
6278 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6279 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
6280 maxlen, &it->len);
6281 }
6282 else
6283 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6284
6285 return success_p;
6286 }
6287
6288
6289 /* Set up IT to return characters from an ellipsis, if appropriate.
6290 The definition of the ellipsis glyphs may come from a display table
6291 entry. This function Fills IT with the first glyph from the
6292 ellipsis if an ellipsis is to be displayed. */
6293
6294 static int
6295 next_element_from_ellipsis (it)
6296 struct it *it;
6297 {
6298 if (it->selective_display_ellipsis_p)
6299 setup_for_ellipsis (it, it->len);
6300 else
6301 {
6302 /* The face at the current position may be different from the
6303 face we find after the invisible text. Remember what it
6304 was in IT->saved_face_id, and signal that it's there by
6305 setting face_before_selective_p. */
6306 it->saved_face_id = it->face_id;
6307 it->method = GET_FROM_BUFFER;
6308 it->object = it->w->buffer;
6309 reseat_at_next_visible_line_start (it, 1);
6310 it->face_before_selective_p = 1;
6311 }
6312
6313 return get_next_display_element (it);
6314 }
6315
6316
6317 /* Deliver an image display element. The iterator IT is already
6318 filled with image information (done in handle_display_prop). Value
6319 is always 1. */
6320
6321
6322 static int
6323 next_element_from_image (it)
6324 struct it *it;
6325 {
6326 it->what = IT_IMAGE;
6327 return 1;
6328 }
6329
6330
6331 /* Fill iterator IT with next display element from a stretch glyph
6332 property. IT->object is the value of the text property. Value is
6333 always 1. */
6334
6335 static int
6336 next_element_from_stretch (it)
6337 struct it *it;
6338 {
6339 it->what = IT_STRETCH;
6340 return 1;
6341 }
6342
6343
6344 /* Load IT with the next display element from current_buffer. Value
6345 is zero if end of buffer reached. IT->stop_charpos is the next
6346 position at which to stop and check for text properties or buffer
6347 end. */
6348
6349 static int
6350 next_element_from_buffer (it)
6351 struct it *it;
6352 {
6353 int success_p = 1;
6354
6355 /* Check this assumption, otherwise, we would never enter the
6356 if-statement, below. */
6357 xassert (IT_CHARPOS (*it) >= BEGV
6358 && IT_CHARPOS (*it) <= it->stop_charpos);
6359
6360 if (IT_CHARPOS (*it) >= it->stop_charpos)
6361 {
6362 if (IT_CHARPOS (*it) >= it->end_charpos)
6363 {
6364 int overlay_strings_follow_p;
6365
6366 /* End of the game, except when overlay strings follow that
6367 haven't been returned yet. */
6368 if (it->overlay_strings_at_end_processed_p)
6369 overlay_strings_follow_p = 0;
6370 else
6371 {
6372 it->overlay_strings_at_end_processed_p = 1;
6373 overlay_strings_follow_p = get_overlay_strings (it, 0);
6374 }
6375
6376 if (overlay_strings_follow_p)
6377 success_p = get_next_display_element (it);
6378 else
6379 {
6380 it->what = IT_EOB;
6381 it->position = it->current.pos;
6382 success_p = 0;
6383 }
6384 }
6385 else
6386 {
6387 handle_stop (it);
6388 return get_next_display_element (it);
6389 }
6390 }
6391 else
6392 {
6393 /* No face changes, overlays etc. in sight, so just return a
6394 character from current_buffer. */
6395 unsigned char *p;
6396
6397 /* Maybe run the redisplay end trigger hook. Performance note:
6398 This doesn't seem to cost measurable time. */
6399 if (it->redisplay_end_trigger_charpos
6400 && it->glyph_row
6401 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6402 run_redisplay_end_trigger_hook (it);
6403
6404 /* Get the next character, maybe multibyte. */
6405 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6406 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6407 {
6408 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
6409 - IT_BYTEPOS (*it));
6410 it->c = string_char_and_length (p, maxlen, &it->len);
6411 }
6412 else
6413 it->c = *p, it->len = 1;
6414
6415 /* Record what we have and where it came from. */
6416 it->what = IT_CHARACTER;
6417 it->object = it->w->buffer;
6418 it->position = it->current.pos;
6419
6420 /* Normally we return the character found above, except when we
6421 really want to return an ellipsis for selective display. */
6422 if (it->selective)
6423 {
6424 if (it->c == '\n')
6425 {
6426 /* A value of selective > 0 means hide lines indented more
6427 than that number of columns. */
6428 if (it->selective > 0
6429 && IT_CHARPOS (*it) + 1 < ZV
6430 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6431 IT_BYTEPOS (*it) + 1,
6432 (double) it->selective)) /* iftc */
6433 {
6434 success_p = next_element_from_ellipsis (it);
6435 it->dpvec_char_len = -1;
6436 }
6437 }
6438 else if (it->c == '\r' && it->selective == -1)
6439 {
6440 /* A value of selective == -1 means that everything from the
6441 CR to the end of the line is invisible, with maybe an
6442 ellipsis displayed for it. */
6443 success_p = next_element_from_ellipsis (it);
6444 it->dpvec_char_len = -1;
6445 }
6446 }
6447 }
6448
6449 /* Value is zero if end of buffer reached. */
6450 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6451 return success_p;
6452 }
6453
6454
6455 /* Run the redisplay end trigger hook for IT. */
6456
6457 static void
6458 run_redisplay_end_trigger_hook (it)
6459 struct it *it;
6460 {
6461 Lisp_Object args[3];
6462
6463 /* IT->glyph_row should be non-null, i.e. we should be actually
6464 displaying something, or otherwise we should not run the hook. */
6465 xassert (it->glyph_row);
6466
6467 /* Set up hook arguments. */
6468 args[0] = Qredisplay_end_trigger_functions;
6469 args[1] = it->window;
6470 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6471 it->redisplay_end_trigger_charpos = 0;
6472
6473 /* Since we are *trying* to run these functions, don't try to run
6474 them again, even if they get an error. */
6475 it->w->redisplay_end_trigger = Qnil;
6476 Frun_hook_with_args (3, args);
6477
6478 /* Notice if it changed the face of the character we are on. */
6479 handle_face_prop (it);
6480 }
6481
6482
6483 /* Deliver a composition display element. The iterator IT is already
6484 filled with composition information (done in
6485 handle_composition_prop). Value is always 1. */
6486
6487 static int
6488 next_element_from_composition (it)
6489 struct it *it;
6490 {
6491 it->what = IT_COMPOSITION;
6492 it->position = (STRINGP (it->string)
6493 ? it->current.string_pos
6494 : it->current.pos);
6495 if (STRINGP (it->string))
6496 it->object = it->string;
6497 else
6498 it->object = it->w->buffer;
6499 return 1;
6500 }
6501
6502
6503 \f
6504 /***********************************************************************
6505 Moving an iterator without producing glyphs
6506 ***********************************************************************/
6507
6508 /* Check if iterator is at a position corresponding to a valid buffer
6509 position after some move_it_ call. */
6510
6511 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6512 ((it)->method == GET_FROM_STRING \
6513 ? IT_STRING_CHARPOS (*it) == 0 \
6514 : 1)
6515
6516
6517 /* Move iterator IT to a specified buffer or X position within one
6518 line on the display without producing glyphs.
6519
6520 OP should be a bit mask including some or all of these bits:
6521 MOVE_TO_X: Stop on reaching x-position TO_X.
6522 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
6523 Regardless of OP's value, stop in reaching the end of the display line.
6524
6525 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6526 This means, in particular, that TO_X includes window's horizontal
6527 scroll amount.
6528
6529 The return value has several possible values that
6530 say what condition caused the scan to stop:
6531
6532 MOVE_POS_MATCH_OR_ZV
6533 - when TO_POS or ZV was reached.
6534
6535 MOVE_X_REACHED
6536 -when TO_X was reached before TO_POS or ZV were reached.
6537
6538 MOVE_LINE_CONTINUED
6539 - when we reached the end of the display area and the line must
6540 be continued.
6541
6542 MOVE_LINE_TRUNCATED
6543 - when we reached the end of the display area and the line is
6544 truncated.
6545
6546 MOVE_NEWLINE_OR_CR
6547 - when we stopped at a line end, i.e. a newline or a CR and selective
6548 display is on. */
6549
6550 static enum move_it_result
6551 move_it_in_display_line_to (it, to_charpos, to_x, op)
6552 struct it *it;
6553 int to_charpos, to_x, op;
6554 {
6555 enum move_it_result result = MOVE_UNDEFINED;
6556 struct glyph_row *saved_glyph_row;
6557
6558 /* Don't produce glyphs in produce_glyphs. */
6559 saved_glyph_row = it->glyph_row;
6560 it->glyph_row = NULL;
6561
6562 #define BUFFER_POS_REACHED_P() \
6563 ((op & MOVE_TO_POS) != 0 \
6564 && BUFFERP (it->object) \
6565 && IT_CHARPOS (*it) >= to_charpos \
6566 && (it->method == GET_FROM_BUFFER \
6567 || (it->method == GET_FROM_DISPLAY_VECTOR \
6568 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6569
6570
6571 while (1)
6572 {
6573 int x, i, ascent = 0, descent = 0;
6574
6575 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
6576 if ((op & MOVE_TO_POS) != 0
6577 && BUFFERP (it->object)
6578 && it->method == GET_FROM_BUFFER
6579 && IT_CHARPOS (*it) > to_charpos)
6580 {
6581 result = MOVE_POS_MATCH_OR_ZV;
6582 break;
6583 }
6584
6585 /* Stop when ZV reached.
6586 We used to stop here when TO_CHARPOS reached as well, but that is
6587 too soon if this glyph does not fit on this line. So we handle it
6588 explicitly below. */
6589 if (!get_next_display_element (it)
6590 || (it->truncate_lines_p
6591 && BUFFER_POS_REACHED_P ()))
6592 {
6593 result = MOVE_POS_MATCH_OR_ZV;
6594 break;
6595 }
6596
6597 /* The call to produce_glyphs will get the metrics of the
6598 display element IT is loaded with. We record in x the
6599 x-position before this display element in case it does not
6600 fit on the line. */
6601 x = it->current_x;
6602
6603 /* Remember the line height so far in case the next element doesn't
6604 fit on the line. */
6605 if (!it->truncate_lines_p)
6606 {
6607 ascent = it->max_ascent;
6608 descent = it->max_descent;
6609 }
6610
6611 PRODUCE_GLYPHS (it);
6612
6613 if (it->area != TEXT_AREA)
6614 {
6615 set_iterator_to_next (it, 1);
6616 continue;
6617 }
6618
6619 /* The number of glyphs we get back in IT->nglyphs will normally
6620 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
6621 character on a terminal frame, or (iii) a line end. For the
6622 second case, IT->nglyphs - 1 padding glyphs will be present
6623 (on X frames, there is only one glyph produced for a
6624 composite character.
6625
6626 The behavior implemented below means, for continuation lines,
6627 that as many spaces of a TAB as fit on the current line are
6628 displayed there. For terminal frames, as many glyphs of a
6629 multi-glyph character are displayed in the current line, too.
6630 This is what the old redisplay code did, and we keep it that
6631 way. Under X, the whole shape of a complex character must
6632 fit on the line or it will be completely displayed in the
6633 next line.
6634
6635 Note that both for tabs and padding glyphs, all glyphs have
6636 the same width. */
6637 if (it->nglyphs)
6638 {
6639 /* More than one glyph or glyph doesn't fit on line. All
6640 glyphs have the same width. */
6641 int single_glyph_width = it->pixel_width / it->nglyphs;
6642 int new_x;
6643 int x_before_this_char = x;
6644 int hpos_before_this_char = it->hpos;
6645
6646 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6647 {
6648 new_x = x + single_glyph_width;
6649
6650 /* We want to leave anything reaching TO_X to the caller. */
6651 if ((op & MOVE_TO_X) && new_x > to_x)
6652 {
6653 if (BUFFER_POS_REACHED_P ())
6654 goto buffer_pos_reached;
6655 it->current_x = x;
6656 result = MOVE_X_REACHED;
6657 break;
6658 }
6659 else if (/* Lines are continued. */
6660 !it->truncate_lines_p
6661 && (/* And glyph doesn't fit on the line. */
6662 new_x > it->last_visible_x
6663 /* Or it fits exactly and we're on a window
6664 system frame. */
6665 || (new_x == it->last_visible_x
6666 && FRAME_WINDOW_P (it->f))))
6667 {
6668 if (/* IT->hpos == 0 means the very first glyph
6669 doesn't fit on the line, e.g. a wide image. */
6670 it->hpos == 0
6671 || (new_x == it->last_visible_x
6672 && FRAME_WINDOW_P (it->f)))
6673 {
6674 ++it->hpos;
6675 it->current_x = new_x;
6676
6677 /* The character's last glyph just barely fits
6678 in this row. */
6679 if (i == it->nglyphs - 1)
6680 {
6681 /* If this is the destination position,
6682 return a position *before* it in this row,
6683 now that we know it fits in this row. */
6684 if (BUFFER_POS_REACHED_P ())
6685 {
6686 it->hpos = hpos_before_this_char;
6687 it->current_x = x_before_this_char;
6688 result = MOVE_POS_MATCH_OR_ZV;
6689 break;
6690 }
6691
6692 set_iterator_to_next (it, 1);
6693 #ifdef HAVE_WINDOW_SYSTEM
6694 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6695 {
6696 if (!get_next_display_element (it))
6697 {
6698 result = MOVE_POS_MATCH_OR_ZV;
6699 break;
6700 }
6701 if (BUFFER_POS_REACHED_P ())
6702 {
6703 if (ITERATOR_AT_END_OF_LINE_P (it))
6704 result = MOVE_POS_MATCH_OR_ZV;
6705 else
6706 result = MOVE_LINE_CONTINUED;
6707 break;
6708 }
6709 if (ITERATOR_AT_END_OF_LINE_P (it))
6710 {
6711 result = MOVE_NEWLINE_OR_CR;
6712 break;
6713 }
6714 }
6715 #endif /* HAVE_WINDOW_SYSTEM */
6716 }
6717 }
6718 else
6719 {
6720 it->current_x = x;
6721 it->max_ascent = ascent;
6722 it->max_descent = descent;
6723 }
6724
6725 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6726 IT_CHARPOS (*it)));
6727 result = MOVE_LINE_CONTINUED;
6728 break;
6729 }
6730 else if (BUFFER_POS_REACHED_P ())
6731 goto buffer_pos_reached;
6732 else if (new_x > it->first_visible_x)
6733 {
6734 /* Glyph is visible. Increment number of glyphs that
6735 would be displayed. */
6736 ++it->hpos;
6737 }
6738 else
6739 {
6740 /* Glyph is completely off the left margin of the display
6741 area. Nothing to do. */
6742 }
6743 }
6744
6745 if (result != MOVE_UNDEFINED)
6746 break;
6747 }
6748 else if (BUFFER_POS_REACHED_P ())
6749 {
6750 buffer_pos_reached:
6751 it->current_x = x;
6752 it->max_ascent = ascent;
6753 it->max_descent = descent;
6754 result = MOVE_POS_MATCH_OR_ZV;
6755 break;
6756 }
6757 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6758 {
6759 /* Stop when TO_X specified and reached. This check is
6760 necessary here because of lines consisting of a line end,
6761 only. The line end will not produce any glyphs and we
6762 would never get MOVE_X_REACHED. */
6763 xassert (it->nglyphs == 0);
6764 result = MOVE_X_REACHED;
6765 break;
6766 }
6767
6768 /* Is this a line end? If yes, we're done. */
6769 if (ITERATOR_AT_END_OF_LINE_P (it))
6770 {
6771 result = MOVE_NEWLINE_OR_CR;
6772 break;
6773 }
6774
6775 /* The current display element has been consumed. Advance
6776 to the next. */
6777 set_iterator_to_next (it, 1);
6778
6779 /* Stop if lines are truncated and IT's current x-position is
6780 past the right edge of the window now. */
6781 if (it->truncate_lines_p
6782 && it->current_x >= it->last_visible_x)
6783 {
6784 #ifdef HAVE_WINDOW_SYSTEM
6785 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6786 {
6787 if (!get_next_display_element (it)
6788 || BUFFER_POS_REACHED_P ())
6789 {
6790 result = MOVE_POS_MATCH_OR_ZV;
6791 break;
6792 }
6793 if (ITERATOR_AT_END_OF_LINE_P (it))
6794 {
6795 result = MOVE_NEWLINE_OR_CR;
6796 break;
6797 }
6798 }
6799 #endif /* HAVE_WINDOW_SYSTEM */
6800 result = MOVE_LINE_TRUNCATED;
6801 break;
6802 }
6803 }
6804
6805 #undef BUFFER_POS_REACHED_P
6806
6807 /* Restore the iterator settings altered at the beginning of this
6808 function. */
6809 it->glyph_row = saved_glyph_row;
6810 return result;
6811 }
6812
6813
6814 /* Move IT forward until it satisfies one or more of the criteria in
6815 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6816
6817 OP is a bit-mask that specifies where to stop, and in particular,
6818 which of those four position arguments makes a difference. See the
6819 description of enum move_operation_enum.
6820
6821 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6822 screen line, this function will set IT to the next position >
6823 TO_CHARPOS. */
6824
6825 void
6826 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6827 struct it *it;
6828 int to_charpos, to_x, to_y, to_vpos;
6829 int op;
6830 {
6831 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6832 int line_height;
6833 int reached = 0;
6834
6835 for (;;)
6836 {
6837 if (op & MOVE_TO_VPOS)
6838 {
6839 /* If no TO_CHARPOS and no TO_X specified, stop at the
6840 start of the line TO_VPOS. */
6841 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6842 {
6843 if (it->vpos == to_vpos)
6844 {
6845 reached = 1;
6846 break;
6847 }
6848 else
6849 skip = move_it_in_display_line_to (it, -1, -1, 0);
6850 }
6851 else
6852 {
6853 /* TO_VPOS >= 0 means stop at TO_X in the line at
6854 TO_VPOS, or at TO_POS, whichever comes first. */
6855 if (it->vpos == to_vpos)
6856 {
6857 reached = 2;
6858 break;
6859 }
6860
6861 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6862
6863 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6864 {
6865 reached = 3;
6866 break;
6867 }
6868 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6869 {
6870 /* We have reached TO_X but not in the line we want. */
6871 skip = move_it_in_display_line_to (it, to_charpos,
6872 -1, MOVE_TO_POS);
6873 if (skip == MOVE_POS_MATCH_OR_ZV)
6874 {
6875 reached = 4;
6876 break;
6877 }
6878 }
6879 }
6880 }
6881 else if (op & MOVE_TO_Y)
6882 {
6883 struct it it_backup;
6884
6885 /* TO_Y specified means stop at TO_X in the line containing
6886 TO_Y---or at TO_CHARPOS if this is reached first. The
6887 problem is that we can't really tell whether the line
6888 contains TO_Y before we have completely scanned it, and
6889 this may skip past TO_X. What we do is to first scan to
6890 TO_X.
6891
6892 If TO_X is not specified, use a TO_X of zero. The reason
6893 is to make the outcome of this function more predictable.
6894 If we didn't use TO_X == 0, we would stop at the end of
6895 the line which is probably not what a caller would expect
6896 to happen. */
6897 skip = move_it_in_display_line_to (it, to_charpos,
6898 ((op & MOVE_TO_X)
6899 ? to_x : 0),
6900 (MOVE_TO_X
6901 | (op & MOVE_TO_POS)));
6902
6903 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6904 if (skip == MOVE_POS_MATCH_OR_ZV)
6905 {
6906 reached = 5;
6907 break;
6908 }
6909
6910 /* If TO_X was reached, we would like to know whether TO_Y
6911 is in the line. This can only be said if we know the
6912 total line height which requires us to scan the rest of
6913 the line. */
6914 if (skip == MOVE_X_REACHED)
6915 {
6916 /* Wait! We can conclude that TO_Y is in the line if
6917 the already scanned glyphs make the line tall enough
6918 because further scanning doesn't make it shorter. */
6919 line_height = it->max_ascent + it->max_descent;
6920 if (to_y >= it->current_y
6921 && to_y < it->current_y + line_height)
6922 {
6923 reached = 6;
6924 break;
6925 }
6926 it_backup = *it;
6927 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6928 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6929 op & MOVE_TO_POS);
6930 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6931 }
6932
6933 /* Now, decide whether TO_Y is in this line. */
6934 line_height = it->max_ascent + it->max_descent;
6935 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6936
6937 if (to_y >= it->current_y
6938 && to_y < it->current_y + line_height)
6939 {
6940 if (skip == MOVE_X_REACHED)
6941 /* If TO_Y is in this line and TO_X was reached above,
6942 we scanned too far. We have to restore IT's settings
6943 to the ones before skipping. */
6944 *it = it_backup;
6945 reached = 6;
6946 }
6947 else if (skip == MOVE_X_REACHED)
6948 {
6949 skip = skip2;
6950 if (skip == MOVE_POS_MATCH_OR_ZV)
6951 reached = 7;
6952 }
6953
6954 if (reached)
6955 break;
6956 }
6957 else if (BUFFERP (it->object)
6958 && it->method == GET_FROM_BUFFER
6959 && IT_CHARPOS (*it) >= to_charpos)
6960 skip = MOVE_POS_MATCH_OR_ZV;
6961 else
6962 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6963
6964 switch (skip)
6965 {
6966 case MOVE_POS_MATCH_OR_ZV:
6967 reached = 8;
6968 goto out;
6969
6970 case MOVE_NEWLINE_OR_CR:
6971 set_iterator_to_next (it, 1);
6972 it->continuation_lines_width = 0;
6973 break;
6974
6975 case MOVE_LINE_TRUNCATED:
6976 it->continuation_lines_width = 0;
6977 reseat_at_next_visible_line_start (it, 0);
6978 if ((op & MOVE_TO_POS) != 0
6979 && IT_CHARPOS (*it) > to_charpos)
6980 {
6981 reached = 9;
6982 goto out;
6983 }
6984 break;
6985
6986 case MOVE_LINE_CONTINUED:
6987 /* For continued lines ending in a tab, some of the glyphs
6988 associated with the tab are displayed on the current
6989 line. Since it->current_x does not include these glyphs,
6990 we use it->last_visible_x instead. */
6991 it->continuation_lines_width +=
6992 (it->c == '\t') ? it->last_visible_x : it->current_x;
6993 break;
6994
6995 default:
6996 abort ();
6997 }
6998
6999 /* Reset/increment for the next run. */
7000 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7001 it->current_x = it->hpos = 0;
7002 it->current_y += it->max_ascent + it->max_descent;
7003 ++it->vpos;
7004 last_height = it->max_ascent + it->max_descent;
7005 last_max_ascent = it->max_ascent;
7006 it->max_ascent = it->max_descent = 0;
7007 }
7008
7009 out:
7010
7011 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7012 }
7013
7014
7015 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7016
7017 If DY > 0, move IT backward at least that many pixels. DY = 0
7018 means move IT backward to the preceding line start or BEGV. This
7019 function may move over more than DY pixels if IT->current_y - DY
7020 ends up in the middle of a line; in this case IT->current_y will be
7021 set to the top of the line moved to. */
7022
7023 void
7024 move_it_vertically_backward (it, dy)
7025 struct it *it;
7026 int dy;
7027 {
7028 int nlines, h;
7029 struct it it2, it3;
7030 int start_pos;
7031
7032 move_further_back:
7033 xassert (dy >= 0);
7034
7035 start_pos = IT_CHARPOS (*it);
7036
7037 /* Estimate how many newlines we must move back. */
7038 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7039
7040 /* Set the iterator's position that many lines back. */
7041 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7042 back_to_previous_visible_line_start (it);
7043
7044 /* Reseat the iterator here. When moving backward, we don't want
7045 reseat to skip forward over invisible text, set up the iterator
7046 to deliver from overlay strings at the new position etc. So,
7047 use reseat_1 here. */
7048 reseat_1 (it, it->current.pos, 1);
7049
7050 /* We are now surely at a line start. */
7051 it->current_x = it->hpos = 0;
7052 it->continuation_lines_width = 0;
7053
7054 /* Move forward and see what y-distance we moved. First move to the
7055 start of the next line so that we get its height. We need this
7056 height to be able to tell whether we reached the specified
7057 y-distance. */
7058 it2 = *it;
7059 it2.max_ascent = it2.max_descent = 0;
7060 do
7061 {
7062 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7063 MOVE_TO_POS | MOVE_TO_VPOS);
7064 }
7065 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7066 xassert (IT_CHARPOS (*it) >= BEGV);
7067 it3 = it2;
7068
7069 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7070 xassert (IT_CHARPOS (*it) >= BEGV);
7071 /* H is the actual vertical distance from the position in *IT
7072 and the starting position. */
7073 h = it2.current_y - it->current_y;
7074 /* NLINES is the distance in number of lines. */
7075 nlines = it2.vpos - it->vpos;
7076
7077 /* Correct IT's y and vpos position
7078 so that they are relative to the starting point. */
7079 it->vpos -= nlines;
7080 it->current_y -= h;
7081
7082 if (dy == 0)
7083 {
7084 /* DY == 0 means move to the start of the screen line. The
7085 value of nlines is > 0 if continuation lines were involved. */
7086 if (nlines > 0)
7087 move_it_by_lines (it, nlines, 1);
7088 #if 0
7089 /* I think this assert is bogus if buffer contains
7090 invisible text or images. KFS. */
7091 xassert (IT_CHARPOS (*it) <= start_pos);
7092 #endif
7093 }
7094 else
7095 {
7096 /* The y-position we try to reach, relative to *IT.
7097 Note that H has been subtracted in front of the if-statement. */
7098 int target_y = it->current_y + h - dy;
7099 int y0 = it3.current_y;
7100 int y1 = line_bottom_y (&it3);
7101 int line_height = y1 - y0;
7102
7103 /* If we did not reach target_y, try to move further backward if
7104 we can. If we moved too far backward, try to move forward. */
7105 if (target_y < it->current_y
7106 /* This is heuristic. In a window that's 3 lines high, with
7107 a line height of 13 pixels each, recentering with point
7108 on the bottom line will try to move -39/2 = 19 pixels
7109 backward. Try to avoid moving into the first line. */
7110 && (it->current_y - target_y
7111 > min (window_box_height (it->w), line_height * 2 / 3))
7112 && IT_CHARPOS (*it) > BEGV)
7113 {
7114 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7115 target_y - it->current_y));
7116 dy = it->current_y - target_y;
7117 goto move_further_back;
7118 }
7119 else if (target_y >= it->current_y + line_height
7120 && IT_CHARPOS (*it) < ZV)
7121 {
7122 /* Should move forward by at least one line, maybe more.
7123
7124 Note: Calling move_it_by_lines can be expensive on
7125 terminal frames, where compute_motion is used (via
7126 vmotion) to do the job, when there are very long lines
7127 and truncate-lines is nil. That's the reason for
7128 treating terminal frames specially here. */
7129
7130 if (!FRAME_WINDOW_P (it->f))
7131 move_it_vertically (it, target_y - (it->current_y + line_height));
7132 else
7133 {
7134 do
7135 {
7136 move_it_by_lines (it, 1, 1);
7137 }
7138 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7139 }
7140
7141 #if 0
7142 /* I think this assert is bogus if buffer contains
7143 invisible text or images. KFS. */
7144 xassert (IT_CHARPOS (*it) >= BEGV);
7145 #endif
7146 }
7147 }
7148 }
7149
7150
7151 /* Move IT by a specified amount of pixel lines DY. DY negative means
7152 move backwards. DY = 0 means move to start of screen line. At the
7153 end, IT will be on the start of a screen line. */
7154
7155 void
7156 move_it_vertically (it, dy)
7157 struct it *it;
7158 int dy;
7159 {
7160 if (dy <= 0)
7161 move_it_vertically_backward (it, -dy);
7162 else
7163 {
7164 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7165 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7166 MOVE_TO_POS | MOVE_TO_Y);
7167 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7168
7169 /* If buffer ends in ZV without a newline, move to the start of
7170 the line to satisfy the post-condition. */
7171 if (IT_CHARPOS (*it) == ZV
7172 && ZV > BEGV
7173 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7174 move_it_by_lines (it, 0, 0);
7175 }
7176 }
7177
7178
7179 /* Move iterator IT past the end of the text line it is in. */
7180
7181 void
7182 move_it_past_eol (it)
7183 struct it *it;
7184 {
7185 enum move_it_result rc;
7186
7187 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7188 if (rc == MOVE_NEWLINE_OR_CR)
7189 set_iterator_to_next (it, 0);
7190 }
7191
7192
7193 #if 0 /* Currently not used. */
7194
7195 /* Return non-zero if some text between buffer positions START_CHARPOS
7196 and END_CHARPOS is invisible. IT->window is the window for text
7197 property lookup. */
7198
7199 static int
7200 invisible_text_between_p (it, start_charpos, end_charpos)
7201 struct it *it;
7202 int start_charpos, end_charpos;
7203 {
7204 Lisp_Object prop, limit;
7205 int invisible_found_p;
7206
7207 xassert (it != NULL && start_charpos <= end_charpos);
7208
7209 /* Is text at START invisible? */
7210 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
7211 it->window);
7212 if (TEXT_PROP_MEANS_INVISIBLE (prop))
7213 invisible_found_p = 1;
7214 else
7215 {
7216 limit = Fnext_single_char_property_change (make_number (start_charpos),
7217 Qinvisible, Qnil,
7218 make_number (end_charpos));
7219 invisible_found_p = XFASTINT (limit) < end_charpos;
7220 }
7221
7222 return invisible_found_p;
7223 }
7224
7225 #endif /* 0 */
7226
7227
7228 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7229 negative means move up. DVPOS == 0 means move to the start of the
7230 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7231 NEED_Y_P is zero, IT->current_y will be left unchanged.
7232
7233 Further optimization ideas: If we would know that IT->f doesn't use
7234 a face with proportional font, we could be faster for
7235 truncate-lines nil. */
7236
7237 void
7238 move_it_by_lines (it, dvpos, need_y_p)
7239 struct it *it;
7240 int dvpos, need_y_p;
7241 {
7242 struct position pos;
7243
7244 /* The commented-out optimization uses vmotion on terminals. This
7245 gives bad results, because elements like it->what, on which
7246 callers such as pos_visible_p rely, aren't updated. */
7247 /* if (!FRAME_WINDOW_P (it->f))
7248 {
7249 struct text_pos textpos;
7250
7251 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7252 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7253 reseat (it, textpos, 1);
7254 it->vpos += pos.vpos;
7255 it->current_y += pos.vpos;
7256 }
7257 else */
7258
7259 if (dvpos == 0)
7260 {
7261 /* DVPOS == 0 means move to the start of the screen line. */
7262 move_it_vertically_backward (it, 0);
7263 xassert (it->current_x == 0 && it->hpos == 0);
7264 /* Let next call to line_bottom_y calculate real line height */
7265 last_height = 0;
7266 }
7267 else if (dvpos > 0)
7268 {
7269 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7270 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7271 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7272 }
7273 else
7274 {
7275 struct it it2;
7276 int start_charpos, i;
7277
7278 /* Start at the beginning of the screen line containing IT's
7279 position. This may actually move vertically backwards,
7280 in case of overlays, so adjust dvpos accordingly. */
7281 dvpos += it->vpos;
7282 move_it_vertically_backward (it, 0);
7283 dvpos -= it->vpos;
7284
7285 /* Go back -DVPOS visible lines and reseat the iterator there. */
7286 start_charpos = IT_CHARPOS (*it);
7287 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7288 back_to_previous_visible_line_start (it);
7289 reseat (it, it->current.pos, 1);
7290
7291 /* Move further back if we end up in a string or an image. */
7292 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7293 {
7294 /* First try to move to start of display line. */
7295 dvpos += it->vpos;
7296 move_it_vertically_backward (it, 0);
7297 dvpos -= it->vpos;
7298 if (IT_POS_VALID_AFTER_MOVE_P (it))
7299 break;
7300 /* If start of line is still in string or image,
7301 move further back. */
7302 back_to_previous_visible_line_start (it);
7303 reseat (it, it->current.pos, 1);
7304 dvpos--;
7305 }
7306
7307 it->current_x = it->hpos = 0;
7308
7309 /* Above call may have moved too far if continuation lines
7310 are involved. Scan forward and see if it did. */
7311 it2 = *it;
7312 it2.vpos = it2.current_y = 0;
7313 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7314 it->vpos -= it2.vpos;
7315 it->current_y -= it2.current_y;
7316 it->current_x = it->hpos = 0;
7317
7318 /* If we moved too far back, move IT some lines forward. */
7319 if (it2.vpos > -dvpos)
7320 {
7321 int delta = it2.vpos + dvpos;
7322 it2 = *it;
7323 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7324 /* Move back again if we got too far ahead. */
7325 if (IT_CHARPOS (*it) >= start_charpos)
7326 *it = it2;
7327 }
7328 }
7329 }
7330
7331 /* Return 1 if IT points into the middle of a display vector. */
7332
7333 int
7334 in_display_vector_p (it)
7335 struct it *it;
7336 {
7337 return (it->method == GET_FROM_DISPLAY_VECTOR
7338 && it->current.dpvec_index > 0
7339 && it->dpvec + it->current.dpvec_index != it->dpend);
7340 }
7341
7342 \f
7343 /***********************************************************************
7344 Messages
7345 ***********************************************************************/
7346
7347
7348 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7349 to *Messages*. */
7350
7351 void
7352 add_to_log (format, arg1, arg2)
7353 char *format;
7354 Lisp_Object arg1, arg2;
7355 {
7356 Lisp_Object args[3];
7357 Lisp_Object msg, fmt;
7358 char *buffer;
7359 int len;
7360 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7361 USE_SAFE_ALLOCA;
7362
7363 /* Do nothing if called asynchronously. Inserting text into
7364 a buffer may call after-change-functions and alike and
7365 that would means running Lisp asynchronously. */
7366 if (handling_signal)
7367 return;
7368
7369 fmt = msg = Qnil;
7370 GCPRO4 (fmt, msg, arg1, arg2);
7371
7372 args[0] = fmt = build_string (format);
7373 args[1] = arg1;
7374 args[2] = arg2;
7375 msg = Fformat (3, args);
7376
7377 len = SBYTES (msg) + 1;
7378 SAFE_ALLOCA (buffer, char *, len);
7379 bcopy (SDATA (msg), buffer, len);
7380
7381 message_dolog (buffer, len - 1, 1, 0);
7382 SAFE_FREE ();
7383
7384 UNGCPRO;
7385 }
7386
7387
7388 /* Output a newline in the *Messages* buffer if "needs" one. */
7389
7390 void
7391 message_log_maybe_newline ()
7392 {
7393 if (message_log_need_newline)
7394 message_dolog ("", 0, 1, 0);
7395 }
7396
7397
7398 /* Add a string M of length NBYTES to the message log, optionally
7399 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7400 nonzero, means interpret the contents of M as multibyte. This
7401 function calls low-level routines in order to bypass text property
7402 hooks, etc. which might not be safe to run.
7403
7404 This may GC (insert may run before/after change hooks),
7405 so the buffer M must NOT point to a Lisp string. */
7406
7407 void
7408 message_dolog (m, nbytes, nlflag, multibyte)
7409 const char *m;
7410 int nbytes, nlflag, multibyte;
7411 {
7412 if (!NILP (Vmemory_full))
7413 return;
7414
7415 if (!NILP (Vmessage_log_max))
7416 {
7417 struct buffer *oldbuf;
7418 Lisp_Object oldpoint, oldbegv, oldzv;
7419 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7420 int point_at_end = 0;
7421 int zv_at_end = 0;
7422 Lisp_Object old_deactivate_mark, tem;
7423 struct gcpro gcpro1;
7424
7425 old_deactivate_mark = Vdeactivate_mark;
7426 oldbuf = current_buffer;
7427 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7428 current_buffer->undo_list = Qt;
7429
7430 oldpoint = message_dolog_marker1;
7431 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7432 oldbegv = message_dolog_marker2;
7433 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7434 oldzv = message_dolog_marker3;
7435 set_marker_restricted (oldzv, make_number (ZV), Qnil);
7436 GCPRO1 (old_deactivate_mark);
7437
7438 if (PT == Z)
7439 point_at_end = 1;
7440 if (ZV == Z)
7441 zv_at_end = 1;
7442
7443 BEGV = BEG;
7444 BEGV_BYTE = BEG_BYTE;
7445 ZV = Z;
7446 ZV_BYTE = Z_BYTE;
7447 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7448
7449 /* Insert the string--maybe converting multibyte to single byte
7450 or vice versa, so that all the text fits the buffer. */
7451 if (multibyte
7452 && NILP (current_buffer->enable_multibyte_characters))
7453 {
7454 int i, c, char_bytes;
7455 unsigned char work[1];
7456
7457 /* Convert a multibyte string to single-byte
7458 for the *Message* buffer. */
7459 for (i = 0; i < nbytes; i += char_bytes)
7460 {
7461 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
7462 work[0] = (ASCII_CHAR_P (c)
7463 ? c
7464 : multibyte_char_to_unibyte (c, Qnil));
7465 insert_1_both (work, 1, 1, 1, 0, 0);
7466 }
7467 }
7468 else if (! multibyte
7469 && ! NILP (current_buffer->enable_multibyte_characters))
7470 {
7471 int i, c, char_bytes;
7472 unsigned char *msg = (unsigned char *) m;
7473 unsigned char str[MAX_MULTIBYTE_LENGTH];
7474 /* Convert a single-byte string to multibyte
7475 for the *Message* buffer. */
7476 for (i = 0; i < nbytes; i++)
7477 {
7478 c = msg[i];
7479 c = unibyte_char_to_multibyte (c);
7480 char_bytes = CHAR_STRING (c, str);
7481 insert_1_both (str, 1, char_bytes, 1, 0, 0);
7482 }
7483 }
7484 else if (nbytes)
7485 insert_1 (m, nbytes, 1, 0, 0);
7486
7487 if (nlflag)
7488 {
7489 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
7490 insert_1 ("\n", 1, 1, 0, 0);
7491
7492 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
7493 this_bol = PT;
7494 this_bol_byte = PT_BYTE;
7495
7496 /* See if this line duplicates the previous one.
7497 If so, combine duplicates. */
7498 if (this_bol > BEG)
7499 {
7500 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
7501 prev_bol = PT;
7502 prev_bol_byte = PT_BYTE;
7503
7504 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
7505 this_bol, this_bol_byte);
7506 if (dup)
7507 {
7508 del_range_both (prev_bol, prev_bol_byte,
7509 this_bol, this_bol_byte, 0);
7510 if (dup > 1)
7511 {
7512 char dupstr[40];
7513 int duplen;
7514
7515 /* If you change this format, don't forget to also
7516 change message_log_check_duplicate. */
7517 sprintf (dupstr, " [%d times]", dup);
7518 duplen = strlen (dupstr);
7519 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
7520 insert_1 (dupstr, duplen, 1, 0, 1);
7521 }
7522 }
7523 }
7524
7525 /* If we have more than the desired maximum number of lines
7526 in the *Messages* buffer now, delete the oldest ones.
7527 This is safe because we don't have undo in this buffer. */
7528
7529 if (NATNUMP (Vmessage_log_max))
7530 {
7531 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
7532 -XFASTINT (Vmessage_log_max) - 1, 0);
7533 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
7534 }
7535 }
7536 BEGV = XMARKER (oldbegv)->charpos;
7537 BEGV_BYTE = marker_byte_position (oldbegv);
7538
7539 if (zv_at_end)
7540 {
7541 ZV = Z;
7542 ZV_BYTE = Z_BYTE;
7543 }
7544 else
7545 {
7546 ZV = XMARKER (oldzv)->charpos;
7547 ZV_BYTE = marker_byte_position (oldzv);
7548 }
7549
7550 if (point_at_end)
7551 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7552 else
7553 /* We can't do Fgoto_char (oldpoint) because it will run some
7554 Lisp code. */
7555 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
7556 XMARKER (oldpoint)->bytepos);
7557
7558 UNGCPRO;
7559 unchain_marker (XMARKER (oldpoint));
7560 unchain_marker (XMARKER (oldbegv));
7561 unchain_marker (XMARKER (oldzv));
7562
7563 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
7564 set_buffer_internal (oldbuf);
7565 if (NILP (tem))
7566 windows_or_buffers_changed = old_windows_or_buffers_changed;
7567 message_log_need_newline = !nlflag;
7568 Vdeactivate_mark = old_deactivate_mark;
7569 }
7570 }
7571
7572
7573 /* We are at the end of the buffer after just having inserted a newline.
7574 (Note: We depend on the fact we won't be crossing the gap.)
7575 Check to see if the most recent message looks a lot like the previous one.
7576 Return 0 if different, 1 if the new one should just replace it, or a
7577 value N > 1 if we should also append " [N times]". */
7578
7579 static int
7580 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
7581 int prev_bol, this_bol;
7582 int prev_bol_byte, this_bol_byte;
7583 {
7584 int i;
7585 int len = Z_BYTE - 1 - this_bol_byte;
7586 int seen_dots = 0;
7587 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
7588 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
7589
7590 for (i = 0; i < len; i++)
7591 {
7592 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
7593 seen_dots = 1;
7594 if (p1[i] != p2[i])
7595 return seen_dots;
7596 }
7597 p1 += len;
7598 if (*p1 == '\n')
7599 return 2;
7600 if (*p1++ == ' ' && *p1++ == '[')
7601 {
7602 int n = 0;
7603 while (*p1 >= '0' && *p1 <= '9')
7604 n = n * 10 + *p1++ - '0';
7605 if (strncmp (p1, " times]\n", 8) == 0)
7606 return n+1;
7607 }
7608 return 0;
7609 }
7610 \f
7611
7612 /* Display an echo area message M with a specified length of NBYTES
7613 bytes. The string may include null characters. If M is 0, clear
7614 out any existing message, and let the mini-buffer text show
7615 through.
7616
7617 This may GC, so the buffer M must NOT point to a Lisp string. */
7618
7619 void
7620 message2 (m, nbytes, multibyte)
7621 const char *m;
7622 int nbytes;
7623 int multibyte;
7624 {
7625 /* First flush out any partial line written with print. */
7626 message_log_maybe_newline ();
7627 if (m)
7628 message_dolog (m, nbytes, 1, multibyte);
7629 message2_nolog (m, nbytes, multibyte);
7630 }
7631
7632
7633 /* The non-logging counterpart of message2. */
7634
7635 void
7636 message2_nolog (m, nbytes, multibyte)
7637 const char *m;
7638 int nbytes, multibyte;
7639 {
7640 struct frame *sf = SELECTED_FRAME ();
7641 message_enable_multibyte = multibyte;
7642
7643 if (noninteractive)
7644 {
7645 if (noninteractive_need_newline)
7646 putc ('\n', stderr);
7647 noninteractive_need_newline = 0;
7648 if (m)
7649 fwrite (m, nbytes, 1, stderr);
7650 if (cursor_in_echo_area == 0)
7651 fprintf (stderr, "\n");
7652 fflush (stderr);
7653 }
7654 /* A null message buffer means that the frame hasn't really been
7655 initialized yet. Error messages get reported properly by
7656 cmd_error, so this must be just an informative message; toss it. */
7657 else if (INTERACTIVE
7658 && sf->glyphs_initialized_p
7659 && FRAME_MESSAGE_BUF (sf))
7660 {
7661 Lisp_Object mini_window;
7662 struct frame *f;
7663
7664 /* Get the frame containing the mini-buffer
7665 that the selected frame is using. */
7666 mini_window = FRAME_MINIBUF_WINDOW (sf);
7667 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7668
7669 FRAME_SAMPLE_VISIBILITY (f);
7670 if (FRAME_VISIBLE_P (sf)
7671 && ! FRAME_VISIBLE_P (f))
7672 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
7673
7674 if (m)
7675 {
7676 set_message (m, Qnil, nbytes, multibyte);
7677 if (minibuffer_auto_raise)
7678 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7679 }
7680 else
7681 clear_message (1, 1);
7682
7683 do_pending_window_change (0);
7684 echo_area_display (1);
7685 do_pending_window_change (0);
7686 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7687 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7688 }
7689 }
7690
7691
7692 /* Display an echo area message M with a specified length of NBYTES
7693 bytes. The string may include null characters. If M is not a
7694 string, clear out any existing message, and let the mini-buffer
7695 text show through.
7696
7697 This function cancels echoing. */
7698
7699 void
7700 message3 (m, nbytes, multibyte)
7701 Lisp_Object m;
7702 int nbytes;
7703 int multibyte;
7704 {
7705 struct gcpro gcpro1;
7706
7707 GCPRO1 (m);
7708 clear_message (1,1);
7709 cancel_echoing ();
7710
7711 /* First flush out any partial line written with print. */
7712 message_log_maybe_newline ();
7713 if (STRINGP (m))
7714 {
7715 char *buffer;
7716 USE_SAFE_ALLOCA;
7717
7718 SAFE_ALLOCA (buffer, char *, nbytes);
7719 bcopy (SDATA (m), buffer, nbytes);
7720 message_dolog (buffer, nbytes, 1, multibyte);
7721 SAFE_FREE ();
7722 }
7723 message3_nolog (m, nbytes, multibyte);
7724
7725 UNGCPRO;
7726 }
7727
7728
7729 /* The non-logging version of message3.
7730 This does not cancel echoing, because it is used for echoing.
7731 Perhaps we need to make a separate function for echoing
7732 and make this cancel echoing. */
7733
7734 void
7735 message3_nolog (m, nbytes, multibyte)
7736 Lisp_Object m;
7737 int nbytes, multibyte;
7738 {
7739 struct frame *sf = SELECTED_FRAME ();
7740 message_enable_multibyte = multibyte;
7741
7742 if (noninteractive)
7743 {
7744 if (noninteractive_need_newline)
7745 putc ('\n', stderr);
7746 noninteractive_need_newline = 0;
7747 if (STRINGP (m))
7748 fwrite (SDATA (m), nbytes, 1, stderr);
7749 if (cursor_in_echo_area == 0)
7750 fprintf (stderr, "\n");
7751 fflush (stderr);
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 it. */
7756 else if (INTERACTIVE
7757 && sf->glyphs_initialized_p
7758 && FRAME_MESSAGE_BUF (sf))
7759 {
7760 Lisp_Object mini_window;
7761 Lisp_Object frame;
7762 struct frame *f;
7763
7764 /* Get the frame containing the mini-buffer
7765 that the selected frame is using. */
7766 mini_window = FRAME_MINIBUF_WINDOW (sf);
7767 frame = XWINDOW (mini_window)->frame;
7768 f = XFRAME (frame);
7769
7770 FRAME_SAMPLE_VISIBILITY (f);
7771 if (FRAME_VISIBLE_P (sf)
7772 && !FRAME_VISIBLE_P (f))
7773 Fmake_frame_visible (frame);
7774
7775 if (STRINGP (m) && SCHARS (m) > 0)
7776 {
7777 set_message (NULL, m, nbytes, multibyte);
7778 if (minibuffer_auto_raise)
7779 Fraise_frame (frame);
7780 /* Assume we are not echoing.
7781 (If we are, echo_now will override this.) */
7782 echo_message_buffer = Qnil;
7783 }
7784 else
7785 clear_message (1, 1);
7786
7787 do_pending_window_change (0);
7788 echo_area_display (1);
7789 do_pending_window_change (0);
7790 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7791 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7792 }
7793 }
7794
7795
7796 /* Display a null-terminated echo area message M. If M is 0, clear
7797 out any existing message, and let the mini-buffer text show through.
7798
7799 The buffer M must continue to exist until after the echo area gets
7800 cleared or some other message gets displayed there. Do not pass
7801 text that is stored in a Lisp string. Do not pass text in a buffer
7802 that was alloca'd. */
7803
7804 void
7805 message1 (m)
7806 char *m;
7807 {
7808 message2 (m, (m ? strlen (m) : 0), 0);
7809 }
7810
7811
7812 /* The non-logging counterpart of message1. */
7813
7814 void
7815 message1_nolog (m)
7816 char *m;
7817 {
7818 message2_nolog (m, (m ? strlen (m) : 0), 0);
7819 }
7820
7821 /* Display a message M which contains a single %s
7822 which gets replaced with STRING. */
7823
7824 void
7825 message_with_string (m, string, log)
7826 char *m;
7827 Lisp_Object string;
7828 int log;
7829 {
7830 CHECK_STRING (string);
7831
7832 if (noninteractive)
7833 {
7834 if (m)
7835 {
7836 if (noninteractive_need_newline)
7837 putc ('\n', stderr);
7838 noninteractive_need_newline = 0;
7839 fprintf (stderr, m, SDATA (string));
7840 if (cursor_in_echo_area == 0)
7841 fprintf (stderr, "\n");
7842 fflush (stderr);
7843 }
7844 }
7845 else if (INTERACTIVE)
7846 {
7847 /* The frame whose minibuffer we're going to display the message on.
7848 It may be larger than the selected frame, so we need
7849 to use its buffer, not the selected frame's buffer. */
7850 Lisp_Object mini_window;
7851 struct frame *f, *sf = SELECTED_FRAME ();
7852
7853 /* Get the frame containing the minibuffer
7854 that the selected frame is using. */
7855 mini_window = FRAME_MINIBUF_WINDOW (sf);
7856 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7857
7858 /* A null message buffer means that the frame hasn't really been
7859 initialized yet. Error messages get reported properly by
7860 cmd_error, so this must be just an informative message; toss it. */
7861 if (FRAME_MESSAGE_BUF (f))
7862 {
7863 Lisp_Object args[2], message;
7864 struct gcpro gcpro1, gcpro2;
7865
7866 args[0] = build_string (m);
7867 args[1] = message = string;
7868 GCPRO2 (args[0], message);
7869 gcpro1.nvars = 2;
7870
7871 message = Fformat (2, args);
7872
7873 if (log)
7874 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7875 else
7876 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7877
7878 UNGCPRO;
7879
7880 /* Print should start at the beginning of the message
7881 buffer next time. */
7882 message_buf_print = 0;
7883 }
7884 }
7885 }
7886
7887
7888 /* Dump an informative message to the minibuf. If M is 0, clear out
7889 any existing message, and let the mini-buffer text show through. */
7890
7891 /* VARARGS 1 */
7892 void
7893 message (m, a1, a2, a3)
7894 char *m;
7895 EMACS_INT a1, a2, a3;
7896 {
7897 if (noninteractive)
7898 {
7899 if (m)
7900 {
7901 if (noninteractive_need_newline)
7902 putc ('\n', stderr);
7903 noninteractive_need_newline = 0;
7904 fprintf (stderr, m, a1, a2, a3);
7905 if (cursor_in_echo_area == 0)
7906 fprintf (stderr, "\n");
7907 fflush (stderr);
7908 }
7909 }
7910 else if (INTERACTIVE)
7911 {
7912 /* The frame whose mini-buffer we're going to display the message
7913 on. It may be larger than the selected frame, so we need to
7914 use its buffer, not the selected frame's buffer. */
7915 Lisp_Object mini_window;
7916 struct frame *f, *sf = SELECTED_FRAME ();
7917
7918 /* Get the frame containing the mini-buffer
7919 that the selected frame is using. */
7920 mini_window = FRAME_MINIBUF_WINDOW (sf);
7921 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7922
7923 /* A null message buffer means that the frame hasn't really been
7924 initialized yet. Error messages get reported properly by
7925 cmd_error, so this must be just an informative message; toss
7926 it. */
7927 if (FRAME_MESSAGE_BUF (f))
7928 {
7929 if (m)
7930 {
7931 int len;
7932 #ifdef NO_ARG_ARRAY
7933 char *a[3];
7934 a[0] = (char *) a1;
7935 a[1] = (char *) a2;
7936 a[2] = (char *) a3;
7937
7938 len = doprnt (FRAME_MESSAGE_BUF (f),
7939 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7940 #else
7941 len = doprnt (FRAME_MESSAGE_BUF (f),
7942 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7943 (char **) &a1);
7944 #endif /* NO_ARG_ARRAY */
7945
7946 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7947 }
7948 else
7949 message1 (0);
7950
7951 /* Print should start at the beginning of the message
7952 buffer next time. */
7953 message_buf_print = 0;
7954 }
7955 }
7956 }
7957
7958
7959 /* The non-logging version of message. */
7960
7961 void
7962 message_nolog (m, a1, a2, a3)
7963 char *m;
7964 EMACS_INT a1, a2, a3;
7965 {
7966 Lisp_Object old_log_max;
7967 old_log_max = Vmessage_log_max;
7968 Vmessage_log_max = Qnil;
7969 message (m, a1, a2, a3);
7970 Vmessage_log_max = old_log_max;
7971 }
7972
7973
7974 /* Display the current message in the current mini-buffer. This is
7975 only called from error handlers in process.c, and is not time
7976 critical. */
7977
7978 void
7979 update_echo_area ()
7980 {
7981 if (!NILP (echo_area_buffer[0]))
7982 {
7983 Lisp_Object string;
7984 string = Fcurrent_message ();
7985 message3 (string, SBYTES (string),
7986 !NILP (current_buffer->enable_multibyte_characters));
7987 }
7988 }
7989
7990
7991 /* Make sure echo area buffers in `echo_buffers' are live.
7992 If they aren't, make new ones. */
7993
7994 static void
7995 ensure_echo_area_buffers ()
7996 {
7997 int i;
7998
7999 for (i = 0; i < 2; ++i)
8000 if (!BUFFERP (echo_buffer[i])
8001 || NILP (XBUFFER (echo_buffer[i])->name))
8002 {
8003 char name[30];
8004 Lisp_Object old_buffer;
8005 int j;
8006
8007 old_buffer = echo_buffer[i];
8008 sprintf (name, " *Echo Area %d*", i);
8009 echo_buffer[i] = Fget_buffer_create (build_string (name));
8010 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
8011
8012 for (j = 0; j < 2; ++j)
8013 if (EQ (old_buffer, echo_area_buffer[j]))
8014 echo_area_buffer[j] = echo_buffer[i];
8015 }
8016 }
8017
8018
8019 /* Call FN with args A1..A4 with either the current or last displayed
8020 echo_area_buffer as current buffer.
8021
8022 WHICH zero means use the current message buffer
8023 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8024 from echo_buffer[] and clear it.
8025
8026 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8027 suitable buffer from echo_buffer[] and clear it.
8028
8029 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8030 that the current message becomes the last displayed one, make
8031 choose a suitable buffer for echo_area_buffer[0], and clear it.
8032
8033 Value is what FN returns. */
8034
8035 static int
8036 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
8037 struct window *w;
8038 int which;
8039 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
8040 EMACS_INT a1;
8041 Lisp_Object a2;
8042 EMACS_INT a3, a4;
8043 {
8044 Lisp_Object buffer;
8045 int this_one, the_other, clear_buffer_p, rc;
8046 int count = SPECPDL_INDEX ();
8047
8048 /* If buffers aren't live, make new ones. */
8049 ensure_echo_area_buffers ();
8050
8051 clear_buffer_p = 0;
8052
8053 if (which == 0)
8054 this_one = 0, the_other = 1;
8055 else if (which > 0)
8056 this_one = 1, the_other = 0;
8057 else
8058 {
8059 this_one = 0, the_other = 1;
8060 clear_buffer_p = 1;
8061
8062 /* We need a fresh one in case the current echo buffer equals
8063 the one containing the last displayed echo area message. */
8064 if (!NILP (echo_area_buffer[this_one])
8065 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8066 echo_area_buffer[this_one] = Qnil;
8067 }
8068
8069 /* Choose a suitable buffer from echo_buffer[] is we don't
8070 have one. */
8071 if (NILP (echo_area_buffer[this_one]))
8072 {
8073 echo_area_buffer[this_one]
8074 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8075 ? echo_buffer[the_other]
8076 : echo_buffer[this_one]);
8077 clear_buffer_p = 1;
8078 }
8079
8080 buffer = echo_area_buffer[this_one];
8081
8082 /* Don't get confused by reusing the buffer used for echoing
8083 for a different purpose. */
8084 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8085 cancel_echoing ();
8086
8087 record_unwind_protect (unwind_with_echo_area_buffer,
8088 with_echo_area_buffer_unwind_data (w));
8089
8090 /* Make the echo area buffer current. Note that for display
8091 purposes, it is not necessary that the displayed window's buffer
8092 == current_buffer, except for text property lookup. So, let's
8093 only set that buffer temporarily here without doing a full
8094 Fset_window_buffer. We must also change w->pointm, though,
8095 because otherwise an assertions in unshow_buffer fails, and Emacs
8096 aborts. */
8097 set_buffer_internal_1 (XBUFFER (buffer));
8098 if (w)
8099 {
8100 w->buffer = buffer;
8101 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8102 }
8103
8104 current_buffer->undo_list = Qt;
8105 current_buffer->read_only = Qnil;
8106 specbind (Qinhibit_read_only, Qt);
8107 specbind (Qinhibit_modification_hooks, Qt);
8108
8109 if (clear_buffer_p && Z > BEG)
8110 del_range (BEG, Z);
8111
8112 xassert (BEGV >= BEG);
8113 xassert (ZV <= Z && ZV >= BEGV);
8114
8115 rc = fn (a1, a2, a3, a4);
8116
8117 xassert (BEGV >= BEG);
8118 xassert (ZV <= Z && ZV >= BEGV);
8119
8120 unbind_to (count, Qnil);
8121 return rc;
8122 }
8123
8124
8125 /* Save state that should be preserved around the call to the function
8126 FN called in with_echo_area_buffer. */
8127
8128 static Lisp_Object
8129 with_echo_area_buffer_unwind_data (w)
8130 struct window *w;
8131 {
8132 int i = 0;
8133 Lisp_Object vector;
8134
8135 /* Reduce consing by keeping one vector in
8136 Vwith_echo_area_save_vector. */
8137 vector = Vwith_echo_area_save_vector;
8138 Vwith_echo_area_save_vector = Qnil;
8139
8140 if (NILP (vector))
8141 vector = Fmake_vector (make_number (7), Qnil);
8142
8143 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
8144 AREF (vector, i) = Vdeactivate_mark, ++i;
8145 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
8146
8147 if (w)
8148 {
8149 XSETWINDOW (AREF (vector, i), w); ++i;
8150 AREF (vector, i) = w->buffer; ++i;
8151 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
8152 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
8153 }
8154 else
8155 {
8156 int end = i + 4;
8157 for (; i < end; ++i)
8158 AREF (vector, i) = Qnil;
8159 }
8160
8161 xassert (i == ASIZE (vector));
8162 return vector;
8163 }
8164
8165
8166 /* Restore global state from VECTOR which was created by
8167 with_echo_area_buffer_unwind_data. */
8168
8169 static Lisp_Object
8170 unwind_with_echo_area_buffer (vector)
8171 Lisp_Object vector;
8172 {
8173 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8174 Vdeactivate_mark = AREF (vector, 1);
8175 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8176
8177 if (WINDOWP (AREF (vector, 3)))
8178 {
8179 struct window *w;
8180 Lisp_Object buffer, charpos, bytepos;
8181
8182 w = XWINDOW (AREF (vector, 3));
8183 buffer = AREF (vector, 4);
8184 charpos = AREF (vector, 5);
8185 bytepos = AREF (vector, 6);
8186
8187 w->buffer = buffer;
8188 set_marker_both (w->pointm, buffer,
8189 XFASTINT (charpos), XFASTINT (bytepos));
8190 }
8191
8192 Vwith_echo_area_save_vector = vector;
8193 return Qnil;
8194 }
8195
8196
8197 /* Set up the echo area for use by print functions. MULTIBYTE_P
8198 non-zero means we will print multibyte. */
8199
8200 void
8201 setup_echo_area_for_printing (multibyte_p)
8202 int multibyte_p;
8203 {
8204 /* If we can't find an echo area any more, exit. */
8205 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8206 Fkill_emacs (Qnil);
8207
8208 ensure_echo_area_buffers ();
8209
8210 if (!message_buf_print)
8211 {
8212 /* A message has been output since the last time we printed.
8213 Choose a fresh echo area buffer. */
8214 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8215 echo_area_buffer[0] = echo_buffer[1];
8216 else
8217 echo_area_buffer[0] = echo_buffer[0];
8218
8219 /* Switch to that buffer and clear it. */
8220 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8221 current_buffer->truncate_lines = Qnil;
8222
8223 if (Z > BEG)
8224 {
8225 int count = SPECPDL_INDEX ();
8226 specbind (Qinhibit_read_only, Qt);
8227 /* Note that undo recording is always disabled. */
8228 del_range (BEG, Z);
8229 unbind_to (count, Qnil);
8230 }
8231 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8232
8233 /* Set up the buffer for the multibyteness we need. */
8234 if (multibyte_p
8235 != !NILP (current_buffer->enable_multibyte_characters))
8236 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8237
8238 /* Raise the frame containing the echo area. */
8239 if (minibuffer_auto_raise)
8240 {
8241 struct frame *sf = SELECTED_FRAME ();
8242 Lisp_Object mini_window;
8243 mini_window = FRAME_MINIBUF_WINDOW (sf);
8244 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8245 }
8246
8247 message_log_maybe_newline ();
8248 message_buf_print = 1;
8249 }
8250 else
8251 {
8252 if (NILP (echo_area_buffer[0]))
8253 {
8254 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8255 echo_area_buffer[0] = echo_buffer[1];
8256 else
8257 echo_area_buffer[0] = echo_buffer[0];
8258 }
8259
8260 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8261 {
8262 /* Someone switched buffers between print requests. */
8263 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8264 current_buffer->truncate_lines = Qnil;
8265 }
8266 }
8267 }
8268
8269
8270 /* Display an echo area message in window W. Value is non-zero if W's
8271 height is changed. If display_last_displayed_message_p is
8272 non-zero, display the message that was last displayed, otherwise
8273 display the current message. */
8274
8275 static int
8276 display_echo_area (w)
8277 struct window *w;
8278 {
8279 int i, no_message_p, window_height_changed_p, count;
8280
8281 /* Temporarily disable garbage collections while displaying the echo
8282 area. This is done because a GC can print a message itself.
8283 That message would modify the echo area buffer's contents while a
8284 redisplay of the buffer is going on, and seriously confuse
8285 redisplay. */
8286 count = inhibit_garbage_collection ();
8287
8288 /* If there is no message, we must call display_echo_area_1
8289 nevertheless because it resizes the window. But we will have to
8290 reset the echo_area_buffer in question to nil at the end because
8291 with_echo_area_buffer will sets it to an empty buffer. */
8292 i = display_last_displayed_message_p ? 1 : 0;
8293 no_message_p = NILP (echo_area_buffer[i]);
8294
8295 window_height_changed_p
8296 = with_echo_area_buffer (w, display_last_displayed_message_p,
8297 display_echo_area_1,
8298 (EMACS_INT) w, Qnil, 0, 0);
8299
8300 if (no_message_p)
8301 echo_area_buffer[i] = Qnil;
8302
8303 unbind_to (count, Qnil);
8304 return window_height_changed_p;
8305 }
8306
8307
8308 /* Helper for display_echo_area. Display the current buffer which
8309 contains the current echo area message in window W, a mini-window,
8310 a pointer to which is passed in A1. A2..A4 are currently not used.
8311 Change the height of W so that all of the message is displayed.
8312 Value is non-zero if height of W was changed. */
8313
8314 static int
8315 display_echo_area_1 (a1, a2, a3, a4)
8316 EMACS_INT a1;
8317 Lisp_Object a2;
8318 EMACS_INT a3, a4;
8319 {
8320 struct window *w = (struct window *) a1;
8321 Lisp_Object window;
8322 struct text_pos start;
8323 int window_height_changed_p = 0;
8324
8325 /* Do this before displaying, so that we have a large enough glyph
8326 matrix for the display. If we can't get enough space for the
8327 whole text, display the last N lines. That works by setting w->start. */
8328 window_height_changed_p = resize_mini_window (w, 0);
8329
8330 /* Use the starting position chosen by resize_mini_window. */
8331 SET_TEXT_POS_FROM_MARKER (start, w->start);
8332
8333 /* Display. */
8334 clear_glyph_matrix (w->desired_matrix);
8335 XSETWINDOW (window, w);
8336 try_window (window, start, 0);
8337
8338 return window_height_changed_p;
8339 }
8340
8341
8342 /* Resize the echo area window to exactly the size needed for the
8343 currently displayed message, if there is one. If a mini-buffer
8344 is active, don't shrink it. */
8345
8346 void
8347 resize_echo_area_exactly ()
8348 {
8349 if (BUFFERP (echo_area_buffer[0])
8350 && WINDOWP (echo_area_window))
8351 {
8352 struct window *w = XWINDOW (echo_area_window);
8353 int resized_p;
8354 Lisp_Object resize_exactly;
8355
8356 if (minibuf_level == 0)
8357 resize_exactly = Qt;
8358 else
8359 resize_exactly = Qnil;
8360
8361 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8362 (EMACS_INT) w, resize_exactly, 0, 0);
8363 if (resized_p)
8364 {
8365 ++windows_or_buffers_changed;
8366 ++update_mode_lines;
8367 redisplay_internal (0);
8368 }
8369 }
8370 }
8371
8372
8373 /* Callback function for with_echo_area_buffer, when used from
8374 resize_echo_area_exactly. A1 contains a pointer to the window to
8375 resize, EXACTLY non-nil means resize the mini-window exactly to the
8376 size of the text displayed. A3 and A4 are not used. Value is what
8377 resize_mini_window returns. */
8378
8379 static int
8380 resize_mini_window_1 (a1, exactly, a3, a4)
8381 EMACS_INT a1;
8382 Lisp_Object exactly;
8383 EMACS_INT a3, a4;
8384 {
8385 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8386 }
8387
8388
8389 /* Resize mini-window W to fit the size of its contents. EXACT:P
8390 means size the window exactly to the size needed. Otherwise, it's
8391 only enlarged until W's buffer is empty.
8392
8393 Set W->start to the right place to begin display. If the whole
8394 contents fit, start at the beginning. Otherwise, start so as
8395 to make the end of the contents appear. This is particularly
8396 important for y-or-n-p, but seems desirable generally.
8397
8398 Value is non-zero if the window height has been changed. */
8399
8400 int
8401 resize_mini_window (w, exact_p)
8402 struct window *w;
8403 int exact_p;
8404 {
8405 struct frame *f = XFRAME (w->frame);
8406 int window_height_changed_p = 0;
8407
8408 xassert (MINI_WINDOW_P (w));
8409
8410 /* By default, start display at the beginning. */
8411 set_marker_both (w->start, w->buffer,
8412 BUF_BEGV (XBUFFER (w->buffer)),
8413 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8414
8415 /* Don't resize windows while redisplaying a window; it would
8416 confuse redisplay functions when the size of the window they are
8417 displaying changes from under them. Such a resizing can happen,
8418 for instance, when which-func prints a long message while
8419 we are running fontification-functions. We're running these
8420 functions with safe_call which binds inhibit-redisplay to t. */
8421 if (!NILP (Vinhibit_redisplay))
8422 return 0;
8423
8424 /* Nil means don't try to resize. */
8425 if (NILP (Vresize_mini_windows)
8426 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8427 return 0;
8428
8429 if (!FRAME_MINIBUF_ONLY_P (f))
8430 {
8431 struct it it;
8432 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8433 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8434 int height, max_height;
8435 int unit = FRAME_LINE_HEIGHT (f);
8436 struct text_pos start;
8437 struct buffer *old_current_buffer = NULL;
8438
8439 if (current_buffer != XBUFFER (w->buffer))
8440 {
8441 old_current_buffer = current_buffer;
8442 set_buffer_internal (XBUFFER (w->buffer));
8443 }
8444
8445 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8446
8447 /* Compute the max. number of lines specified by the user. */
8448 if (FLOATP (Vmax_mini_window_height))
8449 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8450 else if (INTEGERP (Vmax_mini_window_height))
8451 max_height = XINT (Vmax_mini_window_height);
8452 else
8453 max_height = total_height / 4;
8454
8455 /* Correct that max. height if it's bogus. */
8456 max_height = max (1, max_height);
8457 max_height = min (total_height, max_height);
8458
8459 /* Find out the height of the text in the window. */
8460 if (it.truncate_lines_p)
8461 height = 1;
8462 else
8463 {
8464 last_height = 0;
8465 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
8466 if (it.max_ascent == 0 && it.max_descent == 0)
8467 height = it.current_y + last_height;
8468 else
8469 height = it.current_y + it.max_ascent + it.max_descent;
8470 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
8471 height = (height + unit - 1) / unit;
8472 }
8473
8474 /* Compute a suitable window start. */
8475 if (height > max_height)
8476 {
8477 height = max_height;
8478 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
8479 move_it_vertically_backward (&it, (height - 1) * unit);
8480 start = it.current.pos;
8481 }
8482 else
8483 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
8484 SET_MARKER_FROM_TEXT_POS (w->start, start);
8485
8486 if (EQ (Vresize_mini_windows, Qgrow_only))
8487 {
8488 /* Let it grow only, until we display an empty message, in which
8489 case the window shrinks again. */
8490 if (height > WINDOW_TOTAL_LINES (w))
8491 {
8492 int old_height = WINDOW_TOTAL_LINES (w);
8493 freeze_window_starts (f, 1);
8494 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8495 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8496 }
8497 else if (height < WINDOW_TOTAL_LINES (w)
8498 && (exact_p || BEGV == ZV))
8499 {
8500 int old_height = WINDOW_TOTAL_LINES (w);
8501 freeze_window_starts (f, 0);
8502 shrink_mini_window (w);
8503 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8504 }
8505 }
8506 else
8507 {
8508 /* Always resize to exact size needed. */
8509 if (height > WINDOW_TOTAL_LINES (w))
8510 {
8511 int old_height = WINDOW_TOTAL_LINES (w);
8512 freeze_window_starts (f, 1);
8513 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8514 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8515 }
8516 else if (height < WINDOW_TOTAL_LINES (w))
8517 {
8518 int old_height = WINDOW_TOTAL_LINES (w);
8519 freeze_window_starts (f, 0);
8520 shrink_mini_window (w);
8521
8522 if (height)
8523 {
8524 freeze_window_starts (f, 1);
8525 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8526 }
8527
8528 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8529 }
8530 }
8531
8532 if (old_current_buffer)
8533 set_buffer_internal (old_current_buffer);
8534 }
8535
8536 return window_height_changed_p;
8537 }
8538
8539
8540 /* Value is the current message, a string, or nil if there is no
8541 current message. */
8542
8543 Lisp_Object
8544 current_message ()
8545 {
8546 Lisp_Object msg;
8547
8548 if (NILP (echo_area_buffer[0]))
8549 msg = Qnil;
8550 else
8551 {
8552 with_echo_area_buffer (0, 0, current_message_1,
8553 (EMACS_INT) &msg, Qnil, 0, 0);
8554 if (NILP (msg))
8555 echo_area_buffer[0] = Qnil;
8556 }
8557
8558 return msg;
8559 }
8560
8561
8562 static int
8563 current_message_1 (a1, a2, a3, a4)
8564 EMACS_INT a1;
8565 Lisp_Object a2;
8566 EMACS_INT a3, a4;
8567 {
8568 Lisp_Object *msg = (Lisp_Object *) a1;
8569
8570 if (Z > BEG)
8571 *msg = make_buffer_string (BEG, Z, 1);
8572 else
8573 *msg = Qnil;
8574 return 0;
8575 }
8576
8577
8578 /* Push the current message on Vmessage_stack for later restauration
8579 by restore_message. Value is non-zero if the current message isn't
8580 empty. This is a relatively infrequent operation, so it's not
8581 worth optimizing. */
8582
8583 int
8584 push_message ()
8585 {
8586 Lisp_Object msg;
8587 msg = current_message ();
8588 Vmessage_stack = Fcons (msg, Vmessage_stack);
8589 return STRINGP (msg);
8590 }
8591
8592
8593 /* Restore message display from the top of Vmessage_stack. */
8594
8595 void
8596 restore_message ()
8597 {
8598 Lisp_Object msg;
8599
8600 xassert (CONSP (Vmessage_stack));
8601 msg = XCAR (Vmessage_stack);
8602 if (STRINGP (msg))
8603 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8604 else
8605 message3_nolog (msg, 0, 0);
8606 }
8607
8608
8609 /* Handler for record_unwind_protect calling pop_message. */
8610
8611 Lisp_Object
8612 pop_message_unwind (dummy)
8613 Lisp_Object dummy;
8614 {
8615 pop_message ();
8616 return Qnil;
8617 }
8618
8619 /* Pop the top-most entry off Vmessage_stack. */
8620
8621 void
8622 pop_message ()
8623 {
8624 xassert (CONSP (Vmessage_stack));
8625 Vmessage_stack = XCDR (Vmessage_stack);
8626 }
8627
8628
8629 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
8630 exits. If the stack is not empty, we have a missing pop_message
8631 somewhere. */
8632
8633 void
8634 check_message_stack ()
8635 {
8636 if (!NILP (Vmessage_stack))
8637 abort ();
8638 }
8639
8640
8641 /* Truncate to NCHARS what will be displayed in the echo area the next
8642 time we display it---but don't redisplay it now. */
8643
8644 void
8645 truncate_echo_area (nchars)
8646 int nchars;
8647 {
8648 if (nchars == 0)
8649 echo_area_buffer[0] = Qnil;
8650 /* A null message buffer means that the frame hasn't really been
8651 initialized yet. Error messages get reported properly by
8652 cmd_error, so this must be just an informative message; toss it. */
8653 else if (!noninteractive
8654 && INTERACTIVE
8655 && !NILP (echo_area_buffer[0]))
8656 {
8657 struct frame *sf = SELECTED_FRAME ();
8658 if (FRAME_MESSAGE_BUF (sf))
8659 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
8660 }
8661 }
8662
8663
8664 /* Helper function for truncate_echo_area. Truncate the current
8665 message to at most NCHARS characters. */
8666
8667 static int
8668 truncate_message_1 (nchars, a2, a3, a4)
8669 EMACS_INT nchars;
8670 Lisp_Object a2;
8671 EMACS_INT a3, a4;
8672 {
8673 if (BEG + nchars < Z)
8674 del_range (BEG + nchars, Z);
8675 if (Z == BEG)
8676 echo_area_buffer[0] = Qnil;
8677 return 0;
8678 }
8679
8680
8681 /* Set the current message to a substring of S or STRING.
8682
8683 If STRING is a Lisp string, set the message to the first NBYTES
8684 bytes from STRING. NBYTES zero means use the whole string. If
8685 STRING is multibyte, the message will be displayed multibyte.
8686
8687 If S is not null, set the message to the first LEN bytes of S. LEN
8688 zero means use the whole string. MULTIBYTE_P non-zero means S is
8689 multibyte. Display the message multibyte in that case.
8690
8691 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
8692 to t before calling set_message_1 (which calls insert).
8693 */
8694
8695 void
8696 set_message (s, string, nbytes, multibyte_p)
8697 const char *s;
8698 Lisp_Object string;
8699 int nbytes, multibyte_p;
8700 {
8701 message_enable_multibyte
8702 = ((s && multibyte_p)
8703 || (STRINGP (string) && STRING_MULTIBYTE (string)));
8704
8705 with_echo_area_buffer (0, -1, set_message_1,
8706 (EMACS_INT) s, string, nbytes, multibyte_p);
8707 message_buf_print = 0;
8708 help_echo_showing_p = 0;
8709 }
8710
8711
8712 /* Helper function for set_message. Arguments have the same meaning
8713 as there, with A1 corresponding to S and A2 corresponding to STRING
8714 This function is called with the echo area buffer being
8715 current. */
8716
8717 static int
8718 set_message_1 (a1, a2, nbytes, multibyte_p)
8719 EMACS_INT a1;
8720 Lisp_Object a2;
8721 EMACS_INT nbytes, multibyte_p;
8722 {
8723 const char *s = (const char *) a1;
8724 Lisp_Object string = a2;
8725
8726 /* Change multibyteness of the echo buffer appropriately. */
8727 if (message_enable_multibyte
8728 != !NILP (current_buffer->enable_multibyte_characters))
8729 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
8730
8731 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
8732
8733 /* Insert new message at BEG. */
8734 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8735
8736 if (STRINGP (string))
8737 {
8738 int nchars;
8739
8740 if (nbytes == 0)
8741 nbytes = SBYTES (string);
8742 nchars = string_byte_to_char (string, nbytes);
8743
8744 /* This function takes care of single/multibyte conversion. We
8745 just have to ensure that the echo area buffer has the right
8746 setting of enable_multibyte_characters. */
8747 insert_from_string (string, 0, 0, nchars, nbytes, 1);
8748 }
8749 else if (s)
8750 {
8751 if (nbytes == 0)
8752 nbytes = strlen (s);
8753
8754 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
8755 {
8756 /* Convert from multi-byte to single-byte. */
8757 int i, c, n;
8758 unsigned char work[1];
8759
8760 /* Convert a multibyte string to single-byte. */
8761 for (i = 0; i < nbytes; i += n)
8762 {
8763 c = string_char_and_length (s + i, nbytes - i, &n);
8764 work[0] = (ASCII_CHAR_P (c)
8765 ? c
8766 : multibyte_char_to_unibyte (c, Qnil));
8767 insert_1_both (work, 1, 1, 1, 0, 0);
8768 }
8769 }
8770 else if (!multibyte_p
8771 && !NILP (current_buffer->enable_multibyte_characters))
8772 {
8773 /* Convert from single-byte to multi-byte. */
8774 int i, c, n;
8775 const unsigned char *msg = (const unsigned char *) s;
8776 unsigned char str[MAX_MULTIBYTE_LENGTH];
8777
8778 /* Convert a single-byte string to multibyte. */
8779 for (i = 0; i < nbytes; i++)
8780 {
8781 c = msg[i];
8782 c = unibyte_char_to_multibyte (c);
8783 n = CHAR_STRING (c, str);
8784 insert_1_both (str, 1, n, 1, 0, 0);
8785 }
8786 }
8787 else
8788 insert_1 (s, nbytes, 1, 0, 0);
8789 }
8790
8791 return 0;
8792 }
8793
8794
8795 /* Clear messages. CURRENT_P non-zero means clear the current
8796 message. LAST_DISPLAYED_P non-zero means clear the message
8797 last displayed. */
8798
8799 void
8800 clear_message (current_p, last_displayed_p)
8801 int current_p, last_displayed_p;
8802 {
8803 if (current_p)
8804 {
8805 echo_area_buffer[0] = Qnil;
8806 message_cleared_p = 1;
8807 }
8808
8809 if (last_displayed_p)
8810 echo_area_buffer[1] = Qnil;
8811
8812 message_buf_print = 0;
8813 }
8814
8815 /* Clear garbaged frames.
8816
8817 This function is used where the old redisplay called
8818 redraw_garbaged_frames which in turn called redraw_frame which in
8819 turn called clear_frame. The call to clear_frame was a source of
8820 flickering. I believe a clear_frame is not necessary. It should
8821 suffice in the new redisplay to invalidate all current matrices,
8822 and ensure a complete redisplay of all windows. */
8823
8824 static void
8825 clear_garbaged_frames ()
8826 {
8827 if (frame_garbaged)
8828 {
8829 Lisp_Object tail, frame;
8830 int changed_count = 0;
8831
8832 FOR_EACH_FRAME (tail, frame)
8833 {
8834 struct frame *f = XFRAME (frame);
8835
8836 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8837 {
8838 if (f->resized_p)
8839 {
8840 Fredraw_frame (frame);
8841 f->force_flush_display_p = 1;
8842 }
8843 clear_current_matrices (f);
8844 changed_count++;
8845 f->garbaged = 0;
8846 f->resized_p = 0;
8847 }
8848 }
8849
8850 frame_garbaged = 0;
8851 if (changed_count)
8852 ++windows_or_buffers_changed;
8853 }
8854 }
8855
8856
8857 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8858 is non-zero update selected_frame. Value is non-zero if the
8859 mini-windows height has been changed. */
8860
8861 static int
8862 echo_area_display (update_frame_p)
8863 int update_frame_p;
8864 {
8865 Lisp_Object mini_window;
8866 struct window *w;
8867 struct frame *f;
8868 int window_height_changed_p = 0;
8869 struct frame *sf = SELECTED_FRAME ();
8870
8871 mini_window = FRAME_MINIBUF_WINDOW (sf);
8872 w = XWINDOW (mini_window);
8873 f = XFRAME (WINDOW_FRAME (w));
8874
8875 /* Don't display if frame is invisible or not yet initialized. */
8876 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8877 return 0;
8878
8879 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8880 #ifndef MAC_OS8
8881 #ifdef HAVE_WINDOW_SYSTEM
8882 /* When Emacs starts, selected_frame may be the initial terminal
8883 frame. If we let this through, a message would be displayed on
8884 the terminal. */
8885 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
8886 return 0;
8887 #endif /* HAVE_WINDOW_SYSTEM */
8888 #endif
8889
8890 /* Redraw garbaged frames. */
8891 if (frame_garbaged)
8892 clear_garbaged_frames ();
8893
8894 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8895 {
8896 echo_area_window = mini_window;
8897 window_height_changed_p = display_echo_area (w);
8898 w->must_be_updated_p = 1;
8899
8900 /* Update the display, unless called from redisplay_internal.
8901 Also don't update the screen during redisplay itself. The
8902 update will happen at the end of redisplay, and an update
8903 here could cause confusion. */
8904 if (update_frame_p && !redisplaying_p)
8905 {
8906 int n = 0;
8907
8908 /* If the display update has been interrupted by pending
8909 input, update mode lines in the frame. Due to the
8910 pending input, it might have been that redisplay hasn't
8911 been called, so that mode lines above the echo area are
8912 garbaged. This looks odd, so we prevent it here. */
8913 if (!display_completed)
8914 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8915
8916 if (window_height_changed_p
8917 /* Don't do this if Emacs is shutting down. Redisplay
8918 needs to run hooks. */
8919 && !NILP (Vrun_hooks))
8920 {
8921 /* Must update other windows. Likewise as in other
8922 cases, don't let this update be interrupted by
8923 pending input. */
8924 int count = SPECPDL_INDEX ();
8925 specbind (Qredisplay_dont_pause, Qt);
8926 windows_or_buffers_changed = 1;
8927 redisplay_internal (0);
8928 unbind_to (count, Qnil);
8929 }
8930 else if (FRAME_WINDOW_P (f) && n == 0)
8931 {
8932 /* Window configuration is the same as before.
8933 Can do with a display update of the echo area,
8934 unless we displayed some mode lines. */
8935 update_single_window (w, 1);
8936 FRAME_RIF (f)->flush_display (f);
8937 }
8938 else
8939 update_frame (f, 1, 1);
8940
8941 /* If cursor is in the echo area, make sure that the next
8942 redisplay displays the minibuffer, so that the cursor will
8943 be replaced with what the minibuffer wants. */
8944 if (cursor_in_echo_area)
8945 ++windows_or_buffers_changed;
8946 }
8947 }
8948 else if (!EQ (mini_window, selected_window))
8949 windows_or_buffers_changed++;
8950
8951 /* Last displayed message is now the current message. */
8952 echo_area_buffer[1] = echo_area_buffer[0];
8953 /* Inform read_char that we're not echoing. */
8954 echo_message_buffer = Qnil;
8955
8956 /* Prevent redisplay optimization in redisplay_internal by resetting
8957 this_line_start_pos. This is done because the mini-buffer now
8958 displays the message instead of its buffer text. */
8959 if (EQ (mini_window, selected_window))
8960 CHARPOS (this_line_start_pos) = 0;
8961
8962 return window_height_changed_p;
8963 }
8964
8965
8966 \f
8967 /***********************************************************************
8968 Mode Lines and Frame Titles
8969 ***********************************************************************/
8970
8971 /* A buffer for constructing non-propertized mode-line strings and
8972 frame titles in it; allocated from the heap in init_xdisp and
8973 resized as needed in store_mode_line_noprop_char. */
8974
8975 static char *mode_line_noprop_buf;
8976
8977 /* The buffer's end, and a current output position in it. */
8978
8979 static char *mode_line_noprop_buf_end;
8980 static char *mode_line_noprop_ptr;
8981
8982 #define MODE_LINE_NOPROP_LEN(start) \
8983 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
8984
8985 static enum {
8986 MODE_LINE_DISPLAY = 0,
8987 MODE_LINE_TITLE,
8988 MODE_LINE_NOPROP,
8989 MODE_LINE_STRING
8990 } mode_line_target;
8991
8992 /* Alist that caches the results of :propertize.
8993 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
8994 static Lisp_Object mode_line_proptrans_alist;
8995
8996 /* List of strings making up the mode-line. */
8997 static Lisp_Object mode_line_string_list;
8998
8999 /* Base face property when building propertized mode line string. */
9000 static Lisp_Object mode_line_string_face;
9001 static Lisp_Object mode_line_string_face_prop;
9002
9003
9004 /* Unwind data for mode line strings */
9005
9006 static Lisp_Object Vmode_line_unwind_vector;
9007
9008 static Lisp_Object
9009 format_mode_line_unwind_data (obuf, save_proptrans)
9010 struct buffer *obuf;
9011 {
9012 Lisp_Object vector;
9013
9014 /* Reduce consing by keeping one vector in
9015 Vwith_echo_area_save_vector. */
9016 vector = Vmode_line_unwind_vector;
9017 Vmode_line_unwind_vector = Qnil;
9018
9019 if (NILP (vector))
9020 vector = Fmake_vector (make_number (7), Qnil);
9021
9022 AREF (vector, 0) = make_number (mode_line_target);
9023 AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
9024 AREF (vector, 2) = mode_line_string_list;
9025 AREF (vector, 3) = (save_proptrans ? mode_line_proptrans_alist : Qt);
9026 AREF (vector, 4) = mode_line_string_face;
9027 AREF (vector, 5) = mode_line_string_face_prop;
9028
9029 if (obuf)
9030 XSETBUFFER (AREF (vector, 6), obuf);
9031 else
9032 AREF (vector, 6) = Qnil;
9033
9034 return vector;
9035 }
9036
9037 static Lisp_Object
9038 unwind_format_mode_line (vector)
9039 Lisp_Object vector;
9040 {
9041 mode_line_target = XINT (AREF (vector, 0));
9042 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9043 mode_line_string_list = AREF (vector, 2);
9044 if (! EQ (AREF (vector, 3), Qt))
9045 mode_line_proptrans_alist = AREF (vector, 3);
9046 mode_line_string_face = AREF (vector, 4);
9047 mode_line_string_face_prop = AREF (vector, 5);
9048
9049 if (!NILP (AREF (vector, 6)))
9050 {
9051 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9052 AREF (vector, 6) = Qnil;
9053 }
9054
9055 Vmode_line_unwind_vector = vector;
9056 return Qnil;
9057 }
9058
9059
9060 /* Store a single character C for the frame title in mode_line_noprop_buf.
9061 Re-allocate mode_line_noprop_buf if necessary. */
9062
9063 static void
9064 #ifdef PROTOTYPES
9065 store_mode_line_noprop_char (char c)
9066 #else
9067 store_mode_line_noprop_char (c)
9068 char c;
9069 #endif
9070 {
9071 /* If output position has reached the end of the allocated buffer,
9072 double the buffer's size. */
9073 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9074 {
9075 int len = MODE_LINE_NOPROP_LEN (0);
9076 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9077 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9078 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9079 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9080 }
9081
9082 *mode_line_noprop_ptr++ = c;
9083 }
9084
9085
9086 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9087 mode_line_noprop_ptr. STR is the string to store. Do not copy
9088 characters that yield more columns than PRECISION; PRECISION <= 0
9089 means copy the whole string. Pad with spaces until FIELD_WIDTH
9090 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9091 pad. Called from display_mode_element when it is used to build a
9092 frame title. */
9093
9094 static int
9095 store_mode_line_noprop (str, field_width, precision)
9096 const unsigned char *str;
9097 int field_width, precision;
9098 {
9099 int n = 0;
9100 int dummy, nbytes;
9101
9102 /* Copy at most PRECISION chars from STR. */
9103 nbytes = strlen (str);
9104 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9105 while (nbytes--)
9106 store_mode_line_noprop_char (*str++);
9107
9108 /* Fill up with spaces until FIELD_WIDTH reached. */
9109 while (field_width > 0
9110 && n < field_width)
9111 {
9112 store_mode_line_noprop_char (' ');
9113 ++n;
9114 }
9115
9116 return n;
9117 }
9118
9119 /***********************************************************************
9120 Frame Titles
9121 ***********************************************************************/
9122
9123 #ifdef HAVE_WINDOW_SYSTEM
9124
9125 /* Set the title of FRAME, if it has changed. The title format is
9126 Vicon_title_format if FRAME is iconified, otherwise it is
9127 frame_title_format. */
9128
9129 static void
9130 x_consider_frame_title (frame)
9131 Lisp_Object frame;
9132 {
9133 struct frame *f = XFRAME (frame);
9134
9135 if (FRAME_WINDOW_P (f)
9136 || FRAME_MINIBUF_ONLY_P (f)
9137 || f->explicit_name)
9138 {
9139 /* Do we have more than one visible frame on this X display? */
9140 Lisp_Object tail;
9141 Lisp_Object fmt;
9142 int title_start;
9143 char *title;
9144 int len;
9145 struct it it;
9146 int count = SPECPDL_INDEX ();
9147
9148 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9149 {
9150 Lisp_Object other_frame = XCAR (tail);
9151 struct frame *tf = XFRAME (other_frame);
9152
9153 if (tf != f
9154 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9155 && !FRAME_MINIBUF_ONLY_P (tf)
9156 && !EQ (other_frame, tip_frame)
9157 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9158 break;
9159 }
9160
9161 /* Set global variable indicating that multiple frames exist. */
9162 multiple_frames = CONSP (tail);
9163
9164 /* Switch to the buffer of selected window of the frame. Set up
9165 mode_line_target so that display_mode_element will output into
9166 mode_line_noprop_buf; then display the title. */
9167 record_unwind_protect (unwind_format_mode_line,
9168 format_mode_line_unwind_data (current_buffer, 0));
9169
9170 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9171 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9172
9173 mode_line_target = MODE_LINE_TITLE;
9174 title_start = MODE_LINE_NOPROP_LEN (0);
9175 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9176 NULL, DEFAULT_FACE_ID);
9177 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9178 len = MODE_LINE_NOPROP_LEN (title_start);
9179 title = mode_line_noprop_buf + title_start;
9180 unbind_to (count, Qnil);
9181
9182 /* Set the title only if it's changed. This avoids consing in
9183 the common case where it hasn't. (If it turns out that we've
9184 already wasted too much time by walking through the list with
9185 display_mode_element, then we might need to optimize at a
9186 higher level than this.) */
9187 if (! STRINGP (f->name)
9188 || SBYTES (f->name) != len
9189 || bcmp (title, SDATA (f->name), len) != 0)
9190 x_implicitly_set_name (f, make_string (title, len), Qnil);
9191 }
9192 }
9193
9194 #endif /* not HAVE_WINDOW_SYSTEM */
9195
9196
9197
9198 \f
9199 /***********************************************************************
9200 Menu Bars
9201 ***********************************************************************/
9202
9203
9204 /* Prepare for redisplay by updating menu-bar item lists when
9205 appropriate. This can call eval. */
9206
9207 void
9208 prepare_menu_bars ()
9209 {
9210 int all_windows;
9211 struct gcpro gcpro1, gcpro2;
9212 struct frame *f;
9213 Lisp_Object tooltip_frame;
9214
9215 #ifdef HAVE_WINDOW_SYSTEM
9216 tooltip_frame = tip_frame;
9217 #else
9218 tooltip_frame = Qnil;
9219 #endif
9220
9221 /* Update all frame titles based on their buffer names, etc. We do
9222 this before the menu bars so that the buffer-menu will show the
9223 up-to-date frame titles. */
9224 #ifdef HAVE_WINDOW_SYSTEM
9225 if (windows_or_buffers_changed || update_mode_lines)
9226 {
9227 Lisp_Object tail, frame;
9228
9229 FOR_EACH_FRAME (tail, frame)
9230 {
9231 f = XFRAME (frame);
9232 if (!EQ (frame, tooltip_frame)
9233 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9234 x_consider_frame_title (frame);
9235 }
9236 }
9237 #endif /* HAVE_WINDOW_SYSTEM */
9238
9239 /* Update the menu bar item lists, if appropriate. This has to be
9240 done before any actual redisplay or generation of display lines. */
9241 all_windows = (update_mode_lines
9242 || buffer_shared > 1
9243 || windows_or_buffers_changed);
9244 if (all_windows)
9245 {
9246 Lisp_Object tail, frame;
9247 int count = SPECPDL_INDEX ();
9248 /* 1 means that update_menu_bar has run its hooks
9249 so any further calls to update_menu_bar shouldn't do so again. */
9250 int menu_bar_hooks_run = 0;
9251
9252 record_unwind_save_match_data ();
9253
9254 FOR_EACH_FRAME (tail, frame)
9255 {
9256 f = XFRAME (frame);
9257
9258 /* Ignore tooltip frame. */
9259 if (EQ (frame, tooltip_frame))
9260 continue;
9261
9262 /* If a window on this frame changed size, report that to
9263 the user and clear the size-change flag. */
9264 if (FRAME_WINDOW_SIZES_CHANGED (f))
9265 {
9266 Lisp_Object functions;
9267
9268 /* Clear flag first in case we get an error below. */
9269 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9270 functions = Vwindow_size_change_functions;
9271 GCPRO2 (tail, functions);
9272
9273 while (CONSP (functions))
9274 {
9275 call1 (XCAR (functions), frame);
9276 functions = XCDR (functions);
9277 }
9278 UNGCPRO;
9279 }
9280
9281 GCPRO1 (tail);
9282 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9283 #ifdef HAVE_WINDOW_SYSTEM
9284 update_tool_bar (f, 0);
9285 #ifdef MAC_OS
9286 mac_update_title_bar (f, 0);
9287 #endif
9288 #endif
9289 UNGCPRO;
9290 }
9291
9292 unbind_to (count, Qnil);
9293 }
9294 else
9295 {
9296 struct frame *sf = SELECTED_FRAME ();
9297 update_menu_bar (sf, 1, 0);
9298 #ifdef HAVE_WINDOW_SYSTEM
9299 update_tool_bar (sf, 1);
9300 #ifdef MAC_OS
9301 mac_update_title_bar (sf, 1);
9302 #endif
9303 #endif
9304 }
9305
9306 /* Motif needs this. See comment in xmenu.c. Turn it off when
9307 pending_menu_activation is not defined. */
9308 #ifdef USE_X_TOOLKIT
9309 pending_menu_activation = 0;
9310 #endif
9311 }
9312
9313
9314 /* Update the menu bar item list for frame F. This has to be done
9315 before we start to fill in any display lines, because it can call
9316 eval.
9317
9318 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9319
9320 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9321 already ran the menu bar hooks for this redisplay, so there
9322 is no need to run them again. The return value is the
9323 updated value of this flag, to pass to the next call. */
9324
9325 static int
9326 update_menu_bar (f, save_match_data, hooks_run)
9327 struct frame *f;
9328 int save_match_data;
9329 int hooks_run;
9330 {
9331 Lisp_Object window;
9332 register struct window *w;
9333
9334 /* If called recursively during a menu update, do nothing. This can
9335 happen when, for instance, an activate-menubar-hook causes a
9336 redisplay. */
9337 if (inhibit_menubar_update)
9338 return hooks_run;
9339
9340 window = FRAME_SELECTED_WINDOW (f);
9341 w = XWINDOW (window);
9342
9343 #if 0 /* The if statement below this if statement used to include the
9344 condition !NILP (w->update_mode_line), rather than using
9345 update_mode_lines directly, and this if statement may have
9346 been added to make that condition work. Now the if
9347 statement below matches its comment, this isn't needed. */
9348 if (update_mode_lines)
9349 w->update_mode_line = Qt;
9350 #endif
9351
9352 if (FRAME_WINDOW_P (f)
9353 ?
9354 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9355 || defined (USE_GTK)
9356 FRAME_EXTERNAL_MENU_BAR (f)
9357 #else
9358 FRAME_MENU_BAR_LINES (f) > 0
9359 #endif
9360 : FRAME_MENU_BAR_LINES (f) > 0)
9361 {
9362 /* If the user has switched buffers or windows, we need to
9363 recompute to reflect the new bindings. But we'll
9364 recompute when update_mode_lines is set too; that means
9365 that people can use force-mode-line-update to request
9366 that the menu bar be recomputed. The adverse effect on
9367 the rest of the redisplay algorithm is about the same as
9368 windows_or_buffers_changed anyway. */
9369 if (windows_or_buffers_changed
9370 /* This used to test w->update_mode_line, but we believe
9371 there is no need to recompute the menu in that case. */
9372 || update_mode_lines
9373 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9374 < BUF_MODIFF (XBUFFER (w->buffer)))
9375 != !NILP (w->last_had_star))
9376 || ((!NILP (Vtransient_mark_mode)
9377 && !NILP (XBUFFER (w->buffer)->mark_active))
9378 != !NILP (w->region_showing)))
9379 {
9380 struct buffer *prev = current_buffer;
9381 int count = SPECPDL_INDEX ();
9382
9383 specbind (Qinhibit_menubar_update, Qt);
9384
9385 set_buffer_internal_1 (XBUFFER (w->buffer));
9386 if (save_match_data)
9387 record_unwind_save_match_data ();
9388 if (NILP (Voverriding_local_map_menu_flag))
9389 {
9390 specbind (Qoverriding_terminal_local_map, Qnil);
9391 specbind (Qoverriding_local_map, Qnil);
9392 }
9393
9394 if (!hooks_run)
9395 {
9396 /* Run the Lucid hook. */
9397 safe_run_hooks (Qactivate_menubar_hook);
9398
9399 /* If it has changed current-menubar from previous value,
9400 really recompute the menu-bar from the value. */
9401 if (! NILP (Vlucid_menu_bar_dirty_flag))
9402 call0 (Qrecompute_lucid_menubar);
9403
9404 safe_run_hooks (Qmenu_bar_update_hook);
9405
9406 hooks_run = 1;
9407 }
9408
9409 XSETFRAME (Vmenu_updating_frame, f);
9410 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9411
9412 /* Redisplay the menu bar in case we changed it. */
9413 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9414 || defined (USE_GTK)
9415 if (FRAME_WINDOW_P (f))
9416 {
9417 #ifdef MAC_OS
9418 /* All frames on Mac OS share the same menubar. So only
9419 the selected frame should be allowed to set it. */
9420 if (f == SELECTED_FRAME ())
9421 #endif
9422 set_frame_menubar (f, 0, 0);
9423 }
9424 else
9425 /* On a terminal screen, the menu bar is an ordinary screen
9426 line, and this makes it get updated. */
9427 w->update_mode_line = Qt;
9428 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9429 /* In the non-toolkit version, the menu bar is an ordinary screen
9430 line, and this makes it get updated. */
9431 w->update_mode_line = Qt;
9432 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9433
9434 unbind_to (count, Qnil);
9435 set_buffer_internal_1 (prev);
9436 }
9437 }
9438
9439 return hooks_run;
9440 }
9441
9442
9443 \f
9444 /***********************************************************************
9445 Output Cursor
9446 ***********************************************************************/
9447
9448 #ifdef HAVE_WINDOW_SYSTEM
9449
9450 /* EXPORT:
9451 Nominal cursor position -- where to draw output.
9452 HPOS and VPOS are window relative glyph matrix coordinates.
9453 X and Y are window relative pixel coordinates. */
9454
9455 struct cursor_pos output_cursor;
9456
9457
9458 /* EXPORT:
9459 Set the global variable output_cursor to CURSOR. All cursor
9460 positions are relative to updated_window. */
9461
9462 void
9463 set_output_cursor (cursor)
9464 struct cursor_pos *cursor;
9465 {
9466 output_cursor.hpos = cursor->hpos;
9467 output_cursor.vpos = cursor->vpos;
9468 output_cursor.x = cursor->x;
9469 output_cursor.y = cursor->y;
9470 }
9471
9472
9473 /* EXPORT for RIF:
9474 Set a nominal cursor position.
9475
9476 HPOS and VPOS are column/row positions in a window glyph matrix. X
9477 and Y are window text area relative pixel positions.
9478
9479 If this is done during an update, updated_window will contain the
9480 window that is being updated and the position is the future output
9481 cursor position for that window. If updated_window is null, use
9482 selected_window and display the cursor at the given position. */
9483
9484 void
9485 x_cursor_to (vpos, hpos, y, x)
9486 int vpos, hpos, y, x;
9487 {
9488 struct window *w;
9489
9490 /* If updated_window is not set, work on selected_window. */
9491 if (updated_window)
9492 w = updated_window;
9493 else
9494 w = XWINDOW (selected_window);
9495
9496 /* Set the output cursor. */
9497 output_cursor.hpos = hpos;
9498 output_cursor.vpos = vpos;
9499 output_cursor.x = x;
9500 output_cursor.y = y;
9501
9502 /* If not called as part of an update, really display the cursor.
9503 This will also set the cursor position of W. */
9504 if (updated_window == NULL)
9505 {
9506 BLOCK_INPUT;
9507 display_and_set_cursor (w, 1, hpos, vpos, x, y);
9508 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
9509 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
9510 UNBLOCK_INPUT;
9511 }
9512 }
9513
9514 #endif /* HAVE_WINDOW_SYSTEM */
9515
9516 \f
9517 /***********************************************************************
9518 Tool-bars
9519 ***********************************************************************/
9520
9521 #ifdef HAVE_WINDOW_SYSTEM
9522
9523 /* Where the mouse was last time we reported a mouse event. */
9524
9525 FRAME_PTR last_mouse_frame;
9526
9527 /* Tool-bar item index of the item on which a mouse button was pressed
9528 or -1. */
9529
9530 int last_tool_bar_item;
9531
9532
9533 /* Update the tool-bar item list for frame F. This has to be done
9534 before we start to fill in any display lines. Called from
9535 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9536 and restore it here. */
9537
9538 static void
9539 update_tool_bar (f, save_match_data)
9540 struct frame *f;
9541 int save_match_data;
9542 {
9543 #if defined (USE_GTK) || USE_MAC_TOOLBAR
9544 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
9545 #else
9546 int do_update = WINDOWP (f->tool_bar_window)
9547 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
9548 #endif
9549
9550 if (do_update)
9551 {
9552 Lisp_Object window;
9553 struct window *w;
9554
9555 window = FRAME_SELECTED_WINDOW (f);
9556 w = XWINDOW (window);
9557
9558 /* If the user has switched buffers or windows, we need to
9559 recompute to reflect the new bindings. But we'll
9560 recompute when update_mode_lines is set too; that means
9561 that people can use force-mode-line-update to request
9562 that the menu bar be recomputed. The adverse effect on
9563 the rest of the redisplay algorithm is about the same as
9564 windows_or_buffers_changed anyway. */
9565 if (windows_or_buffers_changed
9566 || !NILP (w->update_mode_line)
9567 || update_mode_lines
9568 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9569 < BUF_MODIFF (XBUFFER (w->buffer)))
9570 != !NILP (w->last_had_star))
9571 || ((!NILP (Vtransient_mark_mode)
9572 && !NILP (XBUFFER (w->buffer)->mark_active))
9573 != !NILP (w->region_showing)))
9574 {
9575 struct buffer *prev = current_buffer;
9576 int count = SPECPDL_INDEX ();
9577 Lisp_Object new_tool_bar;
9578 int new_n_tool_bar;
9579 struct gcpro gcpro1;
9580
9581 /* Set current_buffer to the buffer of the selected
9582 window of the frame, so that we get the right local
9583 keymaps. */
9584 set_buffer_internal_1 (XBUFFER (w->buffer));
9585
9586 /* Save match data, if we must. */
9587 if (save_match_data)
9588 record_unwind_save_match_data ();
9589
9590 /* Make sure that we don't accidentally use bogus keymaps. */
9591 if (NILP (Voverriding_local_map_menu_flag))
9592 {
9593 specbind (Qoverriding_terminal_local_map, Qnil);
9594 specbind (Qoverriding_local_map, Qnil);
9595 }
9596
9597 GCPRO1 (new_tool_bar);
9598
9599 /* Build desired tool-bar items from keymaps. */
9600 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
9601 &new_n_tool_bar);
9602
9603 /* Redisplay the tool-bar if we changed it. */
9604 if (new_n_tool_bar != f->n_tool_bar_items
9605 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
9606 {
9607 /* Redisplay that happens asynchronously due to an expose event
9608 may access f->tool_bar_items. Make sure we update both
9609 variables within BLOCK_INPUT so no such event interrupts. */
9610 BLOCK_INPUT;
9611 f->tool_bar_items = new_tool_bar;
9612 f->n_tool_bar_items = new_n_tool_bar;
9613 w->update_mode_line = Qt;
9614 UNBLOCK_INPUT;
9615 }
9616
9617 UNGCPRO;
9618
9619 unbind_to (count, Qnil);
9620 set_buffer_internal_1 (prev);
9621 }
9622 }
9623 }
9624
9625
9626 /* Set F->desired_tool_bar_string to a Lisp string representing frame
9627 F's desired tool-bar contents. F->tool_bar_items must have
9628 been set up previously by calling prepare_menu_bars. */
9629
9630 static void
9631 build_desired_tool_bar_string (f)
9632 struct frame *f;
9633 {
9634 int i, size, size_needed;
9635 struct gcpro gcpro1, gcpro2, gcpro3;
9636 Lisp_Object image, plist, props;
9637
9638 image = plist = props = Qnil;
9639 GCPRO3 (image, plist, props);
9640
9641 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
9642 Otherwise, make a new string. */
9643
9644 /* The size of the string we might be able to reuse. */
9645 size = (STRINGP (f->desired_tool_bar_string)
9646 ? SCHARS (f->desired_tool_bar_string)
9647 : 0);
9648
9649 /* We need one space in the string for each image. */
9650 size_needed = f->n_tool_bar_items;
9651
9652 /* Reuse f->desired_tool_bar_string, if possible. */
9653 if (size < size_needed || NILP (f->desired_tool_bar_string))
9654 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
9655 make_number (' '));
9656 else
9657 {
9658 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
9659 Fremove_text_properties (make_number (0), make_number (size),
9660 props, f->desired_tool_bar_string);
9661 }
9662
9663 /* Put a `display' property on the string for the images to display,
9664 put a `menu_item' property on tool-bar items with a value that
9665 is the index of the item in F's tool-bar item vector. */
9666 for (i = 0; i < f->n_tool_bar_items; ++i)
9667 {
9668 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
9669
9670 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
9671 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
9672 int hmargin, vmargin, relief, idx, end;
9673 extern Lisp_Object QCrelief, QCmargin, QCconversion;
9674
9675 /* If image is a vector, choose the image according to the
9676 button state. */
9677 image = PROP (TOOL_BAR_ITEM_IMAGES);
9678 if (VECTORP (image))
9679 {
9680 if (enabled_p)
9681 idx = (selected_p
9682 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
9683 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
9684 else
9685 idx = (selected_p
9686 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
9687 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
9688
9689 xassert (ASIZE (image) >= idx);
9690 image = AREF (image, idx);
9691 }
9692 else
9693 idx = -1;
9694
9695 /* Ignore invalid image specifications. */
9696 if (!valid_image_p (image))
9697 continue;
9698
9699 /* Display the tool-bar button pressed, or depressed. */
9700 plist = Fcopy_sequence (XCDR (image));
9701
9702 /* Compute margin and relief to draw. */
9703 relief = (tool_bar_button_relief >= 0
9704 ? tool_bar_button_relief
9705 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
9706 hmargin = vmargin = relief;
9707
9708 if (INTEGERP (Vtool_bar_button_margin)
9709 && XINT (Vtool_bar_button_margin) > 0)
9710 {
9711 hmargin += XFASTINT (Vtool_bar_button_margin);
9712 vmargin += XFASTINT (Vtool_bar_button_margin);
9713 }
9714 else if (CONSP (Vtool_bar_button_margin))
9715 {
9716 if (INTEGERP (XCAR (Vtool_bar_button_margin))
9717 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
9718 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
9719
9720 if (INTEGERP (XCDR (Vtool_bar_button_margin))
9721 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
9722 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
9723 }
9724
9725 if (auto_raise_tool_bar_buttons_p)
9726 {
9727 /* Add a `:relief' property to the image spec if the item is
9728 selected. */
9729 if (selected_p)
9730 {
9731 plist = Fplist_put (plist, QCrelief, make_number (-relief));
9732 hmargin -= relief;
9733 vmargin -= relief;
9734 }
9735 }
9736 else
9737 {
9738 /* If image is selected, display it pressed, i.e. with a
9739 negative relief. If it's not selected, display it with a
9740 raised relief. */
9741 plist = Fplist_put (plist, QCrelief,
9742 (selected_p
9743 ? make_number (-relief)
9744 : make_number (relief)));
9745 hmargin -= relief;
9746 vmargin -= relief;
9747 }
9748
9749 /* Put a margin around the image. */
9750 if (hmargin || vmargin)
9751 {
9752 if (hmargin == vmargin)
9753 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
9754 else
9755 plist = Fplist_put (plist, QCmargin,
9756 Fcons (make_number (hmargin),
9757 make_number (vmargin)));
9758 }
9759
9760 /* If button is not enabled, and we don't have special images
9761 for the disabled state, make the image appear disabled by
9762 applying an appropriate algorithm to it. */
9763 if (!enabled_p && idx < 0)
9764 plist = Fplist_put (plist, QCconversion, Qdisabled);
9765
9766 /* Put a `display' text property on the string for the image to
9767 display. Put a `menu-item' property on the string that gives
9768 the start of this item's properties in the tool-bar items
9769 vector. */
9770 image = Fcons (Qimage, plist);
9771 props = list4 (Qdisplay, image,
9772 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
9773
9774 /* Let the last image hide all remaining spaces in the tool bar
9775 string. The string can be longer than needed when we reuse a
9776 previous string. */
9777 if (i + 1 == f->n_tool_bar_items)
9778 end = SCHARS (f->desired_tool_bar_string);
9779 else
9780 end = i + 1;
9781 Fadd_text_properties (make_number (i), make_number (end),
9782 props, f->desired_tool_bar_string);
9783 #undef PROP
9784 }
9785
9786 UNGCPRO;
9787 }
9788
9789
9790 /* Display one line of the tool-bar of frame IT->f.
9791
9792 HEIGHT specifies the desired height of the tool-bar line.
9793 If the actual height of the glyph row is less than HEIGHT, the
9794 row's height is increased to HEIGHT, and the icons are centered
9795 vertically in the new height.
9796
9797 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
9798 count a final empty row in case the tool-bar width exactly matches
9799 the window width.
9800 */
9801
9802 static void
9803 display_tool_bar_line (it, height)
9804 struct it *it;
9805 int height;
9806 {
9807 struct glyph_row *row = it->glyph_row;
9808 int max_x = it->last_visible_x;
9809 struct glyph *last;
9810
9811 prepare_desired_row (row);
9812 row->y = it->current_y;
9813
9814 /* Note that this isn't made use of if the face hasn't a box,
9815 so there's no need to check the face here. */
9816 it->start_of_box_run_p = 1;
9817
9818 while (it->current_x < max_x)
9819 {
9820 int x, n_glyphs_before, i, nglyphs;
9821 struct it it_before;
9822
9823 /* Get the next display element. */
9824 if (!get_next_display_element (it))
9825 {
9826 /* Don't count empty row if we are counting needed tool-bar lines. */
9827 if (height < 0 && !it->hpos)
9828 return;
9829 break;
9830 }
9831
9832 /* Produce glyphs. */
9833 n_glyphs_before = row->used[TEXT_AREA];
9834 it_before = *it;
9835
9836 PRODUCE_GLYPHS (it);
9837
9838 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
9839 i = 0;
9840 x = it_before.current_x;
9841 while (i < nglyphs)
9842 {
9843 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
9844
9845 if (x + glyph->pixel_width > max_x)
9846 {
9847 /* Glyph doesn't fit on line. Backtrack. */
9848 row->used[TEXT_AREA] = n_glyphs_before;
9849 *it = it_before;
9850 /* If this is the only glyph on this line, it will never fit on the
9851 toolbar, so skip it. But ensure there is at least one glyph,
9852 so we don't accidentally disable the tool-bar. */
9853 if (n_glyphs_before == 0
9854 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
9855 break;
9856 goto out;
9857 }
9858
9859 ++it->hpos;
9860 x += glyph->pixel_width;
9861 ++i;
9862 }
9863
9864 /* Stop at line ends. */
9865 if (ITERATOR_AT_END_OF_LINE_P (it))
9866 break;
9867
9868 set_iterator_to_next (it, 1);
9869 }
9870
9871 out:;
9872
9873 row->displays_text_p = row->used[TEXT_AREA] != 0;
9874
9875 /* Use default face for the border below the tool bar.
9876
9877 FIXME: When auto-resize-tool-bars is grow-only, there is
9878 no additional border below the possibly empty tool-bar lines.
9879 So to make the extra empty lines look "normal", we have to
9880 use the tool-bar face for the border too. */
9881 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
9882 it->face_id = DEFAULT_FACE_ID;
9883
9884 extend_face_to_end_of_line (it);
9885 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
9886 last->right_box_line_p = 1;
9887 if (last == row->glyphs[TEXT_AREA])
9888 last->left_box_line_p = 1;
9889
9890 /* Make line the desired height and center it vertically. */
9891 if ((height -= it->max_ascent + it->max_descent) > 0)
9892 {
9893 /* Don't add more than one line height. */
9894 height %= FRAME_LINE_HEIGHT (it->f);
9895 it->max_ascent += height / 2;
9896 it->max_descent += (height + 1) / 2;
9897 }
9898
9899 compute_line_metrics (it);
9900
9901 /* If line is empty, make it occupy the rest of the tool-bar. */
9902 if (!row->displays_text_p)
9903 {
9904 row->height = row->phys_height = it->last_visible_y - row->y;
9905 row->visible_height = row->height;
9906 row->ascent = row->phys_ascent = 0;
9907 row->extra_line_spacing = 0;
9908 }
9909
9910 row->full_width_p = 1;
9911 row->continued_p = 0;
9912 row->truncated_on_left_p = 0;
9913 row->truncated_on_right_p = 0;
9914
9915 it->current_x = it->hpos = 0;
9916 it->current_y += row->height;
9917 ++it->vpos;
9918 ++it->glyph_row;
9919 }
9920
9921
9922 /* Max tool-bar height. */
9923
9924 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
9925 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
9926
9927 /* Value is the number of screen lines needed to make all tool-bar
9928 items of frame F visible. The number of actual rows needed is
9929 returned in *N_ROWS if non-NULL. */
9930
9931 static int
9932 tool_bar_lines_needed (f, n_rows)
9933 struct frame *f;
9934 int *n_rows;
9935 {
9936 struct window *w = XWINDOW (f->tool_bar_window);
9937 struct it it;
9938 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
9939 the desired matrix, so use (unused) mode-line row as temporary row to
9940 avoid destroying the first tool-bar row. */
9941 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
9942
9943 /* Initialize an iterator for iteration over
9944 F->desired_tool_bar_string in the tool-bar window of frame F. */
9945 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
9946 it.first_visible_x = 0;
9947 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9948 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9949
9950 while (!ITERATOR_AT_END_P (&it))
9951 {
9952 clear_glyph_row (temp_row);
9953 it.glyph_row = temp_row;
9954 display_tool_bar_line (&it, -1);
9955 }
9956 clear_glyph_row (temp_row);
9957
9958 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
9959 if (n_rows)
9960 *n_rows = it.vpos > 0 ? it.vpos : -1;
9961
9962 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
9963 }
9964
9965
9966 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
9967 0, 1, 0,
9968 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
9969 (frame)
9970 Lisp_Object frame;
9971 {
9972 struct frame *f;
9973 struct window *w;
9974 int nlines = 0;
9975
9976 if (NILP (frame))
9977 frame = selected_frame;
9978 else
9979 CHECK_FRAME (frame);
9980 f = XFRAME (frame);
9981
9982 if (WINDOWP (f->tool_bar_window)
9983 || (w = XWINDOW (f->tool_bar_window),
9984 WINDOW_TOTAL_LINES (w) > 0))
9985 {
9986 update_tool_bar (f, 1);
9987 if (f->n_tool_bar_items)
9988 {
9989 build_desired_tool_bar_string (f);
9990 nlines = tool_bar_lines_needed (f, NULL);
9991 }
9992 }
9993
9994 return make_number (nlines);
9995 }
9996
9997
9998 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9999 height should be changed. */
10000
10001 static int
10002 redisplay_tool_bar (f)
10003 struct frame *f;
10004 {
10005 struct window *w;
10006 struct it it;
10007 struct glyph_row *row;
10008
10009 #if defined (USE_GTK) || USE_MAC_TOOLBAR
10010 if (FRAME_EXTERNAL_TOOL_BAR (f))
10011 update_frame_tool_bar (f);
10012 return 0;
10013 #endif
10014
10015 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10016 do anything. This means you must start with tool-bar-lines
10017 non-zero to get the auto-sizing effect. Or in other words, you
10018 can turn off tool-bars by specifying tool-bar-lines zero. */
10019 if (!WINDOWP (f->tool_bar_window)
10020 || (w = XWINDOW (f->tool_bar_window),
10021 WINDOW_TOTAL_LINES (w) == 0))
10022 return 0;
10023
10024 /* Set up an iterator for the tool-bar window. */
10025 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10026 it.first_visible_x = 0;
10027 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10028 row = it.glyph_row;
10029
10030 /* Build a string that represents the contents of the tool-bar. */
10031 build_desired_tool_bar_string (f);
10032 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10033
10034 if (f->n_tool_bar_rows == 0)
10035 {
10036 int nlines;
10037
10038 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10039 nlines != WINDOW_TOTAL_LINES (w)))
10040 {
10041 extern Lisp_Object Qtool_bar_lines;
10042 Lisp_Object frame;
10043 int old_height = WINDOW_TOTAL_LINES (w);
10044
10045 XSETFRAME (frame, f);
10046 Fmodify_frame_parameters (frame,
10047 Fcons (Fcons (Qtool_bar_lines,
10048 make_number (nlines)),
10049 Qnil));
10050 if (WINDOW_TOTAL_LINES (w) != old_height)
10051 {
10052 clear_glyph_matrix (w->desired_matrix);
10053 fonts_changed_p = 1;
10054 return 1;
10055 }
10056 }
10057 }
10058
10059 /* Display as many lines as needed to display all tool-bar items. */
10060
10061 if (f->n_tool_bar_rows > 0)
10062 {
10063 int border, rows, height, extra;
10064
10065 if (INTEGERP (Vtool_bar_border))
10066 border = XINT (Vtool_bar_border);
10067 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10068 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10069 else if (EQ (Vtool_bar_border, Qborder_width))
10070 border = f->border_width;
10071 else
10072 border = 0;
10073 if (border < 0)
10074 border = 0;
10075
10076 rows = f->n_tool_bar_rows;
10077 height = max (1, (it.last_visible_y - border) / rows);
10078 extra = it.last_visible_y - border - height * rows;
10079
10080 while (it.current_y < it.last_visible_y)
10081 {
10082 int h = 0;
10083 if (extra > 0 && rows-- > 0)
10084 {
10085 h = (extra + rows - 1) / rows;
10086 extra -= h;
10087 }
10088 display_tool_bar_line (&it, height + h);
10089 }
10090 }
10091 else
10092 {
10093 while (it.current_y < it.last_visible_y)
10094 display_tool_bar_line (&it, 0);
10095 }
10096
10097 /* It doesn't make much sense to try scrolling in the tool-bar
10098 window, so don't do it. */
10099 w->desired_matrix->no_scrolling_p = 1;
10100 w->must_be_updated_p = 1;
10101
10102 if (!NILP (Vauto_resize_tool_bars))
10103 {
10104 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10105 int change_height_p = 0;
10106
10107 /* If we couldn't display everything, change the tool-bar's
10108 height if there is room for more. */
10109 if (IT_STRING_CHARPOS (it) < it.end_charpos
10110 && it.current_y < max_tool_bar_height)
10111 change_height_p = 1;
10112
10113 row = it.glyph_row - 1;
10114
10115 /* If there are blank lines at the end, except for a partially
10116 visible blank line at the end that is smaller than
10117 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10118 if (!row->displays_text_p
10119 && row->height >= FRAME_LINE_HEIGHT (f))
10120 change_height_p = 1;
10121
10122 /* If row displays tool-bar items, but is partially visible,
10123 change the tool-bar's height. */
10124 if (row->displays_text_p
10125 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10126 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10127 change_height_p = 1;
10128
10129 /* Resize windows as needed by changing the `tool-bar-lines'
10130 frame parameter. */
10131 if (change_height_p)
10132 {
10133 extern Lisp_Object Qtool_bar_lines;
10134 Lisp_Object frame;
10135 int old_height = WINDOW_TOTAL_LINES (w);
10136 int nrows;
10137 int nlines = tool_bar_lines_needed (f, &nrows);
10138
10139 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10140 && !f->minimize_tool_bar_window_p)
10141 ? (nlines > old_height)
10142 : (nlines != old_height));
10143 f->minimize_tool_bar_window_p = 0;
10144
10145 if (change_height_p)
10146 {
10147 XSETFRAME (frame, f);
10148 Fmodify_frame_parameters (frame,
10149 Fcons (Fcons (Qtool_bar_lines,
10150 make_number (nlines)),
10151 Qnil));
10152 if (WINDOW_TOTAL_LINES (w) != old_height)
10153 {
10154 clear_glyph_matrix (w->desired_matrix);
10155 f->n_tool_bar_rows = nrows;
10156 fonts_changed_p = 1;
10157 return 1;
10158 }
10159 }
10160 }
10161 }
10162
10163 f->minimize_tool_bar_window_p = 0;
10164 return 0;
10165 }
10166
10167
10168 /* Get information about the tool-bar item which is displayed in GLYPH
10169 on frame F. Return in *PROP_IDX the index where tool-bar item
10170 properties start in F->tool_bar_items. Value is zero if
10171 GLYPH doesn't display a tool-bar item. */
10172
10173 static int
10174 tool_bar_item_info (f, glyph, prop_idx)
10175 struct frame *f;
10176 struct glyph *glyph;
10177 int *prop_idx;
10178 {
10179 Lisp_Object prop;
10180 int success_p;
10181 int charpos;
10182
10183 /* This function can be called asynchronously, which means we must
10184 exclude any possibility that Fget_text_property signals an
10185 error. */
10186 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10187 charpos = max (0, charpos);
10188
10189 /* Get the text property `menu-item' at pos. The value of that
10190 property is the start index of this item's properties in
10191 F->tool_bar_items. */
10192 prop = Fget_text_property (make_number (charpos),
10193 Qmenu_item, f->current_tool_bar_string);
10194 if (INTEGERP (prop))
10195 {
10196 *prop_idx = XINT (prop);
10197 success_p = 1;
10198 }
10199 else
10200 success_p = 0;
10201
10202 return success_p;
10203 }
10204
10205 \f
10206 /* Get information about the tool-bar item at position X/Y on frame F.
10207 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10208 the current matrix of the tool-bar window of F, or NULL if not
10209 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10210 item in F->tool_bar_items. Value is
10211
10212 -1 if X/Y is not on a tool-bar item
10213 0 if X/Y is on the same item that was highlighted before.
10214 1 otherwise. */
10215
10216 static int
10217 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
10218 struct frame *f;
10219 int x, y;
10220 struct glyph **glyph;
10221 int *hpos, *vpos, *prop_idx;
10222 {
10223 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10224 struct window *w = XWINDOW (f->tool_bar_window);
10225 int area;
10226
10227 /* Find the glyph under X/Y. */
10228 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10229 if (*glyph == NULL)
10230 return -1;
10231
10232 /* Get the start of this tool-bar item's properties in
10233 f->tool_bar_items. */
10234 if (!tool_bar_item_info (f, *glyph, prop_idx))
10235 return -1;
10236
10237 /* Is mouse on the highlighted item? */
10238 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10239 && *vpos >= dpyinfo->mouse_face_beg_row
10240 && *vpos <= dpyinfo->mouse_face_end_row
10241 && (*vpos > dpyinfo->mouse_face_beg_row
10242 || *hpos >= dpyinfo->mouse_face_beg_col)
10243 && (*vpos < dpyinfo->mouse_face_end_row
10244 || *hpos < dpyinfo->mouse_face_end_col
10245 || dpyinfo->mouse_face_past_end))
10246 return 0;
10247
10248 return 1;
10249 }
10250
10251
10252 /* EXPORT:
10253 Handle mouse button event on the tool-bar of frame F, at
10254 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10255 0 for button release. MODIFIERS is event modifiers for button
10256 release. */
10257
10258 void
10259 handle_tool_bar_click (f, x, y, down_p, modifiers)
10260 struct frame *f;
10261 int x, y, down_p;
10262 unsigned int modifiers;
10263 {
10264 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10265 struct window *w = XWINDOW (f->tool_bar_window);
10266 int hpos, vpos, prop_idx;
10267 struct glyph *glyph;
10268 Lisp_Object enabled_p;
10269
10270 /* If not on the highlighted tool-bar item, return. */
10271 frame_to_window_pixel_xy (w, &x, &y);
10272 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10273 return;
10274
10275 /* If item is disabled, do nothing. */
10276 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10277 if (NILP (enabled_p))
10278 return;
10279
10280 if (down_p)
10281 {
10282 /* Show item in pressed state. */
10283 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10284 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10285 last_tool_bar_item = prop_idx;
10286 }
10287 else
10288 {
10289 Lisp_Object key, frame;
10290 struct input_event event;
10291 EVENT_INIT (event);
10292
10293 /* Show item in released state. */
10294 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10295 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10296
10297 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10298
10299 XSETFRAME (frame, f);
10300 event.kind = TOOL_BAR_EVENT;
10301 event.frame_or_window = frame;
10302 event.arg = frame;
10303 kbd_buffer_store_event (&event);
10304
10305 event.kind = TOOL_BAR_EVENT;
10306 event.frame_or_window = frame;
10307 event.arg = key;
10308 event.modifiers = modifiers;
10309 kbd_buffer_store_event (&event);
10310 last_tool_bar_item = -1;
10311 }
10312 }
10313
10314
10315 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10316 tool-bar window-relative coordinates X/Y. Called from
10317 note_mouse_highlight. */
10318
10319 static void
10320 note_tool_bar_highlight (f, x, y)
10321 struct frame *f;
10322 int x, y;
10323 {
10324 Lisp_Object window = f->tool_bar_window;
10325 struct window *w = XWINDOW (window);
10326 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10327 int hpos, vpos;
10328 struct glyph *glyph;
10329 struct glyph_row *row;
10330 int i;
10331 Lisp_Object enabled_p;
10332 int prop_idx;
10333 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10334 int mouse_down_p, rc;
10335
10336 /* Function note_mouse_highlight is called with negative x(y
10337 values when mouse moves outside of the frame. */
10338 if (x <= 0 || y <= 0)
10339 {
10340 clear_mouse_face (dpyinfo);
10341 return;
10342 }
10343
10344 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10345 if (rc < 0)
10346 {
10347 /* Not on tool-bar item. */
10348 clear_mouse_face (dpyinfo);
10349 return;
10350 }
10351 else if (rc == 0)
10352 /* On same tool-bar item as before. */
10353 goto set_help_echo;
10354
10355 clear_mouse_face (dpyinfo);
10356
10357 /* Mouse is down, but on different tool-bar item? */
10358 mouse_down_p = (dpyinfo->grabbed
10359 && f == last_mouse_frame
10360 && FRAME_LIVE_P (f));
10361 if (mouse_down_p
10362 && last_tool_bar_item != prop_idx)
10363 return;
10364
10365 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10366 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10367
10368 /* If tool-bar item is not enabled, don't highlight it. */
10369 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10370 if (!NILP (enabled_p))
10371 {
10372 /* Compute the x-position of the glyph. In front and past the
10373 image is a space. We include this in the highlighted area. */
10374 row = MATRIX_ROW (w->current_matrix, vpos);
10375 for (i = x = 0; i < hpos; ++i)
10376 x += row->glyphs[TEXT_AREA][i].pixel_width;
10377
10378 /* Record this as the current active region. */
10379 dpyinfo->mouse_face_beg_col = hpos;
10380 dpyinfo->mouse_face_beg_row = vpos;
10381 dpyinfo->mouse_face_beg_x = x;
10382 dpyinfo->mouse_face_beg_y = row->y;
10383 dpyinfo->mouse_face_past_end = 0;
10384
10385 dpyinfo->mouse_face_end_col = hpos + 1;
10386 dpyinfo->mouse_face_end_row = vpos;
10387 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10388 dpyinfo->mouse_face_end_y = row->y;
10389 dpyinfo->mouse_face_window = window;
10390 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10391
10392 /* Display it as active. */
10393 show_mouse_face (dpyinfo, draw);
10394 dpyinfo->mouse_face_image_state = draw;
10395 }
10396
10397 set_help_echo:
10398
10399 /* Set help_echo_string to a help string to display for this tool-bar item.
10400 XTread_socket does the rest. */
10401 help_echo_object = help_echo_window = Qnil;
10402 help_echo_pos = -1;
10403 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10404 if (NILP (help_echo_string))
10405 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10406 }
10407
10408 #endif /* HAVE_WINDOW_SYSTEM */
10409
10410
10411 \f
10412 /************************************************************************
10413 Horizontal scrolling
10414 ************************************************************************/
10415
10416 static int hscroll_window_tree P_ ((Lisp_Object));
10417 static int hscroll_windows P_ ((Lisp_Object));
10418
10419 /* For all leaf windows in the window tree rooted at WINDOW, set their
10420 hscroll value so that PT is (i) visible in the window, and (ii) so
10421 that it is not within a certain margin at the window's left and
10422 right border. Value is non-zero if any window's hscroll has been
10423 changed. */
10424
10425 static int
10426 hscroll_window_tree (window)
10427 Lisp_Object window;
10428 {
10429 int hscrolled_p = 0;
10430 int hscroll_relative_p = FLOATP (Vhscroll_step);
10431 int hscroll_step_abs = 0;
10432 double hscroll_step_rel = 0;
10433
10434 if (hscroll_relative_p)
10435 {
10436 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10437 if (hscroll_step_rel < 0)
10438 {
10439 hscroll_relative_p = 0;
10440 hscroll_step_abs = 0;
10441 }
10442 }
10443 else if (INTEGERP (Vhscroll_step))
10444 {
10445 hscroll_step_abs = XINT (Vhscroll_step);
10446 if (hscroll_step_abs < 0)
10447 hscroll_step_abs = 0;
10448 }
10449 else
10450 hscroll_step_abs = 0;
10451
10452 while (WINDOWP (window))
10453 {
10454 struct window *w = XWINDOW (window);
10455
10456 if (WINDOWP (w->hchild))
10457 hscrolled_p |= hscroll_window_tree (w->hchild);
10458 else if (WINDOWP (w->vchild))
10459 hscrolled_p |= hscroll_window_tree (w->vchild);
10460 else if (w->cursor.vpos >= 0)
10461 {
10462 int h_margin;
10463 int text_area_width;
10464 struct glyph_row *current_cursor_row
10465 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10466 struct glyph_row *desired_cursor_row
10467 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10468 struct glyph_row *cursor_row
10469 = (desired_cursor_row->enabled_p
10470 ? desired_cursor_row
10471 : current_cursor_row);
10472
10473 text_area_width = window_box_width (w, TEXT_AREA);
10474
10475 /* Scroll when cursor is inside this scroll margin. */
10476 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
10477
10478 if ((XFASTINT (w->hscroll)
10479 && w->cursor.x <= h_margin)
10480 || (cursor_row->enabled_p
10481 && cursor_row->truncated_on_right_p
10482 && (w->cursor.x >= text_area_width - h_margin)))
10483 {
10484 struct it it;
10485 int hscroll;
10486 struct buffer *saved_current_buffer;
10487 int pt;
10488 int wanted_x;
10489
10490 /* Find point in a display of infinite width. */
10491 saved_current_buffer = current_buffer;
10492 current_buffer = XBUFFER (w->buffer);
10493
10494 if (w == XWINDOW (selected_window))
10495 pt = BUF_PT (current_buffer);
10496 else
10497 {
10498 pt = marker_position (w->pointm);
10499 pt = max (BEGV, pt);
10500 pt = min (ZV, pt);
10501 }
10502
10503 /* Move iterator to pt starting at cursor_row->start in
10504 a line with infinite width. */
10505 init_to_row_start (&it, w, cursor_row);
10506 it.last_visible_x = INFINITY;
10507 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
10508 current_buffer = saved_current_buffer;
10509
10510 /* Position cursor in window. */
10511 if (!hscroll_relative_p && hscroll_step_abs == 0)
10512 hscroll = max (0, (it.current_x
10513 - (ITERATOR_AT_END_OF_LINE_P (&it)
10514 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
10515 : (text_area_width / 2))))
10516 / FRAME_COLUMN_WIDTH (it.f);
10517 else if (w->cursor.x >= text_area_width - h_margin)
10518 {
10519 if (hscroll_relative_p)
10520 wanted_x = text_area_width * (1 - hscroll_step_rel)
10521 - h_margin;
10522 else
10523 wanted_x = text_area_width
10524 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10525 - h_margin;
10526 hscroll
10527 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10528 }
10529 else
10530 {
10531 if (hscroll_relative_p)
10532 wanted_x = text_area_width * hscroll_step_rel
10533 + h_margin;
10534 else
10535 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10536 + h_margin;
10537 hscroll
10538 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10539 }
10540 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
10541
10542 /* Don't call Fset_window_hscroll if value hasn't
10543 changed because it will prevent redisplay
10544 optimizations. */
10545 if (XFASTINT (w->hscroll) != hscroll)
10546 {
10547 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
10548 w->hscroll = make_number (hscroll);
10549 hscrolled_p = 1;
10550 }
10551 }
10552 }
10553
10554 window = w->next;
10555 }
10556
10557 /* Value is non-zero if hscroll of any leaf window has been changed. */
10558 return hscrolled_p;
10559 }
10560
10561
10562 /* Set hscroll so that cursor is visible and not inside horizontal
10563 scroll margins for all windows in the tree rooted at WINDOW. See
10564 also hscroll_window_tree above. Value is non-zero if any window's
10565 hscroll has been changed. If it has, desired matrices on the frame
10566 of WINDOW are cleared. */
10567
10568 static int
10569 hscroll_windows (window)
10570 Lisp_Object window;
10571 {
10572 int hscrolled_p;
10573
10574 if (automatic_hscrolling_p)
10575 {
10576 hscrolled_p = hscroll_window_tree (window);
10577 if (hscrolled_p)
10578 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
10579 }
10580 else
10581 hscrolled_p = 0;
10582 return hscrolled_p;
10583 }
10584
10585
10586 \f
10587 /************************************************************************
10588 Redisplay
10589 ************************************************************************/
10590
10591 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
10592 to a non-zero value. This is sometimes handy to have in a debugger
10593 session. */
10594
10595 #if GLYPH_DEBUG
10596
10597 /* First and last unchanged row for try_window_id. */
10598
10599 int debug_first_unchanged_at_end_vpos;
10600 int debug_last_unchanged_at_beg_vpos;
10601
10602 /* Delta vpos and y. */
10603
10604 int debug_dvpos, debug_dy;
10605
10606 /* Delta in characters and bytes for try_window_id. */
10607
10608 int debug_delta, debug_delta_bytes;
10609
10610 /* Values of window_end_pos and window_end_vpos at the end of
10611 try_window_id. */
10612
10613 EMACS_INT debug_end_pos, debug_end_vpos;
10614
10615 /* Append a string to W->desired_matrix->method. FMT is a printf
10616 format string. A1...A9 are a supplement for a variable-length
10617 argument list. If trace_redisplay_p is non-zero also printf the
10618 resulting string to stderr. */
10619
10620 static void
10621 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
10622 struct window *w;
10623 char *fmt;
10624 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
10625 {
10626 char buffer[512];
10627 char *method = w->desired_matrix->method;
10628 int len = strlen (method);
10629 int size = sizeof w->desired_matrix->method;
10630 int remaining = size - len - 1;
10631
10632 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
10633 if (len && remaining)
10634 {
10635 method[len] = '|';
10636 --remaining, ++len;
10637 }
10638
10639 strncpy (method + len, buffer, remaining);
10640
10641 if (trace_redisplay_p)
10642 fprintf (stderr, "%p (%s): %s\n",
10643 w,
10644 ((BUFFERP (w->buffer)
10645 && STRINGP (XBUFFER (w->buffer)->name))
10646 ? (char *) SDATA (XBUFFER (w->buffer)->name)
10647 : "no buffer"),
10648 buffer);
10649 }
10650
10651 #endif /* GLYPH_DEBUG */
10652
10653
10654 /* Value is non-zero if all changes in window W, which displays
10655 current_buffer, are in the text between START and END. START is a
10656 buffer position, END is given as a distance from Z. Used in
10657 redisplay_internal for display optimization. */
10658
10659 static INLINE int
10660 text_outside_line_unchanged_p (w, start, end)
10661 struct window *w;
10662 int start, end;
10663 {
10664 int unchanged_p = 1;
10665
10666 /* If text or overlays have changed, see where. */
10667 if (XFASTINT (w->last_modified) < MODIFF
10668 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10669 {
10670 /* Gap in the line? */
10671 if (GPT < start || Z - GPT < end)
10672 unchanged_p = 0;
10673
10674 /* Changes start in front of the line, or end after it? */
10675 if (unchanged_p
10676 && (BEG_UNCHANGED < start - 1
10677 || END_UNCHANGED < end))
10678 unchanged_p = 0;
10679
10680 /* If selective display, can't optimize if changes start at the
10681 beginning of the line. */
10682 if (unchanged_p
10683 && INTEGERP (current_buffer->selective_display)
10684 && XINT (current_buffer->selective_display) > 0
10685 && (BEG_UNCHANGED < start || GPT <= start))
10686 unchanged_p = 0;
10687
10688 /* If there are overlays at the start or end of the line, these
10689 may have overlay strings with newlines in them. A change at
10690 START, for instance, may actually concern the display of such
10691 overlay strings as well, and they are displayed on different
10692 lines. So, quickly rule out this case. (For the future, it
10693 might be desirable to implement something more telling than
10694 just BEG/END_UNCHANGED.) */
10695 if (unchanged_p)
10696 {
10697 if (BEG + BEG_UNCHANGED == start
10698 && overlay_touches_p (start))
10699 unchanged_p = 0;
10700 if (END_UNCHANGED == end
10701 && overlay_touches_p (Z - end))
10702 unchanged_p = 0;
10703 }
10704 }
10705
10706 return unchanged_p;
10707 }
10708
10709
10710 /* Do a frame update, taking possible shortcuts into account. This is
10711 the main external entry point for redisplay.
10712
10713 If the last redisplay displayed an echo area message and that message
10714 is no longer requested, we clear the echo area or bring back the
10715 mini-buffer if that is in use. */
10716
10717 void
10718 redisplay ()
10719 {
10720 redisplay_internal (0);
10721 }
10722
10723
10724 static Lisp_Object
10725 overlay_arrow_string_or_property (var)
10726 Lisp_Object var;
10727 {
10728 Lisp_Object val;
10729
10730 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
10731 return val;
10732
10733 return Voverlay_arrow_string;
10734 }
10735
10736 /* Return 1 if there are any overlay-arrows in current_buffer. */
10737 static int
10738 overlay_arrow_in_current_buffer_p ()
10739 {
10740 Lisp_Object vlist;
10741
10742 for (vlist = Voverlay_arrow_variable_list;
10743 CONSP (vlist);
10744 vlist = XCDR (vlist))
10745 {
10746 Lisp_Object var = XCAR (vlist);
10747 Lisp_Object val;
10748
10749 if (!SYMBOLP (var))
10750 continue;
10751 val = find_symbol_value (var);
10752 if (MARKERP (val)
10753 && current_buffer == XMARKER (val)->buffer)
10754 return 1;
10755 }
10756 return 0;
10757 }
10758
10759
10760 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
10761 has changed. */
10762
10763 static int
10764 overlay_arrows_changed_p ()
10765 {
10766 Lisp_Object vlist;
10767
10768 for (vlist = Voverlay_arrow_variable_list;
10769 CONSP (vlist);
10770 vlist = XCDR (vlist))
10771 {
10772 Lisp_Object var = XCAR (vlist);
10773 Lisp_Object val, pstr;
10774
10775 if (!SYMBOLP (var))
10776 continue;
10777 val = find_symbol_value (var);
10778 if (!MARKERP (val))
10779 continue;
10780 if (! EQ (COERCE_MARKER (val),
10781 Fget (var, Qlast_arrow_position))
10782 || ! (pstr = overlay_arrow_string_or_property (var),
10783 EQ (pstr, Fget (var, Qlast_arrow_string))))
10784 return 1;
10785 }
10786 return 0;
10787 }
10788
10789 /* Mark overlay arrows to be updated on next redisplay. */
10790
10791 static void
10792 update_overlay_arrows (up_to_date)
10793 int up_to_date;
10794 {
10795 Lisp_Object vlist;
10796
10797 for (vlist = Voverlay_arrow_variable_list;
10798 CONSP (vlist);
10799 vlist = XCDR (vlist))
10800 {
10801 Lisp_Object var = XCAR (vlist);
10802
10803 if (!SYMBOLP (var))
10804 continue;
10805
10806 if (up_to_date > 0)
10807 {
10808 Lisp_Object val = find_symbol_value (var);
10809 Fput (var, Qlast_arrow_position,
10810 COERCE_MARKER (val));
10811 Fput (var, Qlast_arrow_string,
10812 overlay_arrow_string_or_property (var));
10813 }
10814 else if (up_to_date < 0
10815 || !NILP (Fget (var, Qlast_arrow_position)))
10816 {
10817 Fput (var, Qlast_arrow_position, Qt);
10818 Fput (var, Qlast_arrow_string, Qt);
10819 }
10820 }
10821 }
10822
10823
10824 /* Return overlay arrow string to display at row.
10825 Return integer (bitmap number) for arrow bitmap in left fringe.
10826 Return nil if no overlay arrow. */
10827
10828 static Lisp_Object
10829 overlay_arrow_at_row (it, row)
10830 struct it *it;
10831 struct glyph_row *row;
10832 {
10833 Lisp_Object vlist;
10834
10835 for (vlist = Voverlay_arrow_variable_list;
10836 CONSP (vlist);
10837 vlist = XCDR (vlist))
10838 {
10839 Lisp_Object var = XCAR (vlist);
10840 Lisp_Object val;
10841
10842 if (!SYMBOLP (var))
10843 continue;
10844
10845 val = find_symbol_value (var);
10846
10847 if (MARKERP (val)
10848 && current_buffer == XMARKER (val)->buffer
10849 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
10850 {
10851 if (FRAME_WINDOW_P (it->f)
10852 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
10853 {
10854 #ifdef HAVE_WINDOW_SYSTEM
10855 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
10856 {
10857 int fringe_bitmap;
10858 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
10859 return make_number (fringe_bitmap);
10860 }
10861 #endif
10862 return make_number (-1); /* Use default arrow bitmap */
10863 }
10864 return overlay_arrow_string_or_property (var);
10865 }
10866 }
10867
10868 return Qnil;
10869 }
10870
10871 /* Return 1 if point moved out of or into a composition. Otherwise
10872 return 0. PREV_BUF and PREV_PT are the last point buffer and
10873 position. BUF and PT are the current point buffer and position. */
10874
10875 int
10876 check_point_in_composition (prev_buf, prev_pt, buf, pt)
10877 struct buffer *prev_buf, *buf;
10878 int prev_pt, pt;
10879 {
10880 EMACS_INT start, end;
10881 Lisp_Object prop;
10882 Lisp_Object buffer;
10883
10884 XSETBUFFER (buffer, buf);
10885 /* Check a composition at the last point if point moved within the
10886 same buffer. */
10887 if (prev_buf == buf)
10888 {
10889 if (prev_pt == pt)
10890 /* Point didn't move. */
10891 return 0;
10892
10893 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
10894 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
10895 && COMPOSITION_VALID_P (start, end, prop)
10896 && start < prev_pt && end > prev_pt)
10897 /* The last point was within the composition. Return 1 iff
10898 point moved out of the composition. */
10899 return (pt <= start || pt >= end);
10900 }
10901
10902 /* Check a composition at the current point. */
10903 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
10904 && find_composition (pt, -1, &start, &end, &prop, buffer)
10905 && COMPOSITION_VALID_P (start, end, prop)
10906 && start < pt && end > pt);
10907 }
10908
10909
10910 /* Reconsider the setting of B->clip_changed which is displayed
10911 in window W. */
10912
10913 static INLINE void
10914 reconsider_clip_changes (w, b)
10915 struct window *w;
10916 struct buffer *b;
10917 {
10918 if (b->clip_changed
10919 && !NILP (w->window_end_valid)
10920 && w->current_matrix->buffer == b
10921 && w->current_matrix->zv == BUF_ZV (b)
10922 && w->current_matrix->begv == BUF_BEGV (b))
10923 b->clip_changed = 0;
10924
10925 /* If display wasn't paused, and W is not a tool bar window, see if
10926 point has been moved into or out of a composition. In that case,
10927 we set b->clip_changed to 1 to force updating the screen. If
10928 b->clip_changed has already been set to 1, we can skip this
10929 check. */
10930 if (!b->clip_changed
10931 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
10932 {
10933 int pt;
10934
10935 if (w == XWINDOW (selected_window))
10936 pt = BUF_PT (current_buffer);
10937 else
10938 pt = marker_position (w->pointm);
10939
10940 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
10941 || pt != XINT (w->last_point))
10942 && check_point_in_composition (w->current_matrix->buffer,
10943 XINT (w->last_point),
10944 XBUFFER (w->buffer), pt))
10945 b->clip_changed = 1;
10946 }
10947 }
10948 \f
10949
10950 /* Select FRAME to forward the values of frame-local variables into C
10951 variables so that the redisplay routines can access those values
10952 directly. */
10953
10954 static void
10955 select_frame_for_redisplay (frame)
10956 Lisp_Object frame;
10957 {
10958 Lisp_Object tail, sym, val;
10959 Lisp_Object old = selected_frame;
10960
10961 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
10962
10963 selected_frame = frame;
10964
10965 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
10966 if (CONSP (XCAR (tail))
10967 && (sym = XCAR (XCAR (tail)),
10968 SYMBOLP (sym))
10969 && (sym = indirect_variable (sym),
10970 val = SYMBOL_VALUE (sym),
10971 (BUFFER_LOCAL_VALUEP (val)
10972 || SOME_BUFFER_LOCAL_VALUEP (val)))
10973 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10974 /* Use find_symbol_value rather than Fsymbol_value
10975 to avoid an error if it is void. */
10976 find_symbol_value (sym);
10977
10978 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
10979 if (CONSP (XCAR (tail))
10980 && (sym = XCAR (XCAR (tail)),
10981 SYMBOLP (sym))
10982 && (sym = indirect_variable (sym),
10983 val = SYMBOL_VALUE (sym),
10984 (BUFFER_LOCAL_VALUEP (val)
10985 || SOME_BUFFER_LOCAL_VALUEP (val)))
10986 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10987 find_symbol_value (sym);
10988 }
10989
10990
10991 #define STOP_POLLING \
10992 do { if (! polling_stopped_here) stop_polling (); \
10993 polling_stopped_here = 1; } while (0)
10994
10995 #define RESUME_POLLING \
10996 do { if (polling_stopped_here) start_polling (); \
10997 polling_stopped_here = 0; } while (0)
10998
10999
11000 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11001 response to any user action; therefore, we should preserve the echo
11002 area. (Actually, our caller does that job.) Perhaps in the future
11003 avoid recentering windows if it is not necessary; currently that
11004 causes some problems. */
11005
11006 static void
11007 redisplay_internal (preserve_echo_area)
11008 int preserve_echo_area;
11009 {
11010 struct window *w = XWINDOW (selected_window);
11011 struct frame *f;
11012 int pause;
11013 int must_finish = 0;
11014 struct text_pos tlbufpos, tlendpos;
11015 int number_of_visible_frames;
11016 int count, count1;
11017 struct frame *sf;
11018 int polling_stopped_here = 0;
11019 Lisp_Object old_frame = selected_frame;
11020
11021 /* Non-zero means redisplay has to consider all windows on all
11022 frames. Zero means, only selected_window is considered. */
11023 int consider_all_windows_p;
11024
11025 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11026
11027 /* No redisplay if running in batch mode or frame is not yet fully
11028 initialized, or redisplay is explicitly turned off by setting
11029 Vinhibit_redisplay. */
11030 if (noninteractive
11031 || !NILP (Vinhibit_redisplay))
11032 return;
11033
11034 /* Don't examine these until after testing Vinhibit_redisplay.
11035 When Emacs is shutting down, perhaps because its connection to
11036 X has dropped, we should not look at them at all. */
11037 f = XFRAME (w->frame);
11038 sf = SELECTED_FRAME ();
11039
11040 if (!f->glyphs_initialized_p)
11041 return;
11042
11043 /* The flag redisplay_performed_directly_p is set by
11044 direct_output_for_insert when it already did the whole screen
11045 update necessary. */
11046 if (redisplay_performed_directly_p)
11047 {
11048 redisplay_performed_directly_p = 0;
11049 if (!hscroll_windows (selected_window))
11050 return;
11051 }
11052
11053 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
11054 if (popup_activated ())
11055 return;
11056 #endif
11057
11058 /* I don't think this happens but let's be paranoid. */
11059 if (redisplaying_p)
11060 return;
11061
11062 /* Record a function that resets redisplaying_p to its old value
11063 when we leave this function. */
11064 count = SPECPDL_INDEX ();
11065 record_unwind_protect (unwind_redisplay,
11066 Fcons (make_number (redisplaying_p), selected_frame));
11067 ++redisplaying_p;
11068 specbind (Qinhibit_free_realized_faces, Qnil);
11069
11070 {
11071 Lisp_Object tail, frame;
11072
11073 FOR_EACH_FRAME (tail, frame)
11074 {
11075 struct frame *f = XFRAME (frame);
11076 f->already_hscrolled_p = 0;
11077 }
11078 }
11079
11080 retry:
11081 if (!EQ (old_frame, selected_frame)
11082 && FRAME_LIVE_P (XFRAME (old_frame)))
11083 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11084 selected_frame and selected_window to be temporarily out-of-sync so
11085 when we come back here via `goto retry', we need to resync because we
11086 may need to run Elisp code (via prepare_menu_bars). */
11087 select_frame_for_redisplay (old_frame);
11088
11089 pause = 0;
11090 reconsider_clip_changes (w, current_buffer);
11091 last_escape_glyph_frame = NULL;
11092 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11093
11094 /* If new fonts have been loaded that make a glyph matrix adjustment
11095 necessary, do it. */
11096 if (fonts_changed_p)
11097 {
11098 adjust_glyphs (NULL);
11099 ++windows_or_buffers_changed;
11100 fonts_changed_p = 0;
11101 }
11102
11103 /* If face_change_count is non-zero, init_iterator will free all
11104 realized faces, which includes the faces referenced from current
11105 matrices. So, we can't reuse current matrices in this case. */
11106 if (face_change_count)
11107 ++windows_or_buffers_changed;
11108
11109 if (FRAME_TERMCAP_P (sf)
11110 && FRAME_TTY (sf)->previous_frame != sf)
11111 {
11112 /* Since frames on a single ASCII terminal share the same
11113 display area, displaying a different frame means redisplay
11114 the whole thing. */
11115 windows_or_buffers_changed++;
11116 SET_FRAME_GARBAGED (sf);
11117 FRAME_TTY (sf)->previous_frame = sf;
11118 }
11119
11120 /* Set the visible flags for all frames. Do this before checking
11121 for resized or garbaged frames; they want to know if their frames
11122 are visible. See the comment in frame.h for
11123 FRAME_SAMPLE_VISIBILITY. */
11124 {
11125 Lisp_Object tail, frame;
11126
11127 number_of_visible_frames = 0;
11128
11129 FOR_EACH_FRAME (tail, frame)
11130 {
11131 struct frame *f = XFRAME (frame);
11132
11133 FRAME_SAMPLE_VISIBILITY (f);
11134 if (FRAME_VISIBLE_P (f))
11135 ++number_of_visible_frames;
11136 clear_desired_matrices (f);
11137 }
11138 }
11139
11140
11141 /* Notice any pending interrupt request to change frame size. */
11142 do_pending_window_change (1);
11143
11144 /* Clear frames marked as garbaged. */
11145 if (frame_garbaged)
11146 clear_garbaged_frames ();
11147
11148 /* Build menubar and tool-bar items. */
11149 if (NILP (Vmemory_full))
11150 prepare_menu_bars ();
11151
11152 if (windows_or_buffers_changed)
11153 update_mode_lines++;
11154
11155 /* Detect case that we need to write or remove a star in the mode line. */
11156 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11157 {
11158 w->update_mode_line = Qt;
11159 if (buffer_shared > 1)
11160 update_mode_lines++;
11161 }
11162
11163 /* Avoid invocation of point motion hooks by `current_column' below. */
11164 count1 = SPECPDL_INDEX ();
11165 specbind (Qinhibit_point_motion_hooks, Qt);
11166
11167 /* If %c is in the mode line, update it if needed. */
11168 if (!NILP (w->column_number_displayed)
11169 /* This alternative quickly identifies a common case
11170 where no change is needed. */
11171 && !(PT == XFASTINT (w->last_point)
11172 && XFASTINT (w->last_modified) >= MODIFF
11173 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11174 && (XFASTINT (w->column_number_displayed)
11175 != (int) current_column ())) /* iftc */
11176 w->update_mode_line = Qt;
11177
11178 unbind_to (count1, Qnil);
11179
11180 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11181
11182 /* The variable buffer_shared is set in redisplay_window and
11183 indicates that we redisplay a buffer in different windows. See
11184 there. */
11185 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11186 || cursor_type_changed);
11187
11188 /* If specs for an arrow have changed, do thorough redisplay
11189 to ensure we remove any arrow that should no longer exist. */
11190 if (overlay_arrows_changed_p ())
11191 consider_all_windows_p = windows_or_buffers_changed = 1;
11192
11193 /* Normally the message* functions will have already displayed and
11194 updated the echo area, but the frame may have been trashed, or
11195 the update may have been preempted, so display the echo area
11196 again here. Checking message_cleared_p captures the case that
11197 the echo area should be cleared. */
11198 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11199 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11200 || (message_cleared_p
11201 && minibuf_level == 0
11202 /* If the mini-window is currently selected, this means the
11203 echo-area doesn't show through. */
11204 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11205 {
11206 int window_height_changed_p = echo_area_display (0);
11207 must_finish = 1;
11208
11209 /* If we don't display the current message, don't clear the
11210 message_cleared_p flag, because, if we did, we wouldn't clear
11211 the echo area in the next redisplay which doesn't preserve
11212 the echo area. */
11213 if (!display_last_displayed_message_p)
11214 message_cleared_p = 0;
11215
11216 if (fonts_changed_p)
11217 goto retry;
11218 else if (window_height_changed_p)
11219 {
11220 consider_all_windows_p = 1;
11221 ++update_mode_lines;
11222 ++windows_or_buffers_changed;
11223
11224 /* If window configuration was changed, frames may have been
11225 marked garbaged. Clear them or we will experience
11226 surprises wrt scrolling. */
11227 if (frame_garbaged)
11228 clear_garbaged_frames ();
11229 }
11230 }
11231 else if (EQ (selected_window, minibuf_window)
11232 && (current_buffer->clip_changed
11233 || XFASTINT (w->last_modified) < MODIFF
11234 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11235 && resize_mini_window (w, 0))
11236 {
11237 /* Resized active mini-window to fit the size of what it is
11238 showing if its contents might have changed. */
11239 must_finish = 1;
11240 consider_all_windows_p = 1;
11241 ++windows_or_buffers_changed;
11242 ++update_mode_lines;
11243
11244 /* If window configuration was changed, frames may have been
11245 marked garbaged. Clear them or we will experience
11246 surprises wrt scrolling. */
11247 if (frame_garbaged)
11248 clear_garbaged_frames ();
11249 }
11250
11251
11252 /* If showing the region, and mark has changed, we must redisplay
11253 the whole window. The assignment to this_line_start_pos prevents
11254 the optimization directly below this if-statement. */
11255 if (((!NILP (Vtransient_mark_mode)
11256 && !NILP (XBUFFER (w->buffer)->mark_active))
11257 != !NILP (w->region_showing))
11258 || (!NILP (w->region_showing)
11259 && !EQ (w->region_showing,
11260 Fmarker_position (XBUFFER (w->buffer)->mark))))
11261 CHARPOS (this_line_start_pos) = 0;
11262
11263 /* Optimize the case that only the line containing the cursor in the
11264 selected window has changed. Variables starting with this_ are
11265 set in display_line and record information about the line
11266 containing the cursor. */
11267 tlbufpos = this_line_start_pos;
11268 tlendpos = this_line_end_pos;
11269 if (!consider_all_windows_p
11270 && CHARPOS (tlbufpos) > 0
11271 && NILP (w->update_mode_line)
11272 && !current_buffer->clip_changed
11273 && !current_buffer->prevent_redisplay_optimizations_p
11274 && FRAME_VISIBLE_P (XFRAME (w->frame))
11275 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11276 /* Make sure recorded data applies to current buffer, etc. */
11277 && this_line_buffer == current_buffer
11278 && current_buffer == XBUFFER (w->buffer)
11279 && NILP (w->force_start)
11280 && NILP (w->optional_new_start)
11281 /* Point must be on the line that we have info recorded about. */
11282 && PT >= CHARPOS (tlbufpos)
11283 && PT <= Z - CHARPOS (tlendpos)
11284 /* All text outside that line, including its final newline,
11285 must be unchanged */
11286 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11287 CHARPOS (tlendpos)))
11288 {
11289 if (CHARPOS (tlbufpos) > BEGV
11290 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11291 && (CHARPOS (tlbufpos) == ZV
11292 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11293 /* Former continuation line has disappeared by becoming empty */
11294 goto cancel;
11295 else if (XFASTINT (w->last_modified) < MODIFF
11296 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11297 || MINI_WINDOW_P (w))
11298 {
11299 /* We have to handle the case of continuation around a
11300 wide-column character (See the comment in indent.c around
11301 line 885).
11302
11303 For instance, in the following case:
11304
11305 -------- Insert --------
11306 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11307 J_I_ ==> J_I_ `^^' are cursors.
11308 ^^ ^^
11309 -------- --------
11310
11311 As we have to redraw the line above, we should goto cancel. */
11312
11313 struct it it;
11314 int line_height_before = this_line_pixel_height;
11315
11316 /* Note that start_display will handle the case that the
11317 line starting at tlbufpos is a continuation lines. */
11318 start_display (&it, w, tlbufpos);
11319
11320 /* Implementation note: It this still necessary? */
11321 if (it.current_x != this_line_start_x)
11322 goto cancel;
11323
11324 TRACE ((stderr, "trying display optimization 1\n"));
11325 w->cursor.vpos = -1;
11326 overlay_arrow_seen = 0;
11327 it.vpos = this_line_vpos;
11328 it.current_y = this_line_y;
11329 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11330 display_line (&it);
11331
11332 /* If line contains point, is not continued,
11333 and ends at same distance from eob as before, we win */
11334 if (w->cursor.vpos >= 0
11335 /* Line is not continued, otherwise this_line_start_pos
11336 would have been set to 0 in display_line. */
11337 && CHARPOS (this_line_start_pos)
11338 /* Line ends as before. */
11339 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11340 /* Line has same height as before. Otherwise other lines
11341 would have to be shifted up or down. */
11342 && this_line_pixel_height == line_height_before)
11343 {
11344 /* If this is not the window's last line, we must adjust
11345 the charstarts of the lines below. */
11346 if (it.current_y < it.last_visible_y)
11347 {
11348 struct glyph_row *row
11349 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11350 int delta, delta_bytes;
11351
11352 if (Z - CHARPOS (tlendpos) == ZV)
11353 {
11354 /* This line ends at end of (accessible part of)
11355 buffer. There is no newline to count. */
11356 delta = (Z
11357 - CHARPOS (tlendpos)
11358 - MATRIX_ROW_START_CHARPOS (row));
11359 delta_bytes = (Z_BYTE
11360 - BYTEPOS (tlendpos)
11361 - MATRIX_ROW_START_BYTEPOS (row));
11362 }
11363 else
11364 {
11365 /* This line ends in a newline. Must take
11366 account of the newline and the rest of the
11367 text that follows. */
11368 delta = (Z
11369 - CHARPOS (tlendpos)
11370 - MATRIX_ROW_START_CHARPOS (row));
11371 delta_bytes = (Z_BYTE
11372 - BYTEPOS (tlendpos)
11373 - MATRIX_ROW_START_BYTEPOS (row));
11374 }
11375
11376 increment_matrix_positions (w->current_matrix,
11377 this_line_vpos + 1,
11378 w->current_matrix->nrows,
11379 delta, delta_bytes);
11380 }
11381
11382 /* If this row displays text now but previously didn't,
11383 or vice versa, w->window_end_vpos may have to be
11384 adjusted. */
11385 if ((it.glyph_row - 1)->displays_text_p)
11386 {
11387 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11388 XSETINT (w->window_end_vpos, this_line_vpos);
11389 }
11390 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11391 && this_line_vpos > 0)
11392 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11393 w->window_end_valid = Qnil;
11394
11395 /* Update hint: No need to try to scroll in update_window. */
11396 w->desired_matrix->no_scrolling_p = 1;
11397
11398 #if GLYPH_DEBUG
11399 *w->desired_matrix->method = 0;
11400 debug_method_add (w, "optimization 1");
11401 #endif
11402 #ifdef HAVE_WINDOW_SYSTEM
11403 update_window_fringes (w, 0);
11404 #endif
11405 goto update;
11406 }
11407 else
11408 goto cancel;
11409 }
11410 else if (/* Cursor position hasn't changed. */
11411 PT == XFASTINT (w->last_point)
11412 /* Make sure the cursor was last displayed
11413 in this window. Otherwise we have to reposition it. */
11414 && 0 <= w->cursor.vpos
11415 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11416 {
11417 if (!must_finish)
11418 {
11419 do_pending_window_change (1);
11420
11421 /* We used to always goto end_of_redisplay here, but this
11422 isn't enough if we have a blinking cursor. */
11423 if (w->cursor_off_p == w->last_cursor_off_p)
11424 goto end_of_redisplay;
11425 }
11426 goto update;
11427 }
11428 /* If highlighting the region, or if the cursor is in the echo area,
11429 then we can't just move the cursor. */
11430 else if (! (!NILP (Vtransient_mark_mode)
11431 && !NILP (current_buffer->mark_active))
11432 && (EQ (selected_window, current_buffer->last_selected_window)
11433 || highlight_nonselected_windows)
11434 && NILP (w->region_showing)
11435 && NILP (Vshow_trailing_whitespace)
11436 && !cursor_in_echo_area)
11437 {
11438 struct it it;
11439 struct glyph_row *row;
11440
11441 /* Skip from tlbufpos to PT and see where it is. Note that
11442 PT may be in invisible text. If so, we will end at the
11443 next visible position. */
11444 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11445 NULL, DEFAULT_FACE_ID);
11446 it.current_x = this_line_start_x;
11447 it.current_y = this_line_y;
11448 it.vpos = this_line_vpos;
11449
11450 /* The call to move_it_to stops in front of PT, but
11451 moves over before-strings. */
11452 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11453
11454 if (it.vpos == this_line_vpos
11455 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11456 row->enabled_p))
11457 {
11458 xassert (this_line_vpos == it.vpos);
11459 xassert (this_line_y == it.current_y);
11460 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11461 #if GLYPH_DEBUG
11462 *w->desired_matrix->method = 0;
11463 debug_method_add (w, "optimization 3");
11464 #endif
11465 goto update;
11466 }
11467 else
11468 goto cancel;
11469 }
11470
11471 cancel:
11472 /* Text changed drastically or point moved off of line. */
11473 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11474 }
11475
11476 CHARPOS (this_line_start_pos) = 0;
11477 consider_all_windows_p |= buffer_shared > 1;
11478 ++clear_face_cache_count;
11479 #ifdef HAVE_WINDOW_SYSTEM
11480 ++clear_image_cache_count;
11481 #endif
11482
11483 /* Build desired matrices, and update the display. If
11484 consider_all_windows_p is non-zero, do it for all windows on all
11485 frames. Otherwise do it for selected_window, only. */
11486
11487 if (consider_all_windows_p)
11488 {
11489 Lisp_Object tail, frame;
11490
11491 FOR_EACH_FRAME (tail, frame)
11492 XFRAME (frame)->updated_p = 0;
11493
11494 /* Recompute # windows showing selected buffer. This will be
11495 incremented each time such a window is displayed. */
11496 buffer_shared = 0;
11497
11498 FOR_EACH_FRAME (tail, frame)
11499 {
11500 struct frame *f = XFRAME (frame);
11501
11502 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
11503 {
11504 if (! EQ (frame, selected_frame))
11505 /* Select the frame, for the sake of frame-local
11506 variables. */
11507 select_frame_for_redisplay (frame);
11508
11509 /* Mark all the scroll bars to be removed; we'll redeem
11510 the ones we want when we redisplay their windows. */
11511 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
11512 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
11513
11514 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11515 redisplay_windows (FRAME_ROOT_WINDOW (f));
11516
11517 /* Any scroll bars which redisplay_windows should have
11518 nuked should now go away. */
11519 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
11520 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
11521
11522 /* If fonts changed, display again. */
11523 /* ??? rms: I suspect it is a mistake to jump all the way
11524 back to retry here. It should just retry this frame. */
11525 if (fonts_changed_p)
11526 goto retry;
11527
11528 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11529 {
11530 /* See if we have to hscroll. */
11531 if (!f->already_hscrolled_p)
11532 {
11533 f->already_hscrolled_p = 1;
11534 if (hscroll_windows (f->root_window))
11535 goto retry;
11536 }
11537
11538 /* Prevent various kinds of signals during display
11539 update. stdio is not robust about handling
11540 signals, which can cause an apparent I/O
11541 error. */
11542 if (interrupt_input)
11543 unrequest_sigio ();
11544 STOP_POLLING;
11545
11546 /* Update the display. */
11547 set_window_update_flags (XWINDOW (f->root_window), 1);
11548 pause |= update_frame (f, 0, 0);
11549 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
11550 if (pause)
11551 break;
11552 #endif
11553
11554 f->updated_p = 1;
11555 }
11556 }
11557 }
11558
11559 if (!pause)
11560 {
11561 /* Do the mark_window_display_accurate after all windows have
11562 been redisplayed because this call resets flags in buffers
11563 which are needed for proper redisplay. */
11564 FOR_EACH_FRAME (tail, frame)
11565 {
11566 struct frame *f = XFRAME (frame);
11567 if (f->updated_p)
11568 {
11569 mark_window_display_accurate (f->root_window, 1);
11570 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
11571 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
11572 }
11573 }
11574 }
11575 }
11576 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11577 {
11578 Lisp_Object mini_window;
11579 struct frame *mini_frame;
11580
11581 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
11582 /* Use list_of_error, not Qerror, so that
11583 we catch only errors and don't run the debugger. */
11584 internal_condition_case_1 (redisplay_window_1, selected_window,
11585 list_of_error,
11586 redisplay_window_error);
11587
11588 /* Compare desired and current matrices, perform output. */
11589
11590 update:
11591 /* If fonts changed, display again. */
11592 if (fonts_changed_p)
11593 goto retry;
11594
11595 /* Prevent various kinds of signals during display update.
11596 stdio is not robust about handling signals,
11597 which can cause an apparent I/O error. */
11598 if (interrupt_input)
11599 unrequest_sigio ();
11600 STOP_POLLING;
11601
11602 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11603 {
11604 if (hscroll_windows (selected_window))
11605 goto retry;
11606
11607 XWINDOW (selected_window)->must_be_updated_p = 1;
11608 pause = update_frame (sf, 0, 0);
11609 }
11610
11611 /* We may have called echo_area_display at the top of this
11612 function. If the echo area is on another frame, that may
11613 have put text on a frame other than the selected one, so the
11614 above call to update_frame would not have caught it. Catch
11615 it here. */
11616 mini_window = FRAME_MINIBUF_WINDOW (sf);
11617 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
11618
11619 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
11620 {
11621 XWINDOW (mini_window)->must_be_updated_p = 1;
11622 pause |= update_frame (mini_frame, 0, 0);
11623 if (!pause && hscroll_windows (mini_window))
11624 goto retry;
11625 }
11626 }
11627
11628 /* If display was paused because of pending input, make sure we do a
11629 thorough update the next time. */
11630 if (pause)
11631 {
11632 /* Prevent the optimization at the beginning of
11633 redisplay_internal that tries a single-line update of the
11634 line containing the cursor in the selected window. */
11635 CHARPOS (this_line_start_pos) = 0;
11636
11637 /* Let the overlay arrow be updated the next time. */
11638 update_overlay_arrows (0);
11639
11640 /* If we pause after scrolling, some rows in the current
11641 matrices of some windows are not valid. */
11642 if (!WINDOW_FULL_WIDTH_P (w)
11643 && !FRAME_WINDOW_P (XFRAME (w->frame)))
11644 update_mode_lines = 1;
11645 }
11646 else
11647 {
11648 if (!consider_all_windows_p)
11649 {
11650 /* This has already been done above if
11651 consider_all_windows_p is set. */
11652 mark_window_display_accurate_1 (w, 1);
11653
11654 /* Say overlay arrows are up to date. */
11655 update_overlay_arrows (1);
11656
11657 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
11658 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
11659 }
11660
11661 update_mode_lines = 0;
11662 windows_or_buffers_changed = 0;
11663 cursor_type_changed = 0;
11664 }
11665
11666 /* Start SIGIO interrupts coming again. Having them off during the
11667 code above makes it less likely one will discard output, but not
11668 impossible, since there might be stuff in the system buffer here.
11669 But it is much hairier to try to do anything about that. */
11670 if (interrupt_input)
11671 request_sigio ();
11672 RESUME_POLLING;
11673
11674 /* If a frame has become visible which was not before, redisplay
11675 again, so that we display it. Expose events for such a frame
11676 (which it gets when becoming visible) don't call the parts of
11677 redisplay constructing glyphs, so simply exposing a frame won't
11678 display anything in this case. So, we have to display these
11679 frames here explicitly. */
11680 if (!pause)
11681 {
11682 Lisp_Object tail, frame;
11683 int new_count = 0;
11684
11685 FOR_EACH_FRAME (tail, frame)
11686 {
11687 int this_is_visible = 0;
11688
11689 if (XFRAME (frame)->visible)
11690 this_is_visible = 1;
11691 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
11692 if (XFRAME (frame)->visible)
11693 this_is_visible = 1;
11694
11695 if (this_is_visible)
11696 new_count++;
11697 }
11698
11699 if (new_count != number_of_visible_frames)
11700 windows_or_buffers_changed++;
11701 }
11702
11703 /* Change frame size now if a change is pending. */
11704 do_pending_window_change (1);
11705
11706 /* If we just did a pending size change, or have additional
11707 visible frames, redisplay again. */
11708 if (windows_or_buffers_changed && !pause)
11709 goto retry;
11710
11711 /* Clear the face cache eventually. */
11712 if (consider_all_windows_p)
11713 {
11714 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
11715 {
11716 clear_face_cache (0);
11717 clear_face_cache_count = 0;
11718 }
11719 #ifdef HAVE_WINDOW_SYSTEM
11720 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
11721 {
11722 Lisp_Object tail, frame;
11723 FOR_EACH_FRAME (tail, frame)
11724 {
11725 struct frame *f = XFRAME (frame);
11726 if (FRAME_WINDOW_P (f))
11727 clear_image_cache (f, 0);
11728 }
11729 clear_image_cache_count = 0;
11730 }
11731 #endif /* HAVE_WINDOW_SYSTEM */
11732 }
11733
11734 end_of_redisplay:
11735 unbind_to (count, Qnil);
11736 RESUME_POLLING;
11737 }
11738
11739
11740 /* Redisplay, but leave alone any recent echo area message unless
11741 another message has been requested in its place.
11742
11743 This is useful in situations where you need to redisplay but no
11744 user action has occurred, making it inappropriate for the message
11745 area to be cleared. See tracking_off and
11746 wait_reading_process_output for examples of these situations.
11747
11748 FROM_WHERE is an integer saying from where this function was
11749 called. This is useful for debugging. */
11750
11751 void
11752 redisplay_preserve_echo_area (from_where)
11753 int from_where;
11754 {
11755 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
11756
11757 if (!NILP (echo_area_buffer[1]))
11758 {
11759 /* We have a previously displayed message, but no current
11760 message. Redisplay the previous message. */
11761 display_last_displayed_message_p = 1;
11762 redisplay_internal (1);
11763 display_last_displayed_message_p = 0;
11764 }
11765 else
11766 redisplay_internal (1);
11767
11768 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
11769 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11770 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
11771 }
11772
11773
11774 /* Function registered with record_unwind_protect in
11775 redisplay_internal. Reset redisplaying_p to the value it had
11776 before redisplay_internal was called, and clear
11777 prevent_freeing_realized_faces_p. It also selects the previously
11778 selected frame, unless it has been deleted (by an X connection
11779 failure during redisplay, for example). */
11780
11781 static Lisp_Object
11782 unwind_redisplay (val)
11783 Lisp_Object val;
11784 {
11785 Lisp_Object old_redisplaying_p, old_frame;
11786
11787 old_redisplaying_p = XCAR (val);
11788 redisplaying_p = XFASTINT (old_redisplaying_p);
11789 old_frame = XCDR (val);
11790 if (! EQ (old_frame, selected_frame)
11791 && FRAME_LIVE_P (XFRAME (old_frame)))
11792 select_frame_for_redisplay (old_frame);
11793 return Qnil;
11794 }
11795
11796
11797 /* Mark the display of window W as accurate or inaccurate. If
11798 ACCURATE_P is non-zero mark display of W as accurate. If
11799 ACCURATE_P is zero, arrange for W to be redisplayed the next time
11800 redisplay_internal is called. */
11801
11802 static void
11803 mark_window_display_accurate_1 (w, accurate_p)
11804 struct window *w;
11805 int accurate_p;
11806 {
11807 if (BUFFERP (w->buffer))
11808 {
11809 struct buffer *b = XBUFFER (w->buffer);
11810
11811 w->last_modified
11812 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
11813 w->last_overlay_modified
11814 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
11815 w->last_had_star
11816 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
11817
11818 if (accurate_p)
11819 {
11820 b->clip_changed = 0;
11821 b->prevent_redisplay_optimizations_p = 0;
11822
11823 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
11824 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
11825 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
11826 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
11827
11828 w->current_matrix->buffer = b;
11829 w->current_matrix->begv = BUF_BEGV (b);
11830 w->current_matrix->zv = BUF_ZV (b);
11831
11832 w->last_cursor = w->cursor;
11833 w->last_cursor_off_p = w->cursor_off_p;
11834
11835 if (w == XWINDOW (selected_window))
11836 w->last_point = make_number (BUF_PT (b));
11837 else
11838 w->last_point = make_number (XMARKER (w->pointm)->charpos);
11839 }
11840 }
11841
11842 if (accurate_p)
11843 {
11844 w->window_end_valid = w->buffer;
11845 #if 0 /* This is incorrect with variable-height lines. */
11846 xassert (XINT (w->window_end_vpos)
11847 < (WINDOW_TOTAL_LINES (w)
11848 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
11849 #endif
11850 w->update_mode_line = Qnil;
11851 }
11852 }
11853
11854
11855 /* Mark the display of windows in the window tree rooted at WINDOW as
11856 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
11857 windows as accurate. If ACCURATE_P is zero, arrange for windows to
11858 be redisplayed the next time redisplay_internal is called. */
11859
11860 void
11861 mark_window_display_accurate (window, accurate_p)
11862 Lisp_Object window;
11863 int accurate_p;
11864 {
11865 struct window *w;
11866
11867 for (; !NILP (window); window = w->next)
11868 {
11869 w = XWINDOW (window);
11870 mark_window_display_accurate_1 (w, accurate_p);
11871
11872 if (!NILP (w->vchild))
11873 mark_window_display_accurate (w->vchild, accurate_p);
11874 if (!NILP (w->hchild))
11875 mark_window_display_accurate (w->hchild, accurate_p);
11876 }
11877
11878 if (accurate_p)
11879 {
11880 update_overlay_arrows (1);
11881 }
11882 else
11883 {
11884 /* Force a thorough redisplay the next time by setting
11885 last_arrow_position and last_arrow_string to t, which is
11886 unequal to any useful value of Voverlay_arrow_... */
11887 update_overlay_arrows (-1);
11888 }
11889 }
11890
11891
11892 /* Return value in display table DP (Lisp_Char_Table *) for character
11893 C. Since a display table doesn't have any parent, we don't have to
11894 follow parent. Do not call this function directly but use the
11895 macro DISP_CHAR_VECTOR. */
11896
11897 Lisp_Object
11898 disp_char_vector (dp, c)
11899 struct Lisp_Char_Table *dp;
11900 int c;
11901 {
11902 Lisp_Object val;
11903
11904 if (ASCII_CHAR_P (c))
11905 {
11906 val = dp->ascii;
11907 if (SUB_CHAR_TABLE_P (val))
11908 val = XSUB_CHAR_TABLE (val)->contents[c];
11909 }
11910 else
11911 {
11912 Lisp_Object table;
11913
11914 XSETCHAR_TABLE (table, dp);
11915 val = char_table_ref (table, c);
11916 }
11917 if (NILP (val))
11918 val = dp->defalt;
11919 return val;
11920 }
11921
11922
11923 \f
11924 /***********************************************************************
11925 Window Redisplay
11926 ***********************************************************************/
11927
11928 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
11929
11930 static void
11931 redisplay_windows (window)
11932 Lisp_Object window;
11933 {
11934 while (!NILP (window))
11935 {
11936 struct window *w = XWINDOW (window);
11937
11938 if (!NILP (w->hchild))
11939 redisplay_windows (w->hchild);
11940 else if (!NILP (w->vchild))
11941 redisplay_windows (w->vchild);
11942 else
11943 {
11944 displayed_buffer = XBUFFER (w->buffer);
11945 /* Use list_of_error, not Qerror, so that
11946 we catch only errors and don't run the debugger. */
11947 internal_condition_case_1 (redisplay_window_0, window,
11948 list_of_error,
11949 redisplay_window_error);
11950 }
11951
11952 window = w->next;
11953 }
11954 }
11955
11956 static Lisp_Object
11957 redisplay_window_error ()
11958 {
11959 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
11960 return Qnil;
11961 }
11962
11963 static Lisp_Object
11964 redisplay_window_0 (window)
11965 Lisp_Object window;
11966 {
11967 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11968 redisplay_window (window, 0);
11969 return Qnil;
11970 }
11971
11972 static Lisp_Object
11973 redisplay_window_1 (window)
11974 Lisp_Object window;
11975 {
11976 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11977 redisplay_window (window, 1);
11978 return Qnil;
11979 }
11980 \f
11981
11982 /* Increment GLYPH until it reaches END or CONDITION fails while
11983 adding (GLYPH)->pixel_width to X. */
11984
11985 #define SKIP_GLYPHS(glyph, end, x, condition) \
11986 do \
11987 { \
11988 (x) += (glyph)->pixel_width; \
11989 ++(glyph); \
11990 } \
11991 while ((glyph) < (end) && (condition))
11992
11993
11994 /* Set cursor position of W. PT is assumed to be displayed in ROW.
11995 DELTA is the number of bytes by which positions recorded in ROW
11996 differ from current buffer positions.
11997
11998 Return 0 if cursor is not on this row. 1 otherwise. */
11999
12000 int
12001 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
12002 struct window *w;
12003 struct glyph_row *row;
12004 struct glyph_matrix *matrix;
12005 int delta, delta_bytes, dy, dvpos;
12006 {
12007 struct glyph *glyph = row->glyphs[TEXT_AREA];
12008 struct glyph *end = glyph + row->used[TEXT_AREA];
12009 struct glyph *cursor = NULL;
12010 /* The first glyph that starts a sequence of glyphs from string. */
12011 struct glyph *string_start;
12012 /* The X coordinate of string_start. */
12013 int string_start_x;
12014 /* The last known character position. */
12015 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12016 /* The last known character position before string_start. */
12017 int string_before_pos;
12018 int x = row->x;
12019 int cursor_x = x;
12020 int cursor_from_overlay_pos = 0;
12021 int pt_old = PT - delta;
12022
12023 /* Skip over glyphs not having an object at the start of the row.
12024 These are special glyphs like truncation marks on terminal
12025 frames. */
12026 if (row->displays_text_p)
12027 while (glyph < end
12028 && INTEGERP (glyph->object)
12029 && glyph->charpos < 0)
12030 {
12031 x += glyph->pixel_width;
12032 ++glyph;
12033 }
12034
12035 string_start = NULL;
12036 while (glyph < end
12037 && !INTEGERP (glyph->object)
12038 && (!BUFFERP (glyph->object)
12039 || (last_pos = glyph->charpos) < pt_old))
12040 {
12041 if (! STRINGP (glyph->object))
12042 {
12043 string_start = NULL;
12044 x += glyph->pixel_width;
12045 ++glyph;
12046 if (cursor_from_overlay_pos
12047 && last_pos >= cursor_from_overlay_pos)
12048 {
12049 cursor_from_overlay_pos = 0;
12050 cursor = 0;
12051 }
12052 }
12053 else
12054 {
12055 if (string_start == NULL)
12056 {
12057 string_before_pos = last_pos;
12058 string_start = glyph;
12059 string_start_x = x;
12060 }
12061 /* Skip all glyphs from string. */
12062 do
12063 {
12064 Lisp_Object cprop;
12065 int pos;
12066 if ((cursor == NULL || glyph > cursor)
12067 && (cprop = Fget_char_property (make_number ((glyph)->charpos),
12068 Qcursor, (glyph)->object),
12069 !NILP (cprop))
12070 && (pos = string_buffer_position (w, glyph->object,
12071 string_before_pos),
12072 (pos == 0 /* From overlay */
12073 || pos == pt_old)))
12074 {
12075 /* Estimate overlay buffer position from the buffer
12076 positions of the glyphs before and after the overlay.
12077 Add 1 to last_pos so that if point corresponds to the
12078 glyph right after the overlay, we still use a 'cursor'
12079 property found in that overlay. */
12080 cursor_from_overlay_pos = (pos ? 0 : last_pos
12081 + (INTEGERP (cprop) ? XINT (cprop) : 0));
12082 cursor = glyph;
12083 cursor_x = x;
12084 }
12085 x += glyph->pixel_width;
12086 ++glyph;
12087 }
12088 while (glyph < end && EQ (glyph->object, string_start->object));
12089 }
12090 }
12091
12092 if (cursor != NULL)
12093 {
12094 glyph = cursor;
12095 x = cursor_x;
12096 }
12097 else if (row->ends_in_ellipsis_p && glyph == end)
12098 {
12099 /* Scan back over the ellipsis glyphs, decrementing positions. */
12100 while (glyph > row->glyphs[TEXT_AREA]
12101 && (glyph - 1)->charpos == last_pos)
12102 glyph--, x -= glyph->pixel_width;
12103 /* That loop always goes one position too far,
12104 including the glyph before the ellipsis.
12105 So scan forward over that one. */
12106 x += glyph->pixel_width;
12107 glyph++;
12108 }
12109 else if (string_start
12110 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
12111 {
12112 /* We may have skipped over point because the previous glyphs
12113 are from string. As there's no easy way to know the
12114 character position of the current glyph, find the correct
12115 glyph on point by scanning from string_start again. */
12116 Lisp_Object limit;
12117 Lisp_Object string;
12118 struct glyph *stop = glyph;
12119 int pos;
12120
12121 limit = make_number (pt_old + 1);
12122 glyph = string_start;
12123 x = string_start_x;
12124 string = glyph->object;
12125 pos = string_buffer_position (w, string, string_before_pos);
12126 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
12127 because we always put cursor after overlay strings. */
12128 while (pos == 0 && glyph < stop)
12129 {
12130 string = glyph->object;
12131 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12132 if (glyph < stop)
12133 pos = string_buffer_position (w, glyph->object, string_before_pos);
12134 }
12135
12136 while (glyph < stop)
12137 {
12138 pos = XINT (Fnext_single_char_property_change
12139 (make_number (pos), Qdisplay, Qnil, limit));
12140 if (pos > pt_old)
12141 break;
12142 /* Skip glyphs from the same string. */
12143 string = glyph->object;
12144 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12145 /* Skip glyphs from an overlay. */
12146 while (glyph < stop
12147 && ! string_buffer_position (w, glyph->object, pos))
12148 {
12149 string = glyph->object;
12150 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12151 }
12152 }
12153
12154 /* If we reached the end of the line, and end was from a string,
12155 cursor is not on this line. */
12156 if (glyph == end && row->continued_p)
12157 return 0;
12158 }
12159
12160 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12161 w->cursor.x = x;
12162 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12163 w->cursor.y = row->y + dy;
12164
12165 if (w == XWINDOW (selected_window))
12166 {
12167 if (!row->continued_p
12168 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12169 && row->x == 0)
12170 {
12171 this_line_buffer = XBUFFER (w->buffer);
12172
12173 CHARPOS (this_line_start_pos)
12174 = MATRIX_ROW_START_CHARPOS (row) + delta;
12175 BYTEPOS (this_line_start_pos)
12176 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12177
12178 CHARPOS (this_line_end_pos)
12179 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12180 BYTEPOS (this_line_end_pos)
12181 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12182
12183 this_line_y = w->cursor.y;
12184 this_line_pixel_height = row->height;
12185 this_line_vpos = w->cursor.vpos;
12186 this_line_start_x = row->x;
12187 }
12188 else
12189 CHARPOS (this_line_start_pos) = 0;
12190 }
12191
12192 return 1;
12193 }
12194
12195
12196 /* Run window scroll functions, if any, for WINDOW with new window
12197 start STARTP. Sets the window start of WINDOW to that position.
12198
12199 We assume that the window's buffer is really current. */
12200
12201 static INLINE struct text_pos
12202 run_window_scroll_functions (window, startp)
12203 Lisp_Object window;
12204 struct text_pos startp;
12205 {
12206 struct window *w = XWINDOW (window);
12207 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12208
12209 if (current_buffer != XBUFFER (w->buffer))
12210 abort ();
12211
12212 if (!NILP (Vwindow_scroll_functions))
12213 {
12214 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12215 make_number (CHARPOS (startp)));
12216 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12217 /* In case the hook functions switch buffers. */
12218 if (current_buffer != XBUFFER (w->buffer))
12219 set_buffer_internal_1 (XBUFFER (w->buffer));
12220 }
12221
12222 return startp;
12223 }
12224
12225
12226 /* Make sure the line containing the cursor is fully visible.
12227 A value of 1 means there is nothing to be done.
12228 (Either the line is fully visible, or it cannot be made so,
12229 or we cannot tell.)
12230
12231 If FORCE_P is non-zero, return 0 even if partial visible cursor row
12232 is higher than window.
12233
12234 A value of 0 means the caller should do scrolling
12235 as if point had gone off the screen. */
12236
12237 static int
12238 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
12239 struct window *w;
12240 int force_p;
12241 int current_matrix_p;
12242 {
12243 struct glyph_matrix *matrix;
12244 struct glyph_row *row;
12245 int window_height;
12246
12247 if (!make_cursor_line_fully_visible_p)
12248 return 1;
12249
12250 /* It's not always possible to find the cursor, e.g, when a window
12251 is full of overlay strings. Don't do anything in that case. */
12252 if (w->cursor.vpos < 0)
12253 return 1;
12254
12255 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
12256 row = MATRIX_ROW (matrix, w->cursor.vpos);
12257
12258 /* If the cursor row is not partially visible, there's nothing to do. */
12259 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
12260 return 1;
12261
12262 /* If the row the cursor is in is taller than the window's height,
12263 it's not clear what to do, so do nothing. */
12264 window_height = window_box_height (w);
12265 if (row->height >= window_height)
12266 {
12267 if (!force_p || MINI_WINDOW_P (w)
12268 || w->vscroll || w->cursor.vpos == 0)
12269 return 1;
12270 }
12271 return 0;
12272
12273 #if 0
12274 /* This code used to try to scroll the window just enough to make
12275 the line visible. It returned 0 to say that the caller should
12276 allocate larger glyph matrices. */
12277
12278 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
12279 {
12280 int dy = row->height - row->visible_height;
12281 w->vscroll = 0;
12282 w->cursor.y += dy;
12283 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12284 }
12285 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
12286 {
12287 int dy = - (row->height - row->visible_height);
12288 w->vscroll = dy;
12289 w->cursor.y += dy;
12290 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12291 }
12292
12293 /* When we change the cursor y-position of the selected window,
12294 change this_line_y as well so that the display optimization for
12295 the cursor line of the selected window in redisplay_internal uses
12296 the correct y-position. */
12297 if (w == XWINDOW (selected_window))
12298 this_line_y = w->cursor.y;
12299
12300 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
12301 redisplay with larger matrices. */
12302 if (matrix->nrows < required_matrix_height (w))
12303 {
12304 fonts_changed_p = 1;
12305 return 0;
12306 }
12307
12308 return 1;
12309 #endif /* 0 */
12310 }
12311
12312
12313 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
12314 non-zero means only WINDOW is redisplayed in redisplay_internal.
12315 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
12316 in redisplay_window to bring a partially visible line into view in
12317 the case that only the cursor has moved.
12318
12319 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
12320 last screen line's vertical height extends past the end of the screen.
12321
12322 Value is
12323
12324 1 if scrolling succeeded
12325
12326 0 if scrolling didn't find point.
12327
12328 -1 if new fonts have been loaded so that we must interrupt
12329 redisplay, adjust glyph matrices, and try again. */
12330
12331 enum
12332 {
12333 SCROLLING_SUCCESS,
12334 SCROLLING_FAILED,
12335 SCROLLING_NEED_LARGER_MATRICES
12336 };
12337
12338 static int
12339 try_scrolling (window, just_this_one_p, scroll_conservatively,
12340 scroll_step, temp_scroll_step, last_line_misfit)
12341 Lisp_Object window;
12342 int just_this_one_p;
12343 EMACS_INT scroll_conservatively, scroll_step;
12344 int temp_scroll_step;
12345 int last_line_misfit;
12346 {
12347 struct window *w = XWINDOW (window);
12348 struct frame *f = XFRAME (w->frame);
12349 struct text_pos scroll_margin_pos;
12350 struct text_pos pos;
12351 struct text_pos startp;
12352 struct it it;
12353 Lisp_Object window_end;
12354 int this_scroll_margin;
12355 int dy = 0;
12356 int scroll_max;
12357 int rc;
12358 int amount_to_scroll = 0;
12359 Lisp_Object aggressive;
12360 int height;
12361 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
12362
12363 #if GLYPH_DEBUG
12364 debug_method_add (w, "try_scrolling");
12365 #endif
12366
12367 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12368
12369 /* Compute scroll margin height in pixels. We scroll when point is
12370 within this distance from the top or bottom of the window. */
12371 if (scroll_margin > 0)
12372 {
12373 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12374 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12375 }
12376 else
12377 this_scroll_margin = 0;
12378
12379 /* Force scroll_conservatively to have a reasonable value so it doesn't
12380 cause an overflow while computing how much to scroll. */
12381 if (scroll_conservatively)
12382 scroll_conservatively = min (scroll_conservatively,
12383 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
12384
12385 /* Compute how much we should try to scroll maximally to bring point
12386 into view. */
12387 if (scroll_step || scroll_conservatively || temp_scroll_step)
12388 scroll_max = max (scroll_step,
12389 max (scroll_conservatively, temp_scroll_step));
12390 else if (NUMBERP (current_buffer->scroll_down_aggressively)
12391 || NUMBERP (current_buffer->scroll_up_aggressively))
12392 /* We're trying to scroll because of aggressive scrolling
12393 but no scroll_step is set. Choose an arbitrary one. Maybe
12394 there should be a variable for this. */
12395 scroll_max = 10;
12396 else
12397 scroll_max = 0;
12398 scroll_max *= FRAME_LINE_HEIGHT (f);
12399
12400 /* Decide whether we have to scroll down. Start at the window end
12401 and move this_scroll_margin up to find the position of the scroll
12402 margin. */
12403 window_end = Fwindow_end (window, Qt);
12404
12405 too_near_end:
12406
12407 CHARPOS (scroll_margin_pos) = XINT (window_end);
12408 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
12409
12410 if (this_scroll_margin || extra_scroll_margin_lines)
12411 {
12412 start_display (&it, w, scroll_margin_pos);
12413 if (this_scroll_margin)
12414 move_it_vertically_backward (&it, this_scroll_margin);
12415 if (extra_scroll_margin_lines)
12416 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
12417 scroll_margin_pos = it.current.pos;
12418 }
12419
12420 if (PT >= CHARPOS (scroll_margin_pos))
12421 {
12422 int y0;
12423
12424 /* Point is in the scroll margin at the bottom of the window, or
12425 below. Compute a new window start that makes point visible. */
12426
12427 /* Compute the distance from the scroll margin to PT.
12428 Give up if the distance is greater than scroll_max. */
12429 start_display (&it, w, scroll_margin_pos);
12430 y0 = it.current_y;
12431 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12432 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12433
12434 /* To make point visible, we have to move the window start
12435 down so that the line the cursor is in is visible, which
12436 means we have to add in the height of the cursor line. */
12437 dy = line_bottom_y (&it) - y0;
12438
12439 if (dy > scroll_max)
12440 return SCROLLING_FAILED;
12441
12442 /* Move the window start down. If scrolling conservatively,
12443 move it just enough down to make point visible. If
12444 scroll_step is set, move it down by scroll_step. */
12445 start_display (&it, w, startp);
12446
12447 if (scroll_conservatively)
12448 /* Set AMOUNT_TO_SCROLL to at least one line,
12449 and at most scroll_conservatively lines. */
12450 amount_to_scroll
12451 = min (max (dy, FRAME_LINE_HEIGHT (f)),
12452 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
12453 else if (scroll_step || temp_scroll_step)
12454 amount_to_scroll = scroll_max;
12455 else
12456 {
12457 aggressive = current_buffer->scroll_up_aggressively;
12458 height = WINDOW_BOX_TEXT_HEIGHT (w);
12459 if (NUMBERP (aggressive))
12460 {
12461 double float_amount = XFLOATINT (aggressive) * height;
12462 amount_to_scroll = float_amount;
12463 if (amount_to_scroll == 0 && float_amount > 0)
12464 amount_to_scroll = 1;
12465 }
12466 }
12467
12468 if (amount_to_scroll <= 0)
12469 return SCROLLING_FAILED;
12470
12471 /* If moving by amount_to_scroll leaves STARTP unchanged,
12472 move it down one screen line. */
12473
12474 move_it_vertically (&it, amount_to_scroll);
12475 if (CHARPOS (it.current.pos) == CHARPOS (startp))
12476 move_it_by_lines (&it, 1, 1);
12477 startp = it.current.pos;
12478 }
12479 else
12480 {
12481 /* See if point is inside the scroll margin at the top of the
12482 window. */
12483 scroll_margin_pos = startp;
12484 if (this_scroll_margin)
12485 {
12486 start_display (&it, w, startp);
12487 move_it_vertically (&it, this_scroll_margin);
12488 scroll_margin_pos = it.current.pos;
12489 }
12490
12491 if (PT < CHARPOS (scroll_margin_pos))
12492 {
12493 /* Point is in the scroll margin at the top of the window or
12494 above what is displayed in the window. */
12495 int y0;
12496
12497 /* Compute the vertical distance from PT to the scroll
12498 margin position. Give up if distance is greater than
12499 scroll_max. */
12500 SET_TEXT_POS (pos, PT, PT_BYTE);
12501 start_display (&it, w, pos);
12502 y0 = it.current_y;
12503 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
12504 it.last_visible_y, -1,
12505 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12506 dy = it.current_y - y0;
12507 if (dy > scroll_max)
12508 return SCROLLING_FAILED;
12509
12510 /* Compute new window start. */
12511 start_display (&it, w, startp);
12512
12513 if (scroll_conservatively)
12514 amount_to_scroll
12515 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
12516 else if (scroll_step || temp_scroll_step)
12517 amount_to_scroll = scroll_max;
12518 else
12519 {
12520 aggressive = current_buffer->scroll_down_aggressively;
12521 height = WINDOW_BOX_TEXT_HEIGHT (w);
12522 if (NUMBERP (aggressive))
12523 {
12524 double float_amount = XFLOATINT (aggressive) * height;
12525 amount_to_scroll = float_amount;
12526 if (amount_to_scroll == 0 && float_amount > 0)
12527 amount_to_scroll = 1;
12528 }
12529 }
12530
12531 if (amount_to_scroll <= 0)
12532 return SCROLLING_FAILED;
12533
12534 move_it_vertically_backward (&it, amount_to_scroll);
12535 startp = it.current.pos;
12536 }
12537 }
12538
12539 /* Run window scroll functions. */
12540 startp = run_window_scroll_functions (window, startp);
12541
12542 /* Display the window. Give up if new fonts are loaded, or if point
12543 doesn't appear. */
12544 if (!try_window (window, startp, 0))
12545 rc = SCROLLING_NEED_LARGER_MATRICES;
12546 else if (w->cursor.vpos < 0)
12547 {
12548 clear_glyph_matrix (w->desired_matrix);
12549 rc = SCROLLING_FAILED;
12550 }
12551 else
12552 {
12553 /* Maybe forget recorded base line for line number display. */
12554 if (!just_this_one_p
12555 || current_buffer->clip_changed
12556 || BEG_UNCHANGED < CHARPOS (startp))
12557 w->base_line_number = Qnil;
12558
12559 /* If cursor ends up on a partially visible line,
12560 treat that as being off the bottom of the screen. */
12561 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
12562 {
12563 clear_glyph_matrix (w->desired_matrix);
12564 ++extra_scroll_margin_lines;
12565 goto too_near_end;
12566 }
12567 rc = SCROLLING_SUCCESS;
12568 }
12569
12570 return rc;
12571 }
12572
12573
12574 /* Compute a suitable window start for window W if display of W starts
12575 on a continuation line. Value is non-zero if a new window start
12576 was computed.
12577
12578 The new window start will be computed, based on W's width, starting
12579 from the start of the continued line. It is the start of the
12580 screen line with the minimum distance from the old start W->start. */
12581
12582 static int
12583 compute_window_start_on_continuation_line (w)
12584 struct window *w;
12585 {
12586 struct text_pos pos, start_pos;
12587 int window_start_changed_p = 0;
12588
12589 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
12590
12591 /* If window start is on a continuation line... Window start may be
12592 < BEGV in case there's invisible text at the start of the
12593 buffer (M-x rmail, for example). */
12594 if (CHARPOS (start_pos) > BEGV
12595 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
12596 {
12597 struct it it;
12598 struct glyph_row *row;
12599
12600 /* Handle the case that the window start is out of range. */
12601 if (CHARPOS (start_pos) < BEGV)
12602 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
12603 else if (CHARPOS (start_pos) > ZV)
12604 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
12605
12606 /* Find the start of the continued line. This should be fast
12607 because scan_buffer is fast (newline cache). */
12608 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
12609 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
12610 row, DEFAULT_FACE_ID);
12611 reseat_at_previous_visible_line_start (&it);
12612
12613 /* If the line start is "too far" away from the window start,
12614 say it takes too much time to compute a new window start. */
12615 if (CHARPOS (start_pos) - IT_CHARPOS (it)
12616 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
12617 {
12618 int min_distance, distance;
12619
12620 /* Move forward by display lines to find the new window
12621 start. If window width was enlarged, the new start can
12622 be expected to be > the old start. If window width was
12623 decreased, the new window start will be < the old start.
12624 So, we're looking for the display line start with the
12625 minimum distance from the old window start. */
12626 pos = it.current.pos;
12627 min_distance = INFINITY;
12628 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
12629 distance < min_distance)
12630 {
12631 min_distance = distance;
12632 pos = it.current.pos;
12633 move_it_by_lines (&it, 1, 0);
12634 }
12635
12636 /* Set the window start there. */
12637 SET_MARKER_FROM_TEXT_POS (w->start, pos);
12638 window_start_changed_p = 1;
12639 }
12640 }
12641
12642 return window_start_changed_p;
12643 }
12644
12645
12646 /* Try cursor movement in case text has not changed in window WINDOW,
12647 with window start STARTP. Value is
12648
12649 CURSOR_MOVEMENT_SUCCESS if successful
12650
12651 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
12652
12653 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
12654 display. *SCROLL_STEP is set to 1, under certain circumstances, if
12655 we want to scroll as if scroll-step were set to 1. See the code.
12656
12657 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
12658 which case we have to abort this redisplay, and adjust matrices
12659 first. */
12660
12661 enum
12662 {
12663 CURSOR_MOVEMENT_SUCCESS,
12664 CURSOR_MOVEMENT_CANNOT_BE_USED,
12665 CURSOR_MOVEMENT_MUST_SCROLL,
12666 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
12667 };
12668
12669 static int
12670 try_cursor_movement (window, startp, scroll_step)
12671 Lisp_Object window;
12672 struct text_pos startp;
12673 int *scroll_step;
12674 {
12675 struct window *w = XWINDOW (window);
12676 struct frame *f = XFRAME (w->frame);
12677 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
12678
12679 #if GLYPH_DEBUG
12680 if (inhibit_try_cursor_movement)
12681 return rc;
12682 #endif
12683
12684 /* Handle case where text has not changed, only point, and it has
12685 not moved off the frame. */
12686 if (/* Point may be in this window. */
12687 PT >= CHARPOS (startp)
12688 /* Selective display hasn't changed. */
12689 && !current_buffer->clip_changed
12690 /* Function force-mode-line-update is used to force a thorough
12691 redisplay. It sets either windows_or_buffers_changed or
12692 update_mode_lines. So don't take a shortcut here for these
12693 cases. */
12694 && !update_mode_lines
12695 && !windows_or_buffers_changed
12696 && !cursor_type_changed
12697 /* Can't use this case if highlighting a region. When a
12698 region exists, cursor movement has to do more than just
12699 set the cursor. */
12700 && !(!NILP (Vtransient_mark_mode)
12701 && !NILP (current_buffer->mark_active))
12702 && NILP (w->region_showing)
12703 && NILP (Vshow_trailing_whitespace)
12704 /* Right after splitting windows, last_point may be nil. */
12705 && INTEGERP (w->last_point)
12706 /* This code is not used for mini-buffer for the sake of the case
12707 of redisplaying to replace an echo area message; since in
12708 that case the mini-buffer contents per se are usually
12709 unchanged. This code is of no real use in the mini-buffer
12710 since the handling of this_line_start_pos, etc., in redisplay
12711 handles the same cases. */
12712 && !EQ (window, minibuf_window)
12713 /* When splitting windows or for new windows, it happens that
12714 redisplay is called with a nil window_end_vpos or one being
12715 larger than the window. This should really be fixed in
12716 window.c. I don't have this on my list, now, so we do
12717 approximately the same as the old redisplay code. --gerd. */
12718 && INTEGERP (w->window_end_vpos)
12719 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
12720 && (FRAME_WINDOW_P (f)
12721 || !overlay_arrow_in_current_buffer_p ()))
12722 {
12723 int this_scroll_margin, top_scroll_margin;
12724 struct glyph_row *row = NULL;
12725
12726 #if GLYPH_DEBUG
12727 debug_method_add (w, "cursor movement");
12728 #endif
12729
12730 /* Scroll if point within this distance from the top or bottom
12731 of the window. This is a pixel value. */
12732 this_scroll_margin = max (0, scroll_margin);
12733 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12734 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12735
12736 top_scroll_margin = this_scroll_margin;
12737 if (WINDOW_WANTS_HEADER_LINE_P (w))
12738 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
12739
12740 /* Start with the row the cursor was displayed during the last
12741 not paused redisplay. Give up if that row is not valid. */
12742 if (w->last_cursor.vpos < 0
12743 || w->last_cursor.vpos >= w->current_matrix->nrows)
12744 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12745 else
12746 {
12747 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
12748 if (row->mode_line_p)
12749 ++row;
12750 if (!row->enabled_p)
12751 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12752 }
12753
12754 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
12755 {
12756 int scroll_p = 0;
12757 int last_y = window_text_bottom_y (w) - this_scroll_margin;
12758
12759 if (PT > XFASTINT (w->last_point))
12760 {
12761 /* Point has moved forward. */
12762 while (MATRIX_ROW_END_CHARPOS (row) < PT
12763 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
12764 {
12765 xassert (row->enabled_p);
12766 ++row;
12767 }
12768
12769 /* The end position of a row equals the start position
12770 of the next row. If PT is there, we would rather
12771 display it in the next line. */
12772 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12773 && MATRIX_ROW_END_CHARPOS (row) == PT
12774 && !cursor_row_p (w, row))
12775 ++row;
12776
12777 /* If within the scroll margin, scroll. Note that
12778 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
12779 the next line would be drawn, and that
12780 this_scroll_margin can be zero. */
12781 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
12782 || PT > MATRIX_ROW_END_CHARPOS (row)
12783 /* Line is completely visible last line in window
12784 and PT is to be set in the next line. */
12785 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
12786 && PT == MATRIX_ROW_END_CHARPOS (row)
12787 && !row->ends_at_zv_p
12788 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12789 scroll_p = 1;
12790 }
12791 else if (PT < XFASTINT (w->last_point))
12792 {
12793 /* Cursor has to be moved backward. Note that PT >=
12794 CHARPOS (startp) because of the outer if-statement. */
12795 while (!row->mode_line_p
12796 && (MATRIX_ROW_START_CHARPOS (row) > PT
12797 || (MATRIX_ROW_START_CHARPOS (row) == PT
12798 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
12799 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
12800 row > w->current_matrix->rows
12801 && (row-1)->ends_in_newline_from_string_p))))
12802 && (row->y > top_scroll_margin
12803 || CHARPOS (startp) == BEGV))
12804 {
12805 xassert (row->enabled_p);
12806 --row;
12807 }
12808
12809 /* Consider the following case: Window starts at BEGV,
12810 there is invisible, intangible text at BEGV, so that
12811 display starts at some point START > BEGV. It can
12812 happen that we are called with PT somewhere between
12813 BEGV and START. Try to handle that case. */
12814 if (row < w->current_matrix->rows
12815 || row->mode_line_p)
12816 {
12817 row = w->current_matrix->rows;
12818 if (row->mode_line_p)
12819 ++row;
12820 }
12821
12822 /* Due to newlines in overlay strings, we may have to
12823 skip forward over overlay strings. */
12824 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12825 && MATRIX_ROW_END_CHARPOS (row) == PT
12826 && !cursor_row_p (w, row))
12827 ++row;
12828
12829 /* If within the scroll margin, scroll. */
12830 if (row->y < top_scroll_margin
12831 && CHARPOS (startp) != BEGV)
12832 scroll_p = 1;
12833 }
12834 else
12835 {
12836 /* Cursor did not move. So don't scroll even if cursor line
12837 is partially visible, as it was so before. */
12838 rc = CURSOR_MOVEMENT_SUCCESS;
12839 }
12840
12841 if (PT < MATRIX_ROW_START_CHARPOS (row)
12842 || PT > MATRIX_ROW_END_CHARPOS (row))
12843 {
12844 /* if PT is not in the glyph row, give up. */
12845 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12846 }
12847 else if (rc != CURSOR_MOVEMENT_SUCCESS
12848 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
12849 && make_cursor_line_fully_visible_p)
12850 {
12851 if (PT == MATRIX_ROW_END_CHARPOS (row)
12852 && !row->ends_at_zv_p
12853 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
12854 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12855 else if (row->height > window_box_height (w))
12856 {
12857 /* If we end up in a partially visible line, let's
12858 make it fully visible, except when it's taller
12859 than the window, in which case we can't do much
12860 about it. */
12861 *scroll_step = 1;
12862 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12863 }
12864 else
12865 {
12866 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12867 if (!cursor_row_fully_visible_p (w, 0, 1))
12868 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12869 else
12870 rc = CURSOR_MOVEMENT_SUCCESS;
12871 }
12872 }
12873 else if (scroll_p)
12874 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12875 else
12876 {
12877 do
12878 {
12879 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
12880 {
12881 rc = CURSOR_MOVEMENT_SUCCESS;
12882 break;
12883 }
12884 ++row;
12885 }
12886 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12887 && MATRIX_ROW_START_CHARPOS (row) == PT
12888 && cursor_row_p (w, row));
12889 }
12890 }
12891 }
12892
12893 return rc;
12894 }
12895
12896 void
12897 set_vertical_scroll_bar (w)
12898 struct window *w;
12899 {
12900 int start, end, whole;
12901
12902 /* Calculate the start and end positions for the current window.
12903 At some point, it would be nice to choose between scrollbars
12904 which reflect the whole buffer size, with special markers
12905 indicating narrowing, and scrollbars which reflect only the
12906 visible region.
12907
12908 Note that mini-buffers sometimes aren't displaying any text. */
12909 if (!MINI_WINDOW_P (w)
12910 || (w == XWINDOW (minibuf_window)
12911 && NILP (echo_area_buffer[0])))
12912 {
12913 struct buffer *buf = XBUFFER (w->buffer);
12914 whole = BUF_ZV (buf) - BUF_BEGV (buf);
12915 start = marker_position (w->start) - BUF_BEGV (buf);
12916 /* I don't think this is guaranteed to be right. For the
12917 moment, we'll pretend it is. */
12918 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
12919
12920 if (end < start)
12921 end = start;
12922 if (whole < (end - start))
12923 whole = end - start;
12924 }
12925 else
12926 start = end = whole = 0;
12927
12928 /* Indicate what this scroll bar ought to be displaying now. */
12929 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
12930 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
12931 (w, end - start, whole, start);
12932 }
12933
12934
12935 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
12936 selected_window is redisplayed.
12937
12938 We can return without actually redisplaying the window if
12939 fonts_changed_p is nonzero. In that case, redisplay_internal will
12940 retry. */
12941
12942 static void
12943 redisplay_window (window, just_this_one_p)
12944 Lisp_Object window;
12945 int just_this_one_p;
12946 {
12947 struct window *w = XWINDOW (window);
12948 struct frame *f = XFRAME (w->frame);
12949 struct buffer *buffer = XBUFFER (w->buffer);
12950 struct buffer *old = current_buffer;
12951 struct text_pos lpoint, opoint, startp;
12952 int update_mode_line;
12953 int tem;
12954 struct it it;
12955 /* Record it now because it's overwritten. */
12956 int current_matrix_up_to_date_p = 0;
12957 int used_current_matrix_p = 0;
12958 /* This is less strict than current_matrix_up_to_date_p.
12959 It indictes that the buffer contents and narrowing are unchanged. */
12960 int buffer_unchanged_p = 0;
12961 int temp_scroll_step = 0;
12962 int count = SPECPDL_INDEX ();
12963 int rc;
12964 int centering_position = -1;
12965 int last_line_misfit = 0;
12966 int beg_unchanged, end_unchanged;
12967
12968 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12969 opoint = lpoint;
12970
12971 /* W must be a leaf window here. */
12972 xassert (!NILP (w->buffer));
12973 #if GLYPH_DEBUG
12974 *w->desired_matrix->method = 0;
12975 #endif
12976
12977 specbind (Qinhibit_point_motion_hooks, Qt);
12978
12979 reconsider_clip_changes (w, buffer);
12980
12981 /* Has the mode line to be updated? */
12982 update_mode_line = (!NILP (w->update_mode_line)
12983 || update_mode_lines
12984 || buffer->clip_changed
12985 || buffer->prevent_redisplay_optimizations_p);
12986
12987 if (MINI_WINDOW_P (w))
12988 {
12989 if (w == XWINDOW (echo_area_window)
12990 && !NILP (echo_area_buffer[0]))
12991 {
12992 if (update_mode_line)
12993 /* We may have to update a tty frame's menu bar or a
12994 tool-bar. Example `M-x C-h C-h C-g'. */
12995 goto finish_menu_bars;
12996 else
12997 /* We've already displayed the echo area glyphs in this window. */
12998 goto finish_scroll_bars;
12999 }
13000 else if ((w != XWINDOW (minibuf_window)
13001 || minibuf_level == 0)
13002 /* When buffer is nonempty, redisplay window normally. */
13003 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13004 /* Quail displays non-mini buffers in minibuffer window.
13005 In that case, redisplay the window normally. */
13006 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13007 {
13008 /* W is a mini-buffer window, but it's not active, so clear
13009 it. */
13010 int yb = window_text_bottom_y (w);
13011 struct glyph_row *row;
13012 int y;
13013
13014 for (y = 0, row = w->desired_matrix->rows;
13015 y < yb;
13016 y += row->height, ++row)
13017 blank_row (w, row, y);
13018 goto finish_scroll_bars;
13019 }
13020
13021 clear_glyph_matrix (w->desired_matrix);
13022 }
13023
13024 /* Otherwise set up data on this window; select its buffer and point
13025 value. */
13026 /* Really select the buffer, for the sake of buffer-local
13027 variables. */
13028 set_buffer_internal_1 (XBUFFER (w->buffer));
13029 SET_TEXT_POS (opoint, PT, PT_BYTE);
13030
13031 beg_unchanged = BEG_UNCHANGED;
13032 end_unchanged = END_UNCHANGED;
13033
13034 current_matrix_up_to_date_p
13035 = (!NILP (w->window_end_valid)
13036 && !current_buffer->clip_changed
13037 && !current_buffer->prevent_redisplay_optimizations_p
13038 && XFASTINT (w->last_modified) >= MODIFF
13039 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13040
13041 buffer_unchanged_p
13042 = (!NILP (w->window_end_valid)
13043 && !current_buffer->clip_changed
13044 && XFASTINT (w->last_modified) >= MODIFF
13045 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13046
13047 /* When windows_or_buffers_changed is non-zero, we can't rely on
13048 the window end being valid, so set it to nil there. */
13049 if (windows_or_buffers_changed)
13050 {
13051 /* If window starts on a continuation line, maybe adjust the
13052 window start in case the window's width changed. */
13053 if (XMARKER (w->start)->buffer == current_buffer)
13054 compute_window_start_on_continuation_line (w);
13055
13056 w->window_end_valid = Qnil;
13057 }
13058
13059 /* Some sanity checks. */
13060 CHECK_WINDOW_END (w);
13061 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13062 abort ();
13063 if (BYTEPOS (opoint) < CHARPOS (opoint))
13064 abort ();
13065
13066 /* If %c is in mode line, update it if needed. */
13067 if (!NILP (w->column_number_displayed)
13068 /* This alternative quickly identifies a common case
13069 where no change is needed. */
13070 && !(PT == XFASTINT (w->last_point)
13071 && XFASTINT (w->last_modified) >= MODIFF
13072 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13073 && (XFASTINT (w->column_number_displayed)
13074 != (int) current_column ())) /* iftc */
13075 update_mode_line = 1;
13076
13077 /* Count number of windows showing the selected buffer. An indirect
13078 buffer counts as its base buffer. */
13079 if (!just_this_one_p)
13080 {
13081 struct buffer *current_base, *window_base;
13082 current_base = current_buffer;
13083 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13084 if (current_base->base_buffer)
13085 current_base = current_base->base_buffer;
13086 if (window_base->base_buffer)
13087 window_base = window_base->base_buffer;
13088 if (current_base == window_base)
13089 buffer_shared++;
13090 }
13091
13092 /* Point refers normally to the selected window. For any other
13093 window, set up appropriate value. */
13094 if (!EQ (window, selected_window))
13095 {
13096 int new_pt = XMARKER (w->pointm)->charpos;
13097 int new_pt_byte = marker_byte_position (w->pointm);
13098 if (new_pt < BEGV)
13099 {
13100 new_pt = BEGV;
13101 new_pt_byte = BEGV_BYTE;
13102 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13103 }
13104 else if (new_pt > (ZV - 1))
13105 {
13106 new_pt = ZV;
13107 new_pt_byte = ZV_BYTE;
13108 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
13109 }
13110
13111 /* We don't use SET_PT so that the point-motion hooks don't run. */
13112 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
13113 }
13114
13115 /* If any of the character widths specified in the display table
13116 have changed, invalidate the width run cache. It's true that
13117 this may be a bit late to catch such changes, but the rest of
13118 redisplay goes (non-fatally) haywire when the display table is
13119 changed, so why should we worry about doing any better? */
13120 if (current_buffer->width_run_cache)
13121 {
13122 struct Lisp_Char_Table *disptab = buffer_display_table ();
13123
13124 if (! disptab_matches_widthtab (disptab,
13125 XVECTOR (current_buffer->width_table)))
13126 {
13127 invalidate_region_cache (current_buffer,
13128 current_buffer->width_run_cache,
13129 BEG, Z);
13130 recompute_width_table (current_buffer, disptab);
13131 }
13132 }
13133
13134 /* If window-start is screwed up, choose a new one. */
13135 if (XMARKER (w->start)->buffer != current_buffer)
13136 goto recenter;
13137
13138 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13139
13140 /* If someone specified a new starting point but did not insist,
13141 check whether it can be used. */
13142 if (!NILP (w->optional_new_start)
13143 && CHARPOS (startp) >= BEGV
13144 && CHARPOS (startp) <= ZV)
13145 {
13146 w->optional_new_start = Qnil;
13147 start_display (&it, w, startp);
13148 move_it_to (&it, PT, 0, it.last_visible_y, -1,
13149 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13150 if (IT_CHARPOS (it) == PT)
13151 w->force_start = Qt;
13152 /* IT may overshoot PT if text at PT is invisible. */
13153 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
13154 w->force_start = Qt;
13155 }
13156
13157 force_start:
13158
13159 /* Handle case where place to start displaying has been specified,
13160 unless the specified location is outside the accessible range. */
13161 if (!NILP (w->force_start)
13162 || w->frozen_window_start_p)
13163 {
13164 /* We set this later on if we have to adjust point. */
13165 int new_vpos = -1;
13166 int val;
13167
13168 w->force_start = Qnil;
13169 w->vscroll = 0;
13170 w->window_end_valid = Qnil;
13171
13172 /* Forget any recorded base line for line number display. */
13173 if (!buffer_unchanged_p)
13174 w->base_line_number = Qnil;
13175
13176 /* Redisplay the mode line. Select the buffer properly for that.
13177 Also, run the hook window-scroll-functions
13178 because we have scrolled. */
13179 /* Note, we do this after clearing force_start because
13180 if there's an error, it is better to forget about force_start
13181 than to get into an infinite loop calling the hook functions
13182 and having them get more errors. */
13183 if (!update_mode_line
13184 || ! NILP (Vwindow_scroll_functions))
13185 {
13186 update_mode_line = 1;
13187 w->update_mode_line = Qt;
13188 startp = run_window_scroll_functions (window, startp);
13189 }
13190
13191 w->last_modified = make_number (0);
13192 w->last_overlay_modified = make_number (0);
13193 if (CHARPOS (startp) < BEGV)
13194 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
13195 else if (CHARPOS (startp) > ZV)
13196 SET_TEXT_POS (startp, ZV, ZV_BYTE);
13197
13198 /* Redisplay, then check if cursor has been set during the
13199 redisplay. Give up if new fonts were loaded. */
13200 val = try_window (window, startp, 1);
13201 if (!val)
13202 {
13203 w->force_start = Qt;
13204 clear_glyph_matrix (w->desired_matrix);
13205 goto need_larger_matrices;
13206 }
13207 /* Point was outside the scroll margins. */
13208 if (val < 0)
13209 new_vpos = window_box_height (w) / 2;
13210
13211 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
13212 {
13213 /* If point does not appear, try to move point so it does
13214 appear. The desired matrix has been built above, so we
13215 can use it here. */
13216 new_vpos = window_box_height (w) / 2;
13217 }
13218
13219 if (!cursor_row_fully_visible_p (w, 0, 0))
13220 {
13221 /* Point does appear, but on a line partly visible at end of window.
13222 Move it back to a fully-visible line. */
13223 new_vpos = window_box_height (w);
13224 }
13225
13226 /* If we need to move point for either of the above reasons,
13227 now actually do it. */
13228 if (new_vpos >= 0)
13229 {
13230 struct glyph_row *row;
13231
13232 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
13233 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
13234 ++row;
13235
13236 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
13237 MATRIX_ROW_START_BYTEPOS (row));
13238
13239 if (w != XWINDOW (selected_window))
13240 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
13241 else if (current_buffer == old)
13242 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13243
13244 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
13245
13246 /* If we are highlighting the region, then we just changed
13247 the region, so redisplay to show it. */
13248 if (!NILP (Vtransient_mark_mode)
13249 && !NILP (current_buffer->mark_active))
13250 {
13251 clear_glyph_matrix (w->desired_matrix);
13252 if (!try_window (window, startp, 0))
13253 goto need_larger_matrices;
13254 }
13255 }
13256
13257 #if GLYPH_DEBUG
13258 debug_method_add (w, "forced window start");
13259 #endif
13260 goto done;
13261 }
13262
13263 /* Handle case where text has not changed, only point, and it has
13264 not moved off the frame, and we are not retrying after hscroll.
13265 (current_matrix_up_to_date_p is nonzero when retrying.) */
13266 if (current_matrix_up_to_date_p
13267 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
13268 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
13269 {
13270 switch (rc)
13271 {
13272 case CURSOR_MOVEMENT_SUCCESS:
13273 used_current_matrix_p = 1;
13274 goto done;
13275
13276 #if 0 /* try_cursor_movement never returns this value. */
13277 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
13278 goto need_larger_matrices;
13279 #endif
13280
13281 case CURSOR_MOVEMENT_MUST_SCROLL:
13282 goto try_to_scroll;
13283
13284 default:
13285 abort ();
13286 }
13287 }
13288 /* If current starting point was originally the beginning of a line
13289 but no longer is, find a new starting point. */
13290 else if (!NILP (w->start_at_line_beg)
13291 && !(CHARPOS (startp) <= BEGV
13292 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
13293 {
13294 #if GLYPH_DEBUG
13295 debug_method_add (w, "recenter 1");
13296 #endif
13297 goto recenter;
13298 }
13299
13300 /* Try scrolling with try_window_id. Value is > 0 if update has
13301 been done, it is -1 if we know that the same window start will
13302 not work. It is 0 if unsuccessful for some other reason. */
13303 else if ((tem = try_window_id (w)) != 0)
13304 {
13305 #if GLYPH_DEBUG
13306 debug_method_add (w, "try_window_id %d", tem);
13307 #endif
13308
13309 if (fonts_changed_p)
13310 goto need_larger_matrices;
13311 if (tem > 0)
13312 goto done;
13313
13314 /* Otherwise try_window_id has returned -1 which means that we
13315 don't want the alternative below this comment to execute. */
13316 }
13317 else if (CHARPOS (startp) >= BEGV
13318 && CHARPOS (startp) <= ZV
13319 && PT >= CHARPOS (startp)
13320 && (CHARPOS (startp) < ZV
13321 /* Avoid starting at end of buffer. */
13322 || CHARPOS (startp) == BEGV
13323 || (XFASTINT (w->last_modified) >= MODIFF
13324 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
13325 {
13326
13327 /* If first window line is a continuation line, and window start
13328 is inside the modified region, but the first change is before
13329 current window start, we must select a new window start.
13330
13331 However, if this is the result of a down-mouse event (e.g. by
13332 extending the mouse-drag-overlay), we don't want to select a
13333 new window start, since that would change the position under
13334 the mouse, resulting in an unwanted mouse-movement rather
13335 than a simple mouse-click. */
13336 if (NILP (w->start_at_line_beg)
13337 && NILP (do_mouse_tracking)
13338 && CHARPOS (startp) > BEGV
13339 && CHARPOS (startp) > BEG + beg_unchanged
13340 && CHARPOS (startp) <= Z - end_unchanged)
13341 {
13342 w->force_start = Qt;
13343 if (XMARKER (w->start)->buffer == current_buffer)
13344 compute_window_start_on_continuation_line (w);
13345 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13346 goto force_start;
13347 }
13348
13349 #if GLYPH_DEBUG
13350 debug_method_add (w, "same window start");
13351 #endif
13352
13353 /* Try to redisplay starting at same place as before.
13354 If point has not moved off frame, accept the results. */
13355 if (!current_matrix_up_to_date_p
13356 /* Don't use try_window_reusing_current_matrix in this case
13357 because a window scroll function can have changed the
13358 buffer. */
13359 || !NILP (Vwindow_scroll_functions)
13360 || MINI_WINDOW_P (w)
13361 || !(used_current_matrix_p
13362 = try_window_reusing_current_matrix (w)))
13363 {
13364 IF_DEBUG (debug_method_add (w, "1"));
13365 if (try_window (window, startp, 1) < 0)
13366 /* -1 means we need to scroll.
13367 0 means we need new matrices, but fonts_changed_p
13368 is set in that case, so we will detect it below. */
13369 goto try_to_scroll;
13370 }
13371
13372 if (fonts_changed_p)
13373 goto need_larger_matrices;
13374
13375 if (w->cursor.vpos >= 0)
13376 {
13377 if (!just_this_one_p
13378 || current_buffer->clip_changed
13379 || BEG_UNCHANGED < CHARPOS (startp))
13380 /* Forget any recorded base line for line number display. */
13381 w->base_line_number = Qnil;
13382
13383 if (!cursor_row_fully_visible_p (w, 1, 0))
13384 {
13385 clear_glyph_matrix (w->desired_matrix);
13386 last_line_misfit = 1;
13387 }
13388 /* Drop through and scroll. */
13389 else
13390 goto done;
13391 }
13392 else
13393 clear_glyph_matrix (w->desired_matrix);
13394 }
13395
13396 try_to_scroll:
13397
13398 w->last_modified = make_number (0);
13399 w->last_overlay_modified = make_number (0);
13400
13401 /* Redisplay the mode line. Select the buffer properly for that. */
13402 if (!update_mode_line)
13403 {
13404 update_mode_line = 1;
13405 w->update_mode_line = Qt;
13406 }
13407
13408 /* Try to scroll by specified few lines. */
13409 if ((scroll_conservatively
13410 || scroll_step
13411 || temp_scroll_step
13412 || NUMBERP (current_buffer->scroll_up_aggressively)
13413 || NUMBERP (current_buffer->scroll_down_aggressively))
13414 && !current_buffer->clip_changed
13415 && CHARPOS (startp) >= BEGV
13416 && CHARPOS (startp) <= ZV)
13417 {
13418 /* The function returns -1 if new fonts were loaded, 1 if
13419 successful, 0 if not successful. */
13420 int rc = try_scrolling (window, just_this_one_p,
13421 scroll_conservatively,
13422 scroll_step,
13423 temp_scroll_step, last_line_misfit);
13424 switch (rc)
13425 {
13426 case SCROLLING_SUCCESS:
13427 goto done;
13428
13429 case SCROLLING_NEED_LARGER_MATRICES:
13430 goto need_larger_matrices;
13431
13432 case SCROLLING_FAILED:
13433 break;
13434
13435 default:
13436 abort ();
13437 }
13438 }
13439
13440 /* Finally, just choose place to start which centers point */
13441
13442 recenter:
13443 if (centering_position < 0)
13444 centering_position = window_box_height (w) / 2;
13445
13446 #if GLYPH_DEBUG
13447 debug_method_add (w, "recenter");
13448 #endif
13449
13450 /* w->vscroll = 0; */
13451
13452 /* Forget any previously recorded base line for line number display. */
13453 if (!buffer_unchanged_p)
13454 w->base_line_number = Qnil;
13455
13456 /* Move backward half the height of the window. */
13457 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13458 it.current_y = it.last_visible_y;
13459 move_it_vertically_backward (&it, centering_position);
13460 xassert (IT_CHARPOS (it) >= BEGV);
13461
13462 /* The function move_it_vertically_backward may move over more
13463 than the specified y-distance. If it->w is small, e.g. a
13464 mini-buffer window, we may end up in front of the window's
13465 display area. Start displaying at the start of the line
13466 containing PT in this case. */
13467 if (it.current_y <= 0)
13468 {
13469 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13470 move_it_vertically_backward (&it, 0);
13471 #if 0
13472 /* I think this assert is bogus if buffer contains
13473 invisible text or images. KFS. */
13474 xassert (IT_CHARPOS (it) <= PT);
13475 #endif
13476 it.current_y = 0;
13477 }
13478
13479 it.current_x = it.hpos = 0;
13480
13481 /* Set startp here explicitly in case that helps avoid an infinite loop
13482 in case the window-scroll-functions functions get errors. */
13483 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
13484
13485 /* Run scroll hooks. */
13486 startp = run_window_scroll_functions (window, it.current.pos);
13487
13488 /* Redisplay the window. */
13489 if (!current_matrix_up_to_date_p
13490 || windows_or_buffers_changed
13491 || cursor_type_changed
13492 /* Don't use try_window_reusing_current_matrix in this case
13493 because it can have changed the buffer. */
13494 || !NILP (Vwindow_scroll_functions)
13495 || !just_this_one_p
13496 || MINI_WINDOW_P (w)
13497 || !(used_current_matrix_p
13498 = try_window_reusing_current_matrix (w)))
13499 try_window (window, startp, 0);
13500
13501 /* If new fonts have been loaded (due to fontsets), give up. We
13502 have to start a new redisplay since we need to re-adjust glyph
13503 matrices. */
13504 if (fonts_changed_p)
13505 goto need_larger_matrices;
13506
13507 /* If cursor did not appear assume that the middle of the window is
13508 in the first line of the window. Do it again with the next line.
13509 (Imagine a window of height 100, displaying two lines of height
13510 60. Moving back 50 from it->last_visible_y will end in the first
13511 line.) */
13512 if (w->cursor.vpos < 0)
13513 {
13514 if (!NILP (w->window_end_valid)
13515 && PT >= Z - XFASTINT (w->window_end_pos))
13516 {
13517 clear_glyph_matrix (w->desired_matrix);
13518 move_it_by_lines (&it, 1, 0);
13519 try_window (window, it.current.pos, 0);
13520 }
13521 else if (PT < IT_CHARPOS (it))
13522 {
13523 clear_glyph_matrix (w->desired_matrix);
13524 move_it_by_lines (&it, -1, 0);
13525 try_window (window, it.current.pos, 0);
13526 }
13527 else
13528 {
13529 /* Not much we can do about it. */
13530 }
13531 }
13532
13533 /* Consider the following case: Window starts at BEGV, there is
13534 invisible, intangible text at BEGV, so that display starts at
13535 some point START > BEGV. It can happen that we are called with
13536 PT somewhere between BEGV and START. Try to handle that case. */
13537 if (w->cursor.vpos < 0)
13538 {
13539 struct glyph_row *row = w->current_matrix->rows;
13540 if (row->mode_line_p)
13541 ++row;
13542 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13543 }
13544
13545 if (!cursor_row_fully_visible_p (w, 0, 0))
13546 {
13547 /* If vscroll is enabled, disable it and try again. */
13548 if (w->vscroll)
13549 {
13550 w->vscroll = 0;
13551 clear_glyph_matrix (w->desired_matrix);
13552 goto recenter;
13553 }
13554
13555 /* If centering point failed to make the whole line visible,
13556 put point at the top instead. That has to make the whole line
13557 visible, if it can be done. */
13558 if (centering_position == 0)
13559 goto done;
13560
13561 clear_glyph_matrix (w->desired_matrix);
13562 centering_position = 0;
13563 goto recenter;
13564 }
13565
13566 done:
13567
13568 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13569 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
13570 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
13571 ? Qt : Qnil);
13572
13573 /* Display the mode line, if we must. */
13574 if ((update_mode_line
13575 /* If window not full width, must redo its mode line
13576 if (a) the window to its side is being redone and
13577 (b) we do a frame-based redisplay. This is a consequence
13578 of how inverted lines are drawn in frame-based redisplay. */
13579 || (!just_this_one_p
13580 && !FRAME_WINDOW_P (f)
13581 && !WINDOW_FULL_WIDTH_P (w))
13582 /* Line number to display. */
13583 || INTEGERP (w->base_line_pos)
13584 /* Column number is displayed and different from the one displayed. */
13585 || (!NILP (w->column_number_displayed)
13586 && (XFASTINT (w->column_number_displayed)
13587 != (int) current_column ()))) /* iftc */
13588 /* This means that the window has a mode line. */
13589 && (WINDOW_WANTS_MODELINE_P (w)
13590 || WINDOW_WANTS_HEADER_LINE_P (w)))
13591 {
13592 display_mode_lines (w);
13593
13594 /* If mode line height has changed, arrange for a thorough
13595 immediate redisplay using the correct mode line height. */
13596 if (WINDOW_WANTS_MODELINE_P (w)
13597 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
13598 {
13599 fonts_changed_p = 1;
13600 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
13601 = DESIRED_MODE_LINE_HEIGHT (w);
13602 }
13603
13604 /* If top line height has changed, arrange for a thorough
13605 immediate redisplay using the correct mode line height. */
13606 if (WINDOW_WANTS_HEADER_LINE_P (w)
13607 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
13608 {
13609 fonts_changed_p = 1;
13610 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
13611 = DESIRED_HEADER_LINE_HEIGHT (w);
13612 }
13613
13614 if (fonts_changed_p)
13615 goto need_larger_matrices;
13616 }
13617
13618 if (!line_number_displayed
13619 && !BUFFERP (w->base_line_pos))
13620 {
13621 w->base_line_pos = Qnil;
13622 w->base_line_number = Qnil;
13623 }
13624
13625 finish_menu_bars:
13626
13627 /* When we reach a frame's selected window, redo the frame's menu bar. */
13628 if (update_mode_line
13629 && EQ (FRAME_SELECTED_WINDOW (f), window))
13630 {
13631 int redisplay_menu_p = 0;
13632 int redisplay_tool_bar_p = 0;
13633
13634 if (FRAME_WINDOW_P (f))
13635 {
13636 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
13637 || defined (USE_GTK)
13638 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
13639 #else
13640 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13641 #endif
13642 }
13643 else
13644 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13645
13646 if (redisplay_menu_p)
13647 display_menu_bar (w);
13648
13649 #ifdef HAVE_WINDOW_SYSTEM
13650 if (FRAME_WINDOW_P (f))
13651 {
13652 #if defined (USE_GTK) || USE_MAC_TOOLBAR
13653 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
13654 #else
13655 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
13656 && (FRAME_TOOL_BAR_LINES (f) > 0
13657 || !NILP (Vauto_resize_tool_bars));
13658 #endif
13659
13660 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
13661 {
13662 extern int ignore_mouse_drag_p;
13663 ignore_mouse_drag_p = 1;
13664 }
13665 }
13666 #endif
13667 }
13668
13669 #ifdef HAVE_WINDOW_SYSTEM
13670 if (FRAME_WINDOW_P (f)
13671 && update_window_fringes (w, (just_this_one_p
13672 || (!used_current_matrix_p && !overlay_arrow_seen)
13673 || w->pseudo_window_p)))
13674 {
13675 update_begin (f);
13676 BLOCK_INPUT;
13677 if (draw_window_fringes (w, 1))
13678 x_draw_vertical_border (w);
13679 UNBLOCK_INPUT;
13680 update_end (f);
13681 }
13682 #endif /* HAVE_WINDOW_SYSTEM */
13683
13684 /* We go to this label, with fonts_changed_p nonzero,
13685 if it is necessary to try again using larger glyph matrices.
13686 We have to redeem the scroll bar even in this case,
13687 because the loop in redisplay_internal expects that. */
13688 need_larger_matrices:
13689 ;
13690 finish_scroll_bars:
13691
13692 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
13693 {
13694 /* Set the thumb's position and size. */
13695 set_vertical_scroll_bar (w);
13696
13697 /* Note that we actually used the scroll bar attached to this
13698 window, so it shouldn't be deleted at the end of redisplay. */
13699 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
13700 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
13701 }
13702
13703 /* Restore current_buffer and value of point in it. */
13704 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
13705 set_buffer_internal_1 (old);
13706 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
13707 shorter. This can be caused by log truncation in *Messages*. */
13708 if (CHARPOS (lpoint) <= ZV)
13709 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
13710
13711 unbind_to (count, Qnil);
13712 }
13713
13714
13715 /* Build the complete desired matrix of WINDOW with a window start
13716 buffer position POS.
13717
13718 Value is 1 if successful. It is zero if fonts were loaded during
13719 redisplay which makes re-adjusting glyph matrices necessary, and -1
13720 if point would appear in the scroll margins.
13721 (We check that only if CHECK_MARGINS is nonzero. */
13722
13723 int
13724 try_window (window, pos, check_margins)
13725 Lisp_Object window;
13726 struct text_pos pos;
13727 int check_margins;
13728 {
13729 struct window *w = XWINDOW (window);
13730 struct it it;
13731 struct glyph_row *last_text_row = NULL;
13732 struct frame *f = XFRAME (w->frame);
13733
13734 /* Make POS the new window start. */
13735 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
13736
13737 /* Mark cursor position as unknown. No overlay arrow seen. */
13738 w->cursor.vpos = -1;
13739 overlay_arrow_seen = 0;
13740
13741 /* Initialize iterator and info to start at POS. */
13742 start_display (&it, w, pos);
13743
13744 /* Display all lines of W. */
13745 while (it.current_y < it.last_visible_y)
13746 {
13747 if (display_line (&it))
13748 last_text_row = it.glyph_row - 1;
13749 if (fonts_changed_p)
13750 return 0;
13751 }
13752
13753 /* Don't let the cursor end in the scroll margins. */
13754 if (check_margins
13755 && !MINI_WINDOW_P (w))
13756 {
13757 int this_scroll_margin;
13758
13759 this_scroll_margin = max (0, scroll_margin);
13760 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13761 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13762
13763 if ((w->cursor.y >= 0 /* not vscrolled */
13764 && w->cursor.y < this_scroll_margin
13765 && CHARPOS (pos) > BEGV
13766 && IT_CHARPOS (it) < ZV)
13767 /* rms: considering make_cursor_line_fully_visible_p here
13768 seems to give wrong results. We don't want to recenter
13769 when the last line is partly visible, we want to allow
13770 that case to be handled in the usual way. */
13771 || (w->cursor.y + 1) > it.last_visible_y)
13772 {
13773 w->cursor.vpos = -1;
13774 clear_glyph_matrix (w->desired_matrix);
13775 return -1;
13776 }
13777 }
13778
13779 /* If bottom moved off end of frame, change mode line percentage. */
13780 if (XFASTINT (w->window_end_pos) <= 0
13781 && Z != IT_CHARPOS (it))
13782 w->update_mode_line = Qt;
13783
13784 /* Set window_end_pos to the offset of the last character displayed
13785 on the window from the end of current_buffer. Set
13786 window_end_vpos to its row number. */
13787 if (last_text_row)
13788 {
13789 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
13790 w->window_end_bytepos
13791 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13792 w->window_end_pos
13793 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13794 w->window_end_vpos
13795 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13796 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
13797 ->displays_text_p);
13798 }
13799 else
13800 {
13801 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13802 w->window_end_pos = make_number (Z - ZV);
13803 w->window_end_vpos = make_number (0);
13804 }
13805
13806 /* But that is not valid info until redisplay finishes. */
13807 w->window_end_valid = Qnil;
13808 return 1;
13809 }
13810
13811
13812 \f
13813 /************************************************************************
13814 Window redisplay reusing current matrix when buffer has not changed
13815 ************************************************************************/
13816
13817 /* Try redisplay of window W showing an unchanged buffer with a
13818 different window start than the last time it was displayed by
13819 reusing its current matrix. Value is non-zero if successful.
13820 W->start is the new window start. */
13821
13822 static int
13823 try_window_reusing_current_matrix (w)
13824 struct window *w;
13825 {
13826 struct frame *f = XFRAME (w->frame);
13827 struct glyph_row *row, *bottom_row;
13828 struct it it;
13829 struct run run;
13830 struct text_pos start, new_start;
13831 int nrows_scrolled, i;
13832 struct glyph_row *last_text_row;
13833 struct glyph_row *last_reused_text_row;
13834 struct glyph_row *start_row;
13835 int start_vpos, min_y, max_y;
13836
13837 #if GLYPH_DEBUG
13838 if (inhibit_try_window_reusing)
13839 return 0;
13840 #endif
13841
13842 if (/* This function doesn't handle terminal frames. */
13843 !FRAME_WINDOW_P (f)
13844 /* Don't try to reuse the display if windows have been split
13845 or such. */
13846 || windows_or_buffers_changed
13847 || cursor_type_changed)
13848 return 0;
13849
13850 /* Can't do this if region may have changed. */
13851 if ((!NILP (Vtransient_mark_mode)
13852 && !NILP (current_buffer->mark_active))
13853 || !NILP (w->region_showing)
13854 || !NILP (Vshow_trailing_whitespace))
13855 return 0;
13856
13857 /* If top-line visibility has changed, give up. */
13858 if (WINDOW_WANTS_HEADER_LINE_P (w)
13859 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
13860 return 0;
13861
13862 /* Give up if old or new display is scrolled vertically. We could
13863 make this function handle this, but right now it doesn't. */
13864 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13865 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
13866 return 0;
13867
13868 /* The variable new_start now holds the new window start. The old
13869 start `start' can be determined from the current matrix. */
13870 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
13871 start = start_row->start.pos;
13872 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13873
13874 /* Clear the desired matrix for the display below. */
13875 clear_glyph_matrix (w->desired_matrix);
13876
13877 if (CHARPOS (new_start) <= CHARPOS (start))
13878 {
13879 int first_row_y;
13880
13881 /* Don't use this method if the display starts with an ellipsis
13882 displayed for invisible text. It's not easy to handle that case
13883 below, and it's certainly not worth the effort since this is
13884 not a frequent case. */
13885 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
13886 return 0;
13887
13888 IF_DEBUG (debug_method_add (w, "twu1"));
13889
13890 /* Display up to a row that can be reused. The variable
13891 last_text_row is set to the last row displayed that displays
13892 text. Note that it.vpos == 0 if or if not there is a
13893 header-line; it's not the same as the MATRIX_ROW_VPOS! */
13894 start_display (&it, w, new_start);
13895 first_row_y = it.current_y;
13896 w->cursor.vpos = -1;
13897 last_text_row = last_reused_text_row = NULL;
13898
13899 while (it.current_y < it.last_visible_y
13900 && !fonts_changed_p)
13901 {
13902 /* If we have reached into the characters in the START row,
13903 that means the line boundaries have changed. So we
13904 can't start copying with the row START. Maybe it will
13905 work to start copying with the following row. */
13906 while (IT_CHARPOS (it) > CHARPOS (start))
13907 {
13908 /* Advance to the next row as the "start". */
13909 start_row++;
13910 start = start_row->start.pos;
13911 /* If there are no more rows to try, or just one, give up. */
13912 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
13913 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
13914 || CHARPOS (start) == ZV)
13915 {
13916 clear_glyph_matrix (w->desired_matrix);
13917 return 0;
13918 }
13919
13920 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13921 }
13922 /* If we have reached alignment,
13923 we can copy the rest of the rows. */
13924 if (IT_CHARPOS (it) == CHARPOS (start))
13925 break;
13926
13927 if (display_line (&it))
13928 last_text_row = it.glyph_row - 1;
13929 }
13930
13931 /* A value of current_y < last_visible_y means that we stopped
13932 at the previous window start, which in turn means that we
13933 have at least one reusable row. */
13934 if (it.current_y < it.last_visible_y)
13935 {
13936 /* IT.vpos always starts from 0; it counts text lines. */
13937 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
13938
13939 /* Find PT if not already found in the lines displayed. */
13940 if (w->cursor.vpos < 0)
13941 {
13942 int dy = it.current_y - start_row->y;
13943
13944 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13945 row = row_containing_pos (w, PT, row, NULL, dy);
13946 if (row)
13947 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
13948 dy, nrows_scrolled);
13949 else
13950 {
13951 clear_glyph_matrix (w->desired_matrix);
13952 return 0;
13953 }
13954 }
13955
13956 /* Scroll the display. Do it before the current matrix is
13957 changed. The problem here is that update has not yet
13958 run, i.e. part of the current matrix is not up to date.
13959 scroll_run_hook will clear the cursor, and use the
13960 current matrix to get the height of the row the cursor is
13961 in. */
13962 run.current_y = start_row->y;
13963 run.desired_y = it.current_y;
13964 run.height = it.last_visible_y - it.current_y;
13965
13966 if (run.height > 0 && run.current_y != run.desired_y)
13967 {
13968 update_begin (f);
13969 FRAME_RIF (f)->update_window_begin_hook (w);
13970 FRAME_RIF (f)->clear_window_mouse_face (w);
13971 FRAME_RIF (f)->scroll_run_hook (w, &run);
13972 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
13973 update_end (f);
13974 }
13975
13976 /* Shift current matrix down by nrows_scrolled lines. */
13977 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13978 rotate_matrix (w->current_matrix,
13979 start_vpos,
13980 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13981 nrows_scrolled);
13982
13983 /* Disable lines that must be updated. */
13984 for (i = 0; i < nrows_scrolled; ++i)
13985 (start_row + i)->enabled_p = 0;
13986
13987 /* Re-compute Y positions. */
13988 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13989 max_y = it.last_visible_y;
13990 for (row = start_row + nrows_scrolled;
13991 row < bottom_row;
13992 ++row)
13993 {
13994 row->y = it.current_y;
13995 row->visible_height = row->height;
13996
13997 if (row->y < min_y)
13998 row->visible_height -= min_y - row->y;
13999 if (row->y + row->height > max_y)
14000 row->visible_height -= row->y + row->height - max_y;
14001 row->redraw_fringe_bitmaps_p = 1;
14002
14003 it.current_y += row->height;
14004
14005 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14006 last_reused_text_row = row;
14007 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14008 break;
14009 }
14010
14011 /* Disable lines in the current matrix which are now
14012 below the window. */
14013 for (++row; row < bottom_row; ++row)
14014 row->enabled_p = row->mode_line_p = 0;
14015 }
14016
14017 /* Update window_end_pos etc.; last_reused_text_row is the last
14018 reused row from the current matrix containing text, if any.
14019 The value of last_text_row is the last displayed line
14020 containing text. */
14021 if (last_reused_text_row)
14022 {
14023 w->window_end_bytepos
14024 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14025 w->window_end_pos
14026 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14027 w->window_end_vpos
14028 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14029 w->current_matrix));
14030 }
14031 else if (last_text_row)
14032 {
14033 w->window_end_bytepos
14034 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14035 w->window_end_pos
14036 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14037 w->window_end_vpos
14038 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14039 }
14040 else
14041 {
14042 /* This window must be completely empty. */
14043 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14044 w->window_end_pos = make_number (Z - ZV);
14045 w->window_end_vpos = make_number (0);
14046 }
14047 w->window_end_valid = Qnil;
14048
14049 /* Update hint: don't try scrolling again in update_window. */
14050 w->desired_matrix->no_scrolling_p = 1;
14051
14052 #if GLYPH_DEBUG
14053 debug_method_add (w, "try_window_reusing_current_matrix 1");
14054 #endif
14055 return 1;
14056 }
14057 else if (CHARPOS (new_start) > CHARPOS (start))
14058 {
14059 struct glyph_row *pt_row, *row;
14060 struct glyph_row *first_reusable_row;
14061 struct glyph_row *first_row_to_display;
14062 int dy;
14063 int yb = window_text_bottom_y (w);
14064
14065 /* Find the row starting at new_start, if there is one. Don't
14066 reuse a partially visible line at the end. */
14067 first_reusable_row = start_row;
14068 while (first_reusable_row->enabled_p
14069 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
14070 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14071 < CHARPOS (new_start)))
14072 ++first_reusable_row;
14073
14074 /* Give up if there is no row to reuse. */
14075 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
14076 || !first_reusable_row->enabled_p
14077 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14078 != CHARPOS (new_start)))
14079 return 0;
14080
14081 /* We can reuse fully visible rows beginning with
14082 first_reusable_row to the end of the window. Set
14083 first_row_to_display to the first row that cannot be reused.
14084 Set pt_row to the row containing point, if there is any. */
14085 pt_row = NULL;
14086 for (first_row_to_display = first_reusable_row;
14087 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
14088 ++first_row_to_display)
14089 {
14090 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
14091 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
14092 pt_row = first_row_to_display;
14093 }
14094
14095 /* Start displaying at the start of first_row_to_display. */
14096 xassert (first_row_to_display->y < yb);
14097 init_to_row_start (&it, w, first_row_to_display);
14098
14099 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
14100 - start_vpos);
14101 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
14102 - nrows_scrolled);
14103 it.current_y = (first_row_to_display->y - first_reusable_row->y
14104 + WINDOW_HEADER_LINE_HEIGHT (w));
14105
14106 /* Display lines beginning with first_row_to_display in the
14107 desired matrix. Set last_text_row to the last row displayed
14108 that displays text. */
14109 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
14110 if (pt_row == NULL)
14111 w->cursor.vpos = -1;
14112 last_text_row = NULL;
14113 while (it.current_y < it.last_visible_y && !fonts_changed_p)
14114 if (display_line (&it))
14115 last_text_row = it.glyph_row - 1;
14116
14117 /* Give up If point isn't in a row displayed or reused. */
14118 if (w->cursor.vpos < 0)
14119 {
14120 clear_glyph_matrix (w->desired_matrix);
14121 return 0;
14122 }
14123
14124 /* If point is in a reused row, adjust y and vpos of the cursor
14125 position. */
14126 if (pt_row)
14127 {
14128 w->cursor.vpos -= nrows_scrolled;
14129 w->cursor.y -= first_reusable_row->y - start_row->y;
14130 }
14131
14132 /* Scroll the display. */
14133 run.current_y = first_reusable_row->y;
14134 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
14135 run.height = it.last_visible_y - run.current_y;
14136 dy = run.current_y - run.desired_y;
14137
14138 if (run.height)
14139 {
14140 update_begin (f);
14141 FRAME_RIF (f)->update_window_begin_hook (w);
14142 FRAME_RIF (f)->clear_window_mouse_face (w);
14143 FRAME_RIF (f)->scroll_run_hook (w, &run);
14144 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14145 update_end (f);
14146 }
14147
14148 /* Adjust Y positions of reused rows. */
14149 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14150 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14151 max_y = it.last_visible_y;
14152 for (row = first_reusable_row; row < first_row_to_display; ++row)
14153 {
14154 row->y -= dy;
14155 row->visible_height = row->height;
14156 if (row->y < min_y)
14157 row->visible_height -= min_y - row->y;
14158 if (row->y + row->height > max_y)
14159 row->visible_height -= row->y + row->height - max_y;
14160 row->redraw_fringe_bitmaps_p = 1;
14161 }
14162
14163 /* Scroll the current matrix. */
14164 xassert (nrows_scrolled > 0);
14165 rotate_matrix (w->current_matrix,
14166 start_vpos,
14167 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14168 -nrows_scrolled);
14169
14170 /* Disable rows not reused. */
14171 for (row -= nrows_scrolled; row < bottom_row; ++row)
14172 row->enabled_p = 0;
14173
14174 /* Point may have moved to a different line, so we cannot assume that
14175 the previous cursor position is valid; locate the correct row. */
14176 if (pt_row)
14177 {
14178 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
14179 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
14180 row++)
14181 {
14182 w->cursor.vpos++;
14183 w->cursor.y = row->y;
14184 }
14185 if (row < bottom_row)
14186 {
14187 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
14188 while (glyph->charpos < PT)
14189 {
14190 w->cursor.hpos++;
14191 w->cursor.x += glyph->pixel_width;
14192 glyph++;
14193 }
14194 }
14195 }
14196
14197 /* Adjust window end. A null value of last_text_row means that
14198 the window end is in reused rows which in turn means that
14199 only its vpos can have changed. */
14200 if (last_text_row)
14201 {
14202 w->window_end_bytepos
14203 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14204 w->window_end_pos
14205 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14206 w->window_end_vpos
14207 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14208 }
14209 else
14210 {
14211 w->window_end_vpos
14212 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
14213 }
14214
14215 w->window_end_valid = Qnil;
14216 w->desired_matrix->no_scrolling_p = 1;
14217
14218 #if GLYPH_DEBUG
14219 debug_method_add (w, "try_window_reusing_current_matrix 2");
14220 #endif
14221 return 1;
14222 }
14223
14224 return 0;
14225 }
14226
14227
14228 \f
14229 /************************************************************************
14230 Window redisplay reusing current matrix when buffer has changed
14231 ************************************************************************/
14232
14233 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
14234 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
14235 int *, int *));
14236 static struct glyph_row *
14237 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
14238 struct glyph_row *));
14239
14240
14241 /* Return the last row in MATRIX displaying text. If row START is
14242 non-null, start searching with that row. IT gives the dimensions
14243 of the display. Value is null if matrix is empty; otherwise it is
14244 a pointer to the row found. */
14245
14246 static struct glyph_row *
14247 find_last_row_displaying_text (matrix, it, start)
14248 struct glyph_matrix *matrix;
14249 struct it *it;
14250 struct glyph_row *start;
14251 {
14252 struct glyph_row *row, *row_found;
14253
14254 /* Set row_found to the last row in IT->w's current matrix
14255 displaying text. The loop looks funny but think of partially
14256 visible lines. */
14257 row_found = NULL;
14258 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
14259 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14260 {
14261 xassert (row->enabled_p);
14262 row_found = row;
14263 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
14264 break;
14265 ++row;
14266 }
14267
14268 return row_found;
14269 }
14270
14271
14272 /* Return the last row in the current matrix of W that is not affected
14273 by changes at the start of current_buffer that occurred since W's
14274 current matrix was built. Value is null if no such row exists.
14275
14276 BEG_UNCHANGED us the number of characters unchanged at the start of
14277 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
14278 first changed character in current_buffer. Characters at positions <
14279 BEG + BEG_UNCHANGED are at the same buffer positions as they were
14280 when the current matrix was built. */
14281
14282 static struct glyph_row *
14283 find_last_unchanged_at_beg_row (w)
14284 struct window *w;
14285 {
14286 int first_changed_pos = BEG + BEG_UNCHANGED;
14287 struct glyph_row *row;
14288 struct glyph_row *row_found = NULL;
14289 int yb = window_text_bottom_y (w);
14290
14291 /* Find the last row displaying unchanged text. */
14292 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14293 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14294 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
14295 {
14296 if (/* If row ends before first_changed_pos, it is unchanged,
14297 except in some case. */
14298 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
14299 /* When row ends in ZV and we write at ZV it is not
14300 unchanged. */
14301 && !row->ends_at_zv_p
14302 /* When first_changed_pos is the end of a continued line,
14303 row is not unchanged because it may be no longer
14304 continued. */
14305 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
14306 && (row->continued_p
14307 || row->exact_window_width_line_p)))
14308 row_found = row;
14309
14310 /* Stop if last visible row. */
14311 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
14312 break;
14313
14314 ++row;
14315 }
14316
14317 return row_found;
14318 }
14319
14320
14321 /* Find the first glyph row in the current matrix of W that is not
14322 affected by changes at the end of current_buffer since the
14323 time W's current matrix was built.
14324
14325 Return in *DELTA the number of chars by which buffer positions in
14326 unchanged text at the end of current_buffer must be adjusted.
14327
14328 Return in *DELTA_BYTES the corresponding number of bytes.
14329
14330 Value is null if no such row exists, i.e. all rows are affected by
14331 changes. */
14332
14333 static struct glyph_row *
14334 find_first_unchanged_at_end_row (w, delta, delta_bytes)
14335 struct window *w;
14336 int *delta, *delta_bytes;
14337 {
14338 struct glyph_row *row;
14339 struct glyph_row *row_found = NULL;
14340
14341 *delta = *delta_bytes = 0;
14342
14343 /* Display must not have been paused, otherwise the current matrix
14344 is not up to date. */
14345 if (NILP (w->window_end_valid))
14346 abort ();
14347
14348 /* A value of window_end_pos >= END_UNCHANGED means that the window
14349 end is in the range of changed text. If so, there is no
14350 unchanged row at the end of W's current matrix. */
14351 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
14352 return NULL;
14353
14354 /* Set row to the last row in W's current matrix displaying text. */
14355 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14356
14357 /* If matrix is entirely empty, no unchanged row exists. */
14358 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14359 {
14360 /* The value of row is the last glyph row in the matrix having a
14361 meaningful buffer position in it. The end position of row
14362 corresponds to window_end_pos. This allows us to translate
14363 buffer positions in the current matrix to current buffer
14364 positions for characters not in changed text. */
14365 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14366 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14367 int last_unchanged_pos, last_unchanged_pos_old;
14368 struct glyph_row *first_text_row
14369 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14370
14371 *delta = Z - Z_old;
14372 *delta_bytes = Z_BYTE - Z_BYTE_old;
14373
14374 /* Set last_unchanged_pos to the buffer position of the last
14375 character in the buffer that has not been changed. Z is the
14376 index + 1 of the last character in current_buffer, i.e. by
14377 subtracting END_UNCHANGED we get the index of the last
14378 unchanged character, and we have to add BEG to get its buffer
14379 position. */
14380 last_unchanged_pos = Z - END_UNCHANGED + BEG;
14381 last_unchanged_pos_old = last_unchanged_pos - *delta;
14382
14383 /* Search backward from ROW for a row displaying a line that
14384 starts at a minimum position >= last_unchanged_pos_old. */
14385 for (; row > first_text_row; --row)
14386 {
14387 /* This used to abort, but it can happen.
14388 It is ok to just stop the search instead here. KFS. */
14389 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
14390 break;
14391
14392 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
14393 row_found = row;
14394 }
14395 }
14396
14397 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
14398 abort ();
14399
14400 return row_found;
14401 }
14402
14403
14404 /* Make sure that glyph rows in the current matrix of window W
14405 reference the same glyph memory as corresponding rows in the
14406 frame's frame matrix. This function is called after scrolling W's
14407 current matrix on a terminal frame in try_window_id and
14408 try_window_reusing_current_matrix. */
14409
14410 static void
14411 sync_frame_with_window_matrix_rows (w)
14412 struct window *w;
14413 {
14414 struct frame *f = XFRAME (w->frame);
14415 struct glyph_row *window_row, *window_row_end, *frame_row;
14416
14417 /* Preconditions: W must be a leaf window and full-width. Its frame
14418 must have a frame matrix. */
14419 xassert (NILP (w->hchild) && NILP (w->vchild));
14420 xassert (WINDOW_FULL_WIDTH_P (w));
14421 xassert (!FRAME_WINDOW_P (f));
14422
14423 /* If W is a full-width window, glyph pointers in W's current matrix
14424 have, by definition, to be the same as glyph pointers in the
14425 corresponding frame matrix. Note that frame matrices have no
14426 marginal areas (see build_frame_matrix). */
14427 window_row = w->current_matrix->rows;
14428 window_row_end = window_row + w->current_matrix->nrows;
14429 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
14430 while (window_row < window_row_end)
14431 {
14432 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
14433 struct glyph *end = window_row->glyphs[LAST_AREA];
14434
14435 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
14436 frame_row->glyphs[TEXT_AREA] = start;
14437 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
14438 frame_row->glyphs[LAST_AREA] = end;
14439
14440 /* Disable frame rows whose corresponding window rows have
14441 been disabled in try_window_id. */
14442 if (!window_row->enabled_p)
14443 frame_row->enabled_p = 0;
14444
14445 ++window_row, ++frame_row;
14446 }
14447 }
14448
14449
14450 /* Find the glyph row in window W containing CHARPOS. Consider all
14451 rows between START and END (not inclusive). END null means search
14452 all rows to the end of the display area of W. Value is the row
14453 containing CHARPOS or null. */
14454
14455 struct glyph_row *
14456 row_containing_pos (w, charpos, start, end, dy)
14457 struct window *w;
14458 int charpos;
14459 struct glyph_row *start, *end;
14460 int dy;
14461 {
14462 struct glyph_row *row = start;
14463 int last_y;
14464
14465 /* If we happen to start on a header-line, skip that. */
14466 if (row->mode_line_p)
14467 ++row;
14468
14469 if ((end && row >= end) || !row->enabled_p)
14470 return NULL;
14471
14472 last_y = window_text_bottom_y (w) - dy;
14473
14474 while (1)
14475 {
14476 /* Give up if we have gone too far. */
14477 if (end && row >= end)
14478 return NULL;
14479 /* This formerly returned if they were equal.
14480 I think that both quantities are of a "last plus one" type;
14481 if so, when they are equal, the row is within the screen. -- rms. */
14482 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
14483 return NULL;
14484
14485 /* If it is in this row, return this row. */
14486 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
14487 || (MATRIX_ROW_END_CHARPOS (row) == charpos
14488 /* The end position of a row equals the start
14489 position of the next row. If CHARPOS is there, we
14490 would rather display it in the next line, except
14491 when this line ends in ZV. */
14492 && !row->ends_at_zv_p
14493 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14494 && charpos >= MATRIX_ROW_START_CHARPOS (row))
14495 return row;
14496 ++row;
14497 }
14498 }
14499
14500
14501 /* Try to redisplay window W by reusing its existing display. W's
14502 current matrix must be up to date when this function is called,
14503 i.e. window_end_valid must not be nil.
14504
14505 Value is
14506
14507 1 if display has been updated
14508 0 if otherwise unsuccessful
14509 -1 if redisplay with same window start is known not to succeed
14510
14511 The following steps are performed:
14512
14513 1. Find the last row in the current matrix of W that is not
14514 affected by changes at the start of current_buffer. If no such row
14515 is found, give up.
14516
14517 2. Find the first row in W's current matrix that is not affected by
14518 changes at the end of current_buffer. Maybe there is no such row.
14519
14520 3. Display lines beginning with the row + 1 found in step 1 to the
14521 row found in step 2 or, if step 2 didn't find a row, to the end of
14522 the window.
14523
14524 4. If cursor is not known to appear on the window, give up.
14525
14526 5. If display stopped at the row found in step 2, scroll the
14527 display and current matrix as needed.
14528
14529 6. Maybe display some lines at the end of W, if we must. This can
14530 happen under various circumstances, like a partially visible line
14531 becoming fully visible, or because newly displayed lines are displayed
14532 in smaller font sizes.
14533
14534 7. Update W's window end information. */
14535
14536 static int
14537 try_window_id (w)
14538 struct window *w;
14539 {
14540 struct frame *f = XFRAME (w->frame);
14541 struct glyph_matrix *current_matrix = w->current_matrix;
14542 struct glyph_matrix *desired_matrix = w->desired_matrix;
14543 struct glyph_row *last_unchanged_at_beg_row;
14544 struct glyph_row *first_unchanged_at_end_row;
14545 struct glyph_row *row;
14546 struct glyph_row *bottom_row;
14547 int bottom_vpos;
14548 struct it it;
14549 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
14550 struct text_pos start_pos;
14551 struct run run;
14552 int first_unchanged_at_end_vpos = 0;
14553 struct glyph_row *last_text_row, *last_text_row_at_end;
14554 struct text_pos start;
14555 int first_changed_charpos, last_changed_charpos;
14556
14557 #if GLYPH_DEBUG
14558 if (inhibit_try_window_id)
14559 return 0;
14560 #endif
14561
14562 /* This is handy for debugging. */
14563 #if 0
14564 #define GIVE_UP(X) \
14565 do { \
14566 fprintf (stderr, "try_window_id give up %d\n", (X)); \
14567 return 0; \
14568 } while (0)
14569 #else
14570 #define GIVE_UP(X) return 0
14571 #endif
14572
14573 SET_TEXT_POS_FROM_MARKER (start, w->start);
14574
14575 /* Don't use this for mini-windows because these can show
14576 messages and mini-buffers, and we don't handle that here. */
14577 if (MINI_WINDOW_P (w))
14578 GIVE_UP (1);
14579
14580 /* This flag is used to prevent redisplay optimizations. */
14581 if (windows_or_buffers_changed || cursor_type_changed)
14582 GIVE_UP (2);
14583
14584 /* Verify that narrowing has not changed.
14585 Also verify that we were not told to prevent redisplay optimizations.
14586 It would be nice to further
14587 reduce the number of cases where this prevents try_window_id. */
14588 if (current_buffer->clip_changed
14589 || current_buffer->prevent_redisplay_optimizations_p)
14590 GIVE_UP (3);
14591
14592 /* Window must either use window-based redisplay or be full width. */
14593 if (!FRAME_WINDOW_P (f)
14594 && (!FRAME_LINE_INS_DEL_OK (f)
14595 || !WINDOW_FULL_WIDTH_P (w)))
14596 GIVE_UP (4);
14597
14598 /* Give up if point is not known NOT to appear in W. */
14599 if (PT < CHARPOS (start))
14600 GIVE_UP (5);
14601
14602 /* Another way to prevent redisplay optimizations. */
14603 if (XFASTINT (w->last_modified) == 0)
14604 GIVE_UP (6);
14605
14606 /* Verify that window is not hscrolled. */
14607 if (XFASTINT (w->hscroll) != 0)
14608 GIVE_UP (7);
14609
14610 /* Verify that display wasn't paused. */
14611 if (NILP (w->window_end_valid))
14612 GIVE_UP (8);
14613
14614 /* Can't use this if highlighting a region because a cursor movement
14615 will do more than just set the cursor. */
14616 if (!NILP (Vtransient_mark_mode)
14617 && !NILP (current_buffer->mark_active))
14618 GIVE_UP (9);
14619
14620 /* Likewise if highlighting trailing whitespace. */
14621 if (!NILP (Vshow_trailing_whitespace))
14622 GIVE_UP (11);
14623
14624 /* Likewise if showing a region. */
14625 if (!NILP (w->region_showing))
14626 GIVE_UP (10);
14627
14628 /* Can use this if overlay arrow position and or string have changed. */
14629 if (overlay_arrows_changed_p ())
14630 GIVE_UP (12);
14631
14632
14633 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
14634 only if buffer has really changed. The reason is that the gap is
14635 initially at Z for freshly visited files. The code below would
14636 set end_unchanged to 0 in that case. */
14637 if (MODIFF > SAVE_MODIFF
14638 /* This seems to happen sometimes after saving a buffer. */
14639 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
14640 {
14641 if (GPT - BEG < BEG_UNCHANGED)
14642 BEG_UNCHANGED = GPT - BEG;
14643 if (Z - GPT < END_UNCHANGED)
14644 END_UNCHANGED = Z - GPT;
14645 }
14646
14647 /* The position of the first and last character that has been changed. */
14648 first_changed_charpos = BEG + BEG_UNCHANGED;
14649 last_changed_charpos = Z - END_UNCHANGED;
14650
14651 /* If window starts after a line end, and the last change is in
14652 front of that newline, then changes don't affect the display.
14653 This case happens with stealth-fontification. Note that although
14654 the display is unchanged, glyph positions in the matrix have to
14655 be adjusted, of course. */
14656 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14657 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14658 && ((last_changed_charpos < CHARPOS (start)
14659 && CHARPOS (start) == BEGV)
14660 || (last_changed_charpos < CHARPOS (start) - 1
14661 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
14662 {
14663 int Z_old, delta, Z_BYTE_old, delta_bytes;
14664 struct glyph_row *r0;
14665
14666 /* Compute how many chars/bytes have been added to or removed
14667 from the buffer. */
14668 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14669 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14670 delta = Z - Z_old;
14671 delta_bytes = Z_BYTE - Z_BYTE_old;
14672
14673 /* Give up if PT is not in the window. Note that it already has
14674 been checked at the start of try_window_id that PT is not in
14675 front of the window start. */
14676 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
14677 GIVE_UP (13);
14678
14679 /* If window start is unchanged, we can reuse the whole matrix
14680 as is, after adjusting glyph positions. No need to compute
14681 the window end again, since its offset from Z hasn't changed. */
14682 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14683 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
14684 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
14685 /* PT must not be in a partially visible line. */
14686 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
14687 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14688 {
14689 /* Adjust positions in the glyph matrix. */
14690 if (delta || delta_bytes)
14691 {
14692 struct glyph_row *r1
14693 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14694 increment_matrix_positions (w->current_matrix,
14695 MATRIX_ROW_VPOS (r0, current_matrix),
14696 MATRIX_ROW_VPOS (r1, current_matrix),
14697 delta, delta_bytes);
14698 }
14699
14700 /* Set the cursor. */
14701 row = row_containing_pos (w, PT, r0, NULL, 0);
14702 if (row)
14703 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14704 else
14705 abort ();
14706 return 1;
14707 }
14708 }
14709
14710 /* Handle the case that changes are all below what is displayed in
14711 the window, and that PT is in the window. This shortcut cannot
14712 be taken if ZV is visible in the window, and text has been added
14713 there that is visible in the window. */
14714 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
14715 /* ZV is not visible in the window, or there are no
14716 changes at ZV, actually. */
14717 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
14718 || first_changed_charpos == last_changed_charpos))
14719 {
14720 struct glyph_row *r0;
14721
14722 /* Give up if PT is not in the window. Note that it already has
14723 been checked at the start of try_window_id that PT is not in
14724 front of the window start. */
14725 if (PT >= MATRIX_ROW_END_CHARPOS (row))
14726 GIVE_UP (14);
14727
14728 /* If window start is unchanged, we can reuse the whole matrix
14729 as is, without changing glyph positions since no text has
14730 been added/removed in front of the window end. */
14731 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14732 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
14733 /* PT must not be in a partially visible line. */
14734 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
14735 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14736 {
14737 /* We have to compute the window end anew since text
14738 can have been added/removed after it. */
14739 w->window_end_pos
14740 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14741 w->window_end_bytepos
14742 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14743
14744 /* Set the cursor. */
14745 row = row_containing_pos (w, PT, r0, NULL, 0);
14746 if (row)
14747 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14748 else
14749 abort ();
14750 return 2;
14751 }
14752 }
14753
14754 /* Give up if window start is in the changed area.
14755
14756 The condition used to read
14757
14758 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
14759
14760 but why that was tested escapes me at the moment. */
14761 if (CHARPOS (start) >= first_changed_charpos
14762 && CHARPOS (start) <= last_changed_charpos)
14763 GIVE_UP (15);
14764
14765 /* Check that window start agrees with the start of the first glyph
14766 row in its current matrix. Check this after we know the window
14767 start is not in changed text, otherwise positions would not be
14768 comparable. */
14769 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
14770 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
14771 GIVE_UP (16);
14772
14773 /* Give up if the window ends in strings. Overlay strings
14774 at the end are difficult to handle, so don't try. */
14775 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
14776 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
14777 GIVE_UP (20);
14778
14779 /* Compute the position at which we have to start displaying new
14780 lines. Some of the lines at the top of the window might be
14781 reusable because they are not displaying changed text. Find the
14782 last row in W's current matrix not affected by changes at the
14783 start of current_buffer. Value is null if changes start in the
14784 first line of window. */
14785 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
14786 if (last_unchanged_at_beg_row)
14787 {
14788 /* Avoid starting to display in the moddle of a character, a TAB
14789 for instance. This is easier than to set up the iterator
14790 exactly, and it's not a frequent case, so the additional
14791 effort wouldn't really pay off. */
14792 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
14793 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
14794 && last_unchanged_at_beg_row > w->current_matrix->rows)
14795 --last_unchanged_at_beg_row;
14796
14797 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
14798 GIVE_UP (17);
14799
14800 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
14801 GIVE_UP (18);
14802 start_pos = it.current.pos;
14803
14804 /* Start displaying new lines in the desired matrix at the same
14805 vpos we would use in the current matrix, i.e. below
14806 last_unchanged_at_beg_row. */
14807 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
14808 current_matrix);
14809 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14810 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
14811
14812 xassert (it.hpos == 0 && it.current_x == 0);
14813 }
14814 else
14815 {
14816 /* There are no reusable lines at the start of the window.
14817 Start displaying in the first text line. */
14818 start_display (&it, w, start);
14819 it.vpos = it.first_vpos;
14820 start_pos = it.current.pos;
14821 }
14822
14823 /* Find the first row that is not affected by changes at the end of
14824 the buffer. Value will be null if there is no unchanged row, in
14825 which case we must redisplay to the end of the window. delta
14826 will be set to the value by which buffer positions beginning with
14827 first_unchanged_at_end_row have to be adjusted due to text
14828 changes. */
14829 first_unchanged_at_end_row
14830 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
14831 IF_DEBUG (debug_delta = delta);
14832 IF_DEBUG (debug_delta_bytes = delta_bytes);
14833
14834 /* Set stop_pos to the buffer position up to which we will have to
14835 display new lines. If first_unchanged_at_end_row != NULL, this
14836 is the buffer position of the start of the line displayed in that
14837 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
14838 that we don't stop at a buffer position. */
14839 stop_pos = 0;
14840 if (first_unchanged_at_end_row)
14841 {
14842 xassert (last_unchanged_at_beg_row == NULL
14843 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
14844
14845 /* If this is a continuation line, move forward to the next one
14846 that isn't. Changes in lines above affect this line.
14847 Caution: this may move first_unchanged_at_end_row to a row
14848 not displaying text. */
14849 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
14850 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14851 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14852 < it.last_visible_y))
14853 ++first_unchanged_at_end_row;
14854
14855 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14856 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14857 >= it.last_visible_y))
14858 first_unchanged_at_end_row = NULL;
14859 else
14860 {
14861 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
14862 + delta);
14863 first_unchanged_at_end_vpos
14864 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
14865 xassert (stop_pos >= Z - END_UNCHANGED);
14866 }
14867 }
14868 else if (last_unchanged_at_beg_row == NULL)
14869 GIVE_UP (19);
14870
14871
14872 #if GLYPH_DEBUG
14873
14874 /* Either there is no unchanged row at the end, or the one we have
14875 now displays text. This is a necessary condition for the window
14876 end pos calculation at the end of this function. */
14877 xassert (first_unchanged_at_end_row == NULL
14878 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
14879
14880 debug_last_unchanged_at_beg_vpos
14881 = (last_unchanged_at_beg_row
14882 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
14883 : -1);
14884 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
14885
14886 #endif /* GLYPH_DEBUG != 0 */
14887
14888
14889 /* Display new lines. Set last_text_row to the last new line
14890 displayed which has text on it, i.e. might end up as being the
14891 line where the window_end_vpos is. */
14892 w->cursor.vpos = -1;
14893 last_text_row = NULL;
14894 overlay_arrow_seen = 0;
14895 while (it.current_y < it.last_visible_y
14896 && !fonts_changed_p
14897 && (first_unchanged_at_end_row == NULL
14898 || IT_CHARPOS (it) < stop_pos))
14899 {
14900 if (display_line (&it))
14901 last_text_row = it.glyph_row - 1;
14902 }
14903
14904 if (fonts_changed_p)
14905 return -1;
14906
14907
14908 /* Compute differences in buffer positions, y-positions etc. for
14909 lines reused at the bottom of the window. Compute what we can
14910 scroll. */
14911 if (first_unchanged_at_end_row
14912 /* No lines reused because we displayed everything up to the
14913 bottom of the window. */
14914 && it.current_y < it.last_visible_y)
14915 {
14916 dvpos = (it.vpos
14917 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
14918 current_matrix));
14919 dy = it.current_y - first_unchanged_at_end_row->y;
14920 run.current_y = first_unchanged_at_end_row->y;
14921 run.desired_y = run.current_y + dy;
14922 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
14923 }
14924 else
14925 {
14926 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
14927 first_unchanged_at_end_row = NULL;
14928 }
14929 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
14930
14931
14932 /* Find the cursor if not already found. We have to decide whether
14933 PT will appear on this window (it sometimes doesn't, but this is
14934 not a very frequent case.) This decision has to be made before
14935 the current matrix is altered. A value of cursor.vpos < 0 means
14936 that PT is either in one of the lines beginning at
14937 first_unchanged_at_end_row or below the window. Don't care for
14938 lines that might be displayed later at the window end; as
14939 mentioned, this is not a frequent case. */
14940 if (w->cursor.vpos < 0)
14941 {
14942 /* Cursor in unchanged rows at the top? */
14943 if (PT < CHARPOS (start_pos)
14944 && last_unchanged_at_beg_row)
14945 {
14946 row = row_containing_pos (w, PT,
14947 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
14948 last_unchanged_at_beg_row + 1, 0);
14949 if (row)
14950 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14951 }
14952
14953 /* Start from first_unchanged_at_end_row looking for PT. */
14954 else if (first_unchanged_at_end_row)
14955 {
14956 row = row_containing_pos (w, PT - delta,
14957 first_unchanged_at_end_row, NULL, 0);
14958 if (row)
14959 set_cursor_from_row (w, row, w->current_matrix, delta,
14960 delta_bytes, dy, dvpos);
14961 }
14962
14963 /* Give up if cursor was not found. */
14964 if (w->cursor.vpos < 0)
14965 {
14966 clear_glyph_matrix (w->desired_matrix);
14967 return -1;
14968 }
14969 }
14970
14971 /* Don't let the cursor end in the scroll margins. */
14972 {
14973 int this_scroll_margin, cursor_height;
14974
14975 this_scroll_margin = max (0, scroll_margin);
14976 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14977 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
14978 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
14979
14980 if ((w->cursor.y < this_scroll_margin
14981 && CHARPOS (start) > BEGV)
14982 /* Old redisplay didn't take scroll margin into account at the bottom,
14983 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
14984 || (w->cursor.y + (make_cursor_line_fully_visible_p
14985 ? cursor_height + this_scroll_margin
14986 : 1)) > it.last_visible_y)
14987 {
14988 w->cursor.vpos = -1;
14989 clear_glyph_matrix (w->desired_matrix);
14990 return -1;
14991 }
14992 }
14993
14994 /* Scroll the display. Do it before changing the current matrix so
14995 that xterm.c doesn't get confused about where the cursor glyph is
14996 found. */
14997 if (dy && run.height)
14998 {
14999 update_begin (f);
15000
15001 if (FRAME_WINDOW_P (f))
15002 {
15003 FRAME_RIF (f)->update_window_begin_hook (w);
15004 FRAME_RIF (f)->clear_window_mouse_face (w);
15005 FRAME_RIF (f)->scroll_run_hook (w, &run);
15006 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15007 }
15008 else
15009 {
15010 /* Terminal frame. In this case, dvpos gives the number of
15011 lines to scroll by; dvpos < 0 means scroll up. */
15012 int first_unchanged_at_end_vpos
15013 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
15014 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
15015 int end = (WINDOW_TOP_EDGE_LINE (w)
15016 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
15017 + window_internal_height (w));
15018
15019 /* Perform the operation on the screen. */
15020 if (dvpos > 0)
15021 {
15022 /* Scroll last_unchanged_at_beg_row to the end of the
15023 window down dvpos lines. */
15024 set_terminal_window (f, end);
15025
15026 /* On dumb terminals delete dvpos lines at the end
15027 before inserting dvpos empty lines. */
15028 if (!FRAME_SCROLL_REGION_OK (f))
15029 ins_del_lines (f, end - dvpos, -dvpos);
15030
15031 /* Insert dvpos empty lines in front of
15032 last_unchanged_at_beg_row. */
15033 ins_del_lines (f, from, dvpos);
15034 }
15035 else if (dvpos < 0)
15036 {
15037 /* Scroll up last_unchanged_at_beg_vpos to the end of
15038 the window to last_unchanged_at_beg_vpos - |dvpos|. */
15039 set_terminal_window (f, end);
15040
15041 /* Delete dvpos lines in front of
15042 last_unchanged_at_beg_vpos. ins_del_lines will set
15043 the cursor to the given vpos and emit |dvpos| delete
15044 line sequences. */
15045 ins_del_lines (f, from + dvpos, dvpos);
15046
15047 /* On a dumb terminal insert dvpos empty lines at the
15048 end. */
15049 if (!FRAME_SCROLL_REGION_OK (f))
15050 ins_del_lines (f, end + dvpos, -dvpos);
15051 }
15052
15053 set_terminal_window (f, 0);
15054 }
15055
15056 update_end (f);
15057 }
15058
15059 /* Shift reused rows of the current matrix to the right position.
15060 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15061 text. */
15062 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15063 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
15064 if (dvpos < 0)
15065 {
15066 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
15067 bottom_vpos, dvpos);
15068 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
15069 bottom_vpos, 0);
15070 }
15071 else if (dvpos > 0)
15072 {
15073 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
15074 bottom_vpos, dvpos);
15075 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
15076 first_unchanged_at_end_vpos + dvpos, 0);
15077 }
15078
15079 /* For frame-based redisplay, make sure that current frame and window
15080 matrix are in sync with respect to glyph memory. */
15081 if (!FRAME_WINDOW_P (f))
15082 sync_frame_with_window_matrix_rows (w);
15083
15084 /* Adjust buffer positions in reused rows. */
15085 if (delta || delta_bytes)
15086 increment_matrix_positions (current_matrix,
15087 first_unchanged_at_end_vpos + dvpos,
15088 bottom_vpos, delta, delta_bytes);
15089
15090 /* Adjust Y positions. */
15091 if (dy)
15092 shift_glyph_matrix (w, current_matrix,
15093 first_unchanged_at_end_vpos + dvpos,
15094 bottom_vpos, dy);
15095
15096 if (first_unchanged_at_end_row)
15097 {
15098 first_unchanged_at_end_row += dvpos;
15099 if (first_unchanged_at_end_row->y >= it.last_visible_y
15100 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
15101 first_unchanged_at_end_row = NULL;
15102 }
15103
15104 /* If scrolling up, there may be some lines to display at the end of
15105 the window. */
15106 last_text_row_at_end = NULL;
15107 if (dy < 0)
15108 {
15109 /* Scrolling up can leave for example a partially visible line
15110 at the end of the window to be redisplayed. */
15111 /* Set last_row to the glyph row in the current matrix where the
15112 window end line is found. It has been moved up or down in
15113 the matrix by dvpos. */
15114 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
15115 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
15116
15117 /* If last_row is the window end line, it should display text. */
15118 xassert (last_row->displays_text_p);
15119
15120 /* If window end line was partially visible before, begin
15121 displaying at that line. Otherwise begin displaying with the
15122 line following it. */
15123 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
15124 {
15125 init_to_row_start (&it, w, last_row);
15126 it.vpos = last_vpos;
15127 it.current_y = last_row->y;
15128 }
15129 else
15130 {
15131 init_to_row_end (&it, w, last_row);
15132 it.vpos = 1 + last_vpos;
15133 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
15134 ++last_row;
15135 }
15136
15137 /* We may start in a continuation line. If so, we have to
15138 get the right continuation_lines_width and current_x. */
15139 it.continuation_lines_width = last_row->continuation_lines_width;
15140 it.hpos = it.current_x = 0;
15141
15142 /* Display the rest of the lines at the window end. */
15143 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15144 while (it.current_y < it.last_visible_y
15145 && !fonts_changed_p)
15146 {
15147 /* Is it always sure that the display agrees with lines in
15148 the current matrix? I don't think so, so we mark rows
15149 displayed invalid in the current matrix by setting their
15150 enabled_p flag to zero. */
15151 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
15152 if (display_line (&it))
15153 last_text_row_at_end = it.glyph_row - 1;
15154 }
15155 }
15156
15157 /* Update window_end_pos and window_end_vpos. */
15158 if (first_unchanged_at_end_row
15159 && !last_text_row_at_end)
15160 {
15161 /* Window end line if one of the preserved rows from the current
15162 matrix. Set row to the last row displaying text in current
15163 matrix starting at first_unchanged_at_end_row, after
15164 scrolling. */
15165 xassert (first_unchanged_at_end_row->displays_text_p);
15166 row = find_last_row_displaying_text (w->current_matrix, &it,
15167 first_unchanged_at_end_row);
15168 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
15169
15170 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15171 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15172 w->window_end_vpos
15173 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
15174 xassert (w->window_end_bytepos >= 0);
15175 IF_DEBUG (debug_method_add (w, "A"));
15176 }
15177 else if (last_text_row_at_end)
15178 {
15179 w->window_end_pos
15180 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
15181 w->window_end_bytepos
15182 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
15183 w->window_end_vpos
15184 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
15185 xassert (w->window_end_bytepos >= 0);
15186 IF_DEBUG (debug_method_add (w, "B"));
15187 }
15188 else if (last_text_row)
15189 {
15190 /* We have displayed either to the end of the window or at the
15191 end of the window, i.e. the last row with text is to be found
15192 in the desired matrix. */
15193 w->window_end_pos
15194 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15195 w->window_end_bytepos
15196 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15197 w->window_end_vpos
15198 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
15199 xassert (w->window_end_bytepos >= 0);
15200 }
15201 else if (first_unchanged_at_end_row == NULL
15202 && last_text_row == NULL
15203 && last_text_row_at_end == NULL)
15204 {
15205 /* Displayed to end of window, but no line containing text was
15206 displayed. Lines were deleted at the end of the window. */
15207 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
15208 int vpos = XFASTINT (w->window_end_vpos);
15209 struct glyph_row *current_row = current_matrix->rows + vpos;
15210 struct glyph_row *desired_row = desired_matrix->rows + vpos;
15211
15212 for (row = NULL;
15213 row == NULL && vpos >= first_vpos;
15214 --vpos, --current_row, --desired_row)
15215 {
15216 if (desired_row->enabled_p)
15217 {
15218 if (desired_row->displays_text_p)
15219 row = desired_row;
15220 }
15221 else if (current_row->displays_text_p)
15222 row = current_row;
15223 }
15224
15225 xassert (row != NULL);
15226 w->window_end_vpos = make_number (vpos + 1);
15227 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15228 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15229 xassert (w->window_end_bytepos >= 0);
15230 IF_DEBUG (debug_method_add (w, "C"));
15231 }
15232 else
15233 abort ();
15234
15235 #if 0 /* This leads to problems, for instance when the cursor is
15236 at ZV, and the cursor line displays no text. */
15237 /* Disable rows below what's displayed in the window. This makes
15238 debugging easier. */
15239 enable_glyph_matrix_rows (current_matrix,
15240 XFASTINT (w->window_end_vpos) + 1,
15241 bottom_vpos, 0);
15242 #endif
15243
15244 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
15245 debug_end_vpos = XFASTINT (w->window_end_vpos));
15246
15247 /* Record that display has not been completed. */
15248 w->window_end_valid = Qnil;
15249 w->desired_matrix->no_scrolling_p = 1;
15250 return 3;
15251
15252 #undef GIVE_UP
15253 }
15254
15255
15256 \f
15257 /***********************************************************************
15258 More debugging support
15259 ***********************************************************************/
15260
15261 #if GLYPH_DEBUG
15262
15263 void dump_glyph_row P_ ((struct glyph_row *, int, int));
15264 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
15265 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
15266
15267
15268 /* Dump the contents of glyph matrix MATRIX on stderr.
15269
15270 GLYPHS 0 means don't show glyph contents.
15271 GLYPHS 1 means show glyphs in short form
15272 GLYPHS > 1 means show glyphs in long form. */
15273
15274 void
15275 dump_glyph_matrix (matrix, glyphs)
15276 struct glyph_matrix *matrix;
15277 int glyphs;
15278 {
15279 int i;
15280 for (i = 0; i < matrix->nrows; ++i)
15281 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
15282 }
15283
15284
15285 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
15286 the glyph row and area where the glyph comes from. */
15287
15288 void
15289 dump_glyph (row, glyph, area)
15290 struct glyph_row *row;
15291 struct glyph *glyph;
15292 int area;
15293 {
15294 if (glyph->type == CHAR_GLYPH)
15295 {
15296 fprintf (stderr,
15297 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15298 glyph - row->glyphs[TEXT_AREA],
15299 'C',
15300 glyph->charpos,
15301 (BUFFERP (glyph->object)
15302 ? 'B'
15303 : (STRINGP (glyph->object)
15304 ? 'S'
15305 : '-')),
15306 glyph->pixel_width,
15307 glyph->u.ch,
15308 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
15309 ? glyph->u.ch
15310 : '.'),
15311 glyph->face_id,
15312 glyph->left_box_line_p,
15313 glyph->right_box_line_p);
15314 }
15315 else if (glyph->type == STRETCH_GLYPH)
15316 {
15317 fprintf (stderr,
15318 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15319 glyph - row->glyphs[TEXT_AREA],
15320 'S',
15321 glyph->charpos,
15322 (BUFFERP (glyph->object)
15323 ? 'B'
15324 : (STRINGP (glyph->object)
15325 ? 'S'
15326 : '-')),
15327 glyph->pixel_width,
15328 0,
15329 '.',
15330 glyph->face_id,
15331 glyph->left_box_line_p,
15332 glyph->right_box_line_p);
15333 }
15334 else if (glyph->type == IMAGE_GLYPH)
15335 {
15336 fprintf (stderr,
15337 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15338 glyph - row->glyphs[TEXT_AREA],
15339 'I',
15340 glyph->charpos,
15341 (BUFFERP (glyph->object)
15342 ? 'B'
15343 : (STRINGP (glyph->object)
15344 ? 'S'
15345 : '-')),
15346 glyph->pixel_width,
15347 glyph->u.img_id,
15348 '.',
15349 glyph->face_id,
15350 glyph->left_box_line_p,
15351 glyph->right_box_line_p);
15352 }
15353 else if (glyph->type == COMPOSITE_GLYPH)
15354 {
15355 fprintf (stderr,
15356 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15357 glyph - row->glyphs[TEXT_AREA],
15358 '+',
15359 glyph->charpos,
15360 (BUFFERP (glyph->object)
15361 ? 'B'
15362 : (STRINGP (glyph->object)
15363 ? 'S'
15364 : '-')),
15365 glyph->pixel_width,
15366 glyph->u.cmp_id,
15367 '.',
15368 glyph->face_id,
15369 glyph->left_box_line_p,
15370 glyph->right_box_line_p);
15371 }
15372 }
15373
15374
15375 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
15376 GLYPHS 0 means don't show glyph contents.
15377 GLYPHS 1 means show glyphs in short form
15378 GLYPHS > 1 means show glyphs in long form. */
15379
15380 void
15381 dump_glyph_row (row, vpos, glyphs)
15382 struct glyph_row *row;
15383 int vpos, glyphs;
15384 {
15385 if (glyphs != 1)
15386 {
15387 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
15388 fprintf (stderr, "======================================================================\n");
15389
15390 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
15391 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
15392 vpos,
15393 MATRIX_ROW_START_CHARPOS (row),
15394 MATRIX_ROW_END_CHARPOS (row),
15395 row->used[TEXT_AREA],
15396 row->contains_overlapping_glyphs_p,
15397 row->enabled_p,
15398 row->truncated_on_left_p,
15399 row->truncated_on_right_p,
15400 row->continued_p,
15401 MATRIX_ROW_CONTINUATION_LINE_P (row),
15402 row->displays_text_p,
15403 row->ends_at_zv_p,
15404 row->fill_line_p,
15405 row->ends_in_middle_of_char_p,
15406 row->starts_in_middle_of_char_p,
15407 row->mouse_face_p,
15408 row->x,
15409 row->y,
15410 row->pixel_width,
15411 row->height,
15412 row->visible_height,
15413 row->ascent,
15414 row->phys_ascent);
15415 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
15416 row->end.overlay_string_index,
15417 row->continuation_lines_width);
15418 fprintf (stderr, "%9d %5d\n",
15419 CHARPOS (row->start.string_pos),
15420 CHARPOS (row->end.string_pos));
15421 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
15422 row->end.dpvec_index);
15423 }
15424
15425 if (glyphs > 1)
15426 {
15427 int area;
15428
15429 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15430 {
15431 struct glyph *glyph = row->glyphs[area];
15432 struct glyph *glyph_end = glyph + row->used[area];
15433
15434 /* Glyph for a line end in text. */
15435 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
15436 ++glyph_end;
15437
15438 if (glyph < glyph_end)
15439 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
15440
15441 for (; glyph < glyph_end; ++glyph)
15442 dump_glyph (row, glyph, area);
15443 }
15444 }
15445 else if (glyphs == 1)
15446 {
15447 int area;
15448
15449 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15450 {
15451 char *s = (char *) alloca (row->used[area] + 1);
15452 int i;
15453
15454 for (i = 0; i < row->used[area]; ++i)
15455 {
15456 struct glyph *glyph = row->glyphs[area] + i;
15457 if (glyph->type == CHAR_GLYPH
15458 && glyph->u.ch < 0x80
15459 && glyph->u.ch >= ' ')
15460 s[i] = glyph->u.ch;
15461 else
15462 s[i] = '.';
15463 }
15464
15465 s[i] = '\0';
15466 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
15467 }
15468 }
15469 }
15470
15471
15472 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
15473 Sdump_glyph_matrix, 0, 1, "p",
15474 doc: /* Dump the current matrix of the selected window to stderr.
15475 Shows contents of glyph row structures. With non-nil
15476 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
15477 glyphs in short form, otherwise show glyphs in long form. */)
15478 (glyphs)
15479 Lisp_Object glyphs;
15480 {
15481 struct window *w = XWINDOW (selected_window);
15482 struct buffer *buffer = XBUFFER (w->buffer);
15483
15484 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
15485 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
15486 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
15487 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
15488 fprintf (stderr, "=============================================\n");
15489 dump_glyph_matrix (w->current_matrix,
15490 NILP (glyphs) ? 0 : XINT (glyphs));
15491 return Qnil;
15492 }
15493
15494
15495 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
15496 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
15497 ()
15498 {
15499 struct frame *f = XFRAME (selected_frame);
15500 dump_glyph_matrix (f->current_matrix, 1);
15501 return Qnil;
15502 }
15503
15504
15505 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
15506 doc: /* Dump glyph row ROW to stderr.
15507 GLYPH 0 means don't dump glyphs.
15508 GLYPH 1 means dump glyphs in short form.
15509 GLYPH > 1 or omitted means dump glyphs in long form. */)
15510 (row, glyphs)
15511 Lisp_Object row, glyphs;
15512 {
15513 struct glyph_matrix *matrix;
15514 int vpos;
15515
15516 CHECK_NUMBER (row);
15517 matrix = XWINDOW (selected_window)->current_matrix;
15518 vpos = XINT (row);
15519 if (vpos >= 0 && vpos < matrix->nrows)
15520 dump_glyph_row (MATRIX_ROW (matrix, vpos),
15521 vpos,
15522 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15523 return Qnil;
15524 }
15525
15526
15527 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
15528 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
15529 GLYPH 0 means don't dump glyphs.
15530 GLYPH 1 means dump glyphs in short form.
15531 GLYPH > 1 or omitted means dump glyphs in long form. */)
15532 (row, glyphs)
15533 Lisp_Object row, glyphs;
15534 {
15535 struct frame *sf = SELECTED_FRAME ();
15536 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
15537 int vpos;
15538
15539 CHECK_NUMBER (row);
15540 vpos = XINT (row);
15541 if (vpos >= 0 && vpos < m->nrows)
15542 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
15543 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15544 return Qnil;
15545 }
15546
15547
15548 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
15549 doc: /* Toggle tracing of redisplay.
15550 With ARG, turn tracing on if and only if ARG is positive. */)
15551 (arg)
15552 Lisp_Object arg;
15553 {
15554 if (NILP (arg))
15555 trace_redisplay_p = !trace_redisplay_p;
15556 else
15557 {
15558 arg = Fprefix_numeric_value (arg);
15559 trace_redisplay_p = XINT (arg) > 0;
15560 }
15561
15562 return Qnil;
15563 }
15564
15565
15566 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
15567 doc: /* Like `format', but print result to stderr.
15568 usage: (trace-to-stderr STRING &rest OBJECTS) */)
15569 (nargs, args)
15570 int nargs;
15571 Lisp_Object *args;
15572 {
15573 Lisp_Object s = Fformat (nargs, args);
15574 fprintf (stderr, "%s", SDATA (s));
15575 return Qnil;
15576 }
15577
15578 #endif /* GLYPH_DEBUG */
15579
15580
15581 \f
15582 /***********************************************************************
15583 Building Desired Matrix Rows
15584 ***********************************************************************/
15585
15586 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
15587 Used for non-window-redisplay windows, and for windows w/o left fringe. */
15588
15589 static struct glyph_row *
15590 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
15591 struct window *w;
15592 Lisp_Object overlay_arrow_string;
15593 {
15594 struct frame *f = XFRAME (WINDOW_FRAME (w));
15595 struct buffer *buffer = XBUFFER (w->buffer);
15596 struct buffer *old = current_buffer;
15597 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
15598 int arrow_len = SCHARS (overlay_arrow_string);
15599 const unsigned char *arrow_end = arrow_string + arrow_len;
15600 const unsigned char *p;
15601 struct it it;
15602 int multibyte_p;
15603 int n_glyphs_before;
15604
15605 set_buffer_temp (buffer);
15606 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
15607 it.glyph_row->used[TEXT_AREA] = 0;
15608 SET_TEXT_POS (it.position, 0, 0);
15609
15610 multibyte_p = !NILP (buffer->enable_multibyte_characters);
15611 p = arrow_string;
15612 while (p < arrow_end)
15613 {
15614 Lisp_Object face, ilisp;
15615
15616 /* Get the next character. */
15617 if (multibyte_p)
15618 it.c = string_char_and_length (p, arrow_len, &it.len);
15619 else
15620 it.c = *p, it.len = 1;
15621 p += it.len;
15622
15623 /* Get its face. */
15624 ilisp = make_number (p - arrow_string);
15625 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
15626 it.face_id = compute_char_face (f, it.c, face);
15627
15628 /* Compute its width, get its glyphs. */
15629 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
15630 SET_TEXT_POS (it.position, -1, -1);
15631 PRODUCE_GLYPHS (&it);
15632
15633 /* If this character doesn't fit any more in the line, we have
15634 to remove some glyphs. */
15635 if (it.current_x > it.last_visible_x)
15636 {
15637 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
15638 break;
15639 }
15640 }
15641
15642 set_buffer_temp (old);
15643 return it.glyph_row;
15644 }
15645
15646
15647 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
15648 glyphs are only inserted for terminal frames since we can't really
15649 win with truncation glyphs when partially visible glyphs are
15650 involved. Which glyphs to insert is determined by
15651 produce_special_glyphs. */
15652
15653 static void
15654 insert_left_trunc_glyphs (it)
15655 struct it *it;
15656 {
15657 struct it truncate_it;
15658 struct glyph *from, *end, *to, *toend;
15659
15660 xassert (!FRAME_WINDOW_P (it->f));
15661
15662 /* Get the truncation glyphs. */
15663 truncate_it = *it;
15664 truncate_it.current_x = 0;
15665 truncate_it.face_id = DEFAULT_FACE_ID;
15666 truncate_it.glyph_row = &scratch_glyph_row;
15667 truncate_it.glyph_row->used[TEXT_AREA] = 0;
15668 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
15669 truncate_it.object = make_number (0);
15670 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
15671
15672 /* Overwrite glyphs from IT with truncation glyphs. */
15673 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15674 end = from + truncate_it.glyph_row->used[TEXT_AREA];
15675 to = it->glyph_row->glyphs[TEXT_AREA];
15676 toend = to + it->glyph_row->used[TEXT_AREA];
15677
15678 while (from < end)
15679 *to++ = *from++;
15680
15681 /* There may be padding glyphs left over. Overwrite them too. */
15682 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
15683 {
15684 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15685 while (from < end)
15686 *to++ = *from++;
15687 }
15688
15689 if (to > toend)
15690 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
15691 }
15692
15693
15694 /* Compute the pixel height and width of IT->glyph_row.
15695
15696 Most of the time, ascent and height of a display line will be equal
15697 to the max_ascent and max_height values of the display iterator
15698 structure. This is not the case if
15699
15700 1. We hit ZV without displaying anything. In this case, max_ascent
15701 and max_height will be zero.
15702
15703 2. We have some glyphs that don't contribute to the line height.
15704 (The glyph row flag contributes_to_line_height_p is for future
15705 pixmap extensions).
15706
15707 The first case is easily covered by using default values because in
15708 these cases, the line height does not really matter, except that it
15709 must not be zero. */
15710
15711 static void
15712 compute_line_metrics (it)
15713 struct it *it;
15714 {
15715 struct glyph_row *row = it->glyph_row;
15716 int area, i;
15717
15718 if (FRAME_WINDOW_P (it->f))
15719 {
15720 int i, min_y, max_y;
15721
15722 /* The line may consist of one space only, that was added to
15723 place the cursor on it. If so, the row's height hasn't been
15724 computed yet. */
15725 if (row->height == 0)
15726 {
15727 if (it->max_ascent + it->max_descent == 0)
15728 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
15729 row->ascent = it->max_ascent;
15730 row->height = it->max_ascent + it->max_descent;
15731 row->phys_ascent = it->max_phys_ascent;
15732 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15733 row->extra_line_spacing = it->max_extra_line_spacing;
15734 }
15735
15736 /* Compute the width of this line. */
15737 row->pixel_width = row->x;
15738 for (i = 0; i < row->used[TEXT_AREA]; ++i)
15739 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
15740
15741 xassert (row->pixel_width >= 0);
15742 xassert (row->ascent >= 0 && row->height > 0);
15743
15744 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
15745 || MATRIX_ROW_OVERLAPS_PRED_P (row));
15746
15747 /* If first line's physical ascent is larger than its logical
15748 ascent, use the physical ascent, and make the row taller.
15749 This makes accented characters fully visible. */
15750 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
15751 && row->phys_ascent > row->ascent)
15752 {
15753 row->height += row->phys_ascent - row->ascent;
15754 row->ascent = row->phys_ascent;
15755 }
15756
15757 /* Compute how much of the line is visible. */
15758 row->visible_height = row->height;
15759
15760 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
15761 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
15762
15763 if (row->y < min_y)
15764 row->visible_height -= min_y - row->y;
15765 if (row->y + row->height > max_y)
15766 row->visible_height -= row->y + row->height - max_y;
15767 }
15768 else
15769 {
15770 row->pixel_width = row->used[TEXT_AREA];
15771 if (row->continued_p)
15772 row->pixel_width -= it->continuation_pixel_width;
15773 else if (row->truncated_on_right_p)
15774 row->pixel_width -= it->truncation_pixel_width;
15775 row->ascent = row->phys_ascent = 0;
15776 row->height = row->phys_height = row->visible_height = 1;
15777 row->extra_line_spacing = 0;
15778 }
15779
15780 /* Compute a hash code for this row. */
15781 row->hash = 0;
15782 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15783 for (i = 0; i < row->used[area]; ++i)
15784 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
15785 + row->glyphs[area][i].u.val
15786 + row->glyphs[area][i].face_id
15787 + row->glyphs[area][i].padding_p
15788 + (row->glyphs[area][i].type << 2));
15789
15790 it->max_ascent = it->max_descent = 0;
15791 it->max_phys_ascent = it->max_phys_descent = 0;
15792 }
15793
15794
15795 /* Append one space to the glyph row of iterator IT if doing a
15796 window-based redisplay. The space has the same face as
15797 IT->face_id. Value is non-zero if a space was added.
15798
15799 This function is called to make sure that there is always one glyph
15800 at the end of a glyph row that the cursor can be set on under
15801 window-systems. (If there weren't such a glyph we would not know
15802 how wide and tall a box cursor should be displayed).
15803
15804 At the same time this space let's a nicely handle clearing to the
15805 end of the line if the row ends in italic text. */
15806
15807 static int
15808 append_space_for_newline (it, default_face_p)
15809 struct it *it;
15810 int default_face_p;
15811 {
15812 if (FRAME_WINDOW_P (it->f))
15813 {
15814 int n = it->glyph_row->used[TEXT_AREA];
15815
15816 if (it->glyph_row->glyphs[TEXT_AREA] + n
15817 < it->glyph_row->glyphs[1 + TEXT_AREA])
15818 {
15819 /* Save some values that must not be changed.
15820 Must save IT->c and IT->len because otherwise
15821 ITERATOR_AT_END_P wouldn't work anymore after
15822 append_space_for_newline has been called. */
15823 enum display_element_type saved_what = it->what;
15824 int saved_c = it->c, saved_len = it->len;
15825 int saved_x = it->current_x;
15826 int saved_face_id = it->face_id;
15827 struct text_pos saved_pos;
15828 Lisp_Object saved_object;
15829 struct face *face;
15830
15831 saved_object = it->object;
15832 saved_pos = it->position;
15833
15834 it->what = IT_CHARACTER;
15835 bzero (&it->position, sizeof it->position);
15836 it->object = make_number (0);
15837 it->c = ' ';
15838 it->len = 1;
15839
15840 if (default_face_p)
15841 it->face_id = DEFAULT_FACE_ID;
15842 else if (it->face_before_selective_p)
15843 it->face_id = it->saved_face_id;
15844 face = FACE_FROM_ID (it->f, it->face_id);
15845 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
15846
15847 PRODUCE_GLYPHS (it);
15848
15849 it->override_ascent = -1;
15850 it->constrain_row_ascent_descent_p = 0;
15851 it->current_x = saved_x;
15852 it->object = saved_object;
15853 it->position = saved_pos;
15854 it->what = saved_what;
15855 it->face_id = saved_face_id;
15856 it->len = saved_len;
15857 it->c = saved_c;
15858 return 1;
15859 }
15860 }
15861
15862 return 0;
15863 }
15864
15865
15866 /* Extend the face of the last glyph in the text area of IT->glyph_row
15867 to the end of the display line. Called from display_line.
15868 If the glyph row is empty, add a space glyph to it so that we
15869 know the face to draw. Set the glyph row flag fill_line_p. */
15870
15871 static void
15872 extend_face_to_end_of_line (it)
15873 struct it *it;
15874 {
15875 struct face *face;
15876 struct frame *f = it->f;
15877
15878 /* If line is already filled, do nothing. */
15879 if (it->current_x >= it->last_visible_x)
15880 return;
15881
15882 /* Face extension extends the background and box of IT->face_id
15883 to the end of the line. If the background equals the background
15884 of the frame, we don't have to do anything. */
15885 if (it->face_before_selective_p)
15886 face = FACE_FROM_ID (it->f, it->saved_face_id);
15887 else
15888 face = FACE_FROM_ID (f, it->face_id);
15889
15890 if (FRAME_WINDOW_P (f)
15891 && it->glyph_row->displays_text_p
15892 && face->box == FACE_NO_BOX
15893 && face->background == FRAME_BACKGROUND_PIXEL (f)
15894 && !face->stipple)
15895 return;
15896
15897 /* Set the glyph row flag indicating that the face of the last glyph
15898 in the text area has to be drawn to the end of the text area. */
15899 it->glyph_row->fill_line_p = 1;
15900
15901 /* If current character of IT is not ASCII, make sure we have the
15902 ASCII face. This will be automatically undone the next time
15903 get_next_display_element returns a multibyte character. Note
15904 that the character will always be single byte in unibyte text. */
15905 if (!ASCII_CHAR_P (it->c))
15906 {
15907 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
15908 }
15909
15910 if (FRAME_WINDOW_P (f))
15911 {
15912 /* If the row is empty, add a space with the current face of IT,
15913 so that we know which face to draw. */
15914 if (it->glyph_row->used[TEXT_AREA] == 0)
15915 {
15916 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
15917 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
15918 it->glyph_row->used[TEXT_AREA] = 1;
15919 }
15920 }
15921 else
15922 {
15923 /* Save some values that must not be changed. */
15924 int saved_x = it->current_x;
15925 struct text_pos saved_pos;
15926 Lisp_Object saved_object;
15927 enum display_element_type saved_what = it->what;
15928 int saved_face_id = it->face_id;
15929
15930 saved_object = it->object;
15931 saved_pos = it->position;
15932
15933 it->what = IT_CHARACTER;
15934 bzero (&it->position, sizeof it->position);
15935 it->object = make_number (0);
15936 it->c = ' ';
15937 it->len = 1;
15938 it->face_id = face->id;
15939
15940 PRODUCE_GLYPHS (it);
15941
15942 while (it->current_x <= it->last_visible_x)
15943 PRODUCE_GLYPHS (it);
15944
15945 /* Don't count these blanks really. It would let us insert a left
15946 truncation glyph below and make us set the cursor on them, maybe. */
15947 it->current_x = saved_x;
15948 it->object = saved_object;
15949 it->position = saved_pos;
15950 it->what = saved_what;
15951 it->face_id = saved_face_id;
15952 }
15953 }
15954
15955
15956 /* Value is non-zero if text starting at CHARPOS in current_buffer is
15957 trailing whitespace. */
15958
15959 static int
15960 trailing_whitespace_p (charpos)
15961 int charpos;
15962 {
15963 int bytepos = CHAR_TO_BYTE (charpos);
15964 int c = 0;
15965
15966 while (bytepos < ZV_BYTE
15967 && (c = FETCH_CHAR (bytepos),
15968 c == ' ' || c == '\t'))
15969 ++bytepos;
15970
15971 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
15972 {
15973 if (bytepos != PT_BYTE)
15974 return 1;
15975 }
15976 return 0;
15977 }
15978
15979
15980 /* Highlight trailing whitespace, if any, in ROW. */
15981
15982 void
15983 highlight_trailing_whitespace (f, row)
15984 struct frame *f;
15985 struct glyph_row *row;
15986 {
15987 int used = row->used[TEXT_AREA];
15988
15989 if (used)
15990 {
15991 struct glyph *start = row->glyphs[TEXT_AREA];
15992 struct glyph *glyph = start + used - 1;
15993
15994 /* Skip over glyphs inserted to display the cursor at the
15995 end of a line, for extending the face of the last glyph
15996 to the end of the line on terminals, and for truncation
15997 and continuation glyphs. */
15998 while (glyph >= start
15999 && glyph->type == CHAR_GLYPH
16000 && INTEGERP (glyph->object))
16001 --glyph;
16002
16003 /* If last glyph is a space or stretch, and it's trailing
16004 whitespace, set the face of all trailing whitespace glyphs in
16005 IT->glyph_row to `trailing-whitespace'. */
16006 if (glyph >= start
16007 && BUFFERP (glyph->object)
16008 && (glyph->type == STRETCH_GLYPH
16009 || (glyph->type == CHAR_GLYPH
16010 && glyph->u.ch == ' '))
16011 && trailing_whitespace_p (glyph->charpos))
16012 {
16013 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
16014 if (face_id < 0)
16015 return;
16016
16017 while (glyph >= start
16018 && BUFFERP (glyph->object)
16019 && (glyph->type == STRETCH_GLYPH
16020 || (glyph->type == CHAR_GLYPH
16021 && glyph->u.ch == ' ')))
16022 (glyph--)->face_id = face_id;
16023 }
16024 }
16025 }
16026
16027
16028 /* Value is non-zero if glyph row ROW in window W should be
16029 used to hold the cursor. */
16030
16031 static int
16032 cursor_row_p (w, row)
16033 struct window *w;
16034 struct glyph_row *row;
16035 {
16036 int cursor_row_p = 1;
16037
16038 if (PT == MATRIX_ROW_END_CHARPOS (row))
16039 {
16040 /* Suppose the row ends on a string.
16041 Unless the row is continued, that means it ends on a newline
16042 in the string. If it's anything other than a display string
16043 (e.g. a before-string from an overlay), we don't want the
16044 cursor there. (This heuristic seems to give the optimal
16045 behavior for the various types of multi-line strings.) */
16046 if (CHARPOS (row->end.string_pos) >= 0)
16047 {
16048 if (row->continued_p)
16049 cursor_row_p = 1;
16050 else
16051 {
16052 /* Check for `display' property. */
16053 struct glyph *beg = row->glyphs[TEXT_AREA];
16054 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
16055 struct glyph *glyph;
16056
16057 cursor_row_p = 0;
16058 for (glyph = end; glyph >= beg; --glyph)
16059 if (STRINGP (glyph->object))
16060 {
16061 Lisp_Object prop
16062 = Fget_char_property (make_number (PT),
16063 Qdisplay, Qnil);
16064 cursor_row_p =
16065 (!NILP (prop)
16066 && display_prop_string_p (prop, glyph->object));
16067 break;
16068 }
16069 }
16070 }
16071 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16072 {
16073 /* If the row ends in middle of a real character,
16074 and the line is continued, we want the cursor here.
16075 That's because MATRIX_ROW_END_CHARPOS would equal
16076 PT if PT is before the character. */
16077 if (!row->ends_in_ellipsis_p)
16078 cursor_row_p = row->continued_p;
16079 else
16080 /* If the row ends in an ellipsis, then
16081 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
16082 We want that position to be displayed after the ellipsis. */
16083 cursor_row_p = 0;
16084 }
16085 /* If the row ends at ZV, display the cursor at the end of that
16086 row instead of at the start of the row below. */
16087 else if (row->ends_at_zv_p)
16088 cursor_row_p = 1;
16089 else
16090 cursor_row_p = 0;
16091 }
16092
16093 return cursor_row_p;
16094 }
16095
16096
16097 /* Construct the glyph row IT->glyph_row in the desired matrix of
16098 IT->w from text at the current position of IT. See dispextern.h
16099 for an overview of struct it. Value is non-zero if
16100 IT->glyph_row displays text, as opposed to a line displaying ZV
16101 only. */
16102
16103 static int
16104 display_line (it)
16105 struct it *it;
16106 {
16107 struct glyph_row *row = it->glyph_row;
16108 Lisp_Object overlay_arrow_string;
16109
16110 /* We always start displaying at hpos zero even if hscrolled. */
16111 xassert (it->hpos == 0 && it->current_x == 0);
16112
16113 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
16114 >= it->w->desired_matrix->nrows)
16115 {
16116 it->w->nrows_scale_factor++;
16117 fonts_changed_p = 1;
16118 return 0;
16119 }
16120
16121 /* Is IT->w showing the region? */
16122 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
16123
16124 /* Clear the result glyph row and enable it. */
16125 prepare_desired_row (row);
16126
16127 row->y = it->current_y;
16128 row->start = it->start;
16129 row->continuation_lines_width = it->continuation_lines_width;
16130 row->displays_text_p = 1;
16131 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
16132 it->starts_in_middle_of_char_p = 0;
16133
16134 /* Arrange the overlays nicely for our purposes. Usually, we call
16135 display_line on only one line at a time, in which case this
16136 can't really hurt too much, or we call it on lines which appear
16137 one after another in the buffer, in which case all calls to
16138 recenter_overlay_lists but the first will be pretty cheap. */
16139 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
16140
16141 /* Move over display elements that are not visible because we are
16142 hscrolled. This may stop at an x-position < IT->first_visible_x
16143 if the first glyph is partially visible or if we hit a line end. */
16144 if (it->current_x < it->first_visible_x)
16145 {
16146 move_it_in_display_line_to (it, ZV, it->first_visible_x,
16147 MOVE_TO_POS | MOVE_TO_X);
16148 }
16149
16150 /* Get the initial row height. This is either the height of the
16151 text hscrolled, if there is any, or zero. */
16152 row->ascent = it->max_ascent;
16153 row->height = it->max_ascent + it->max_descent;
16154 row->phys_ascent = it->max_phys_ascent;
16155 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16156 row->extra_line_spacing = it->max_extra_line_spacing;
16157
16158 /* Loop generating characters. The loop is left with IT on the next
16159 character to display. */
16160 while (1)
16161 {
16162 int n_glyphs_before, hpos_before, x_before;
16163 int x, i, nglyphs;
16164 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
16165
16166 /* Retrieve the next thing to display. Value is zero if end of
16167 buffer reached. */
16168 if (!get_next_display_element (it))
16169 {
16170 /* Maybe add a space at the end of this line that is used to
16171 display the cursor there under X. Set the charpos of the
16172 first glyph of blank lines not corresponding to any text
16173 to -1. */
16174 #ifdef HAVE_WINDOW_SYSTEM
16175 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16176 row->exact_window_width_line_p = 1;
16177 else
16178 #endif /* HAVE_WINDOW_SYSTEM */
16179 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
16180 || row->used[TEXT_AREA] == 0)
16181 {
16182 row->glyphs[TEXT_AREA]->charpos = -1;
16183 row->displays_text_p = 0;
16184
16185 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
16186 && (!MINI_WINDOW_P (it->w)
16187 || (minibuf_level && EQ (it->window, minibuf_window))))
16188 row->indicate_empty_line_p = 1;
16189 }
16190
16191 it->continuation_lines_width = 0;
16192 row->ends_at_zv_p = 1;
16193 break;
16194 }
16195
16196 /* Now, get the metrics of what we want to display. This also
16197 generates glyphs in `row' (which is IT->glyph_row). */
16198 n_glyphs_before = row->used[TEXT_AREA];
16199 x = it->current_x;
16200
16201 /* Remember the line height so far in case the next element doesn't
16202 fit on the line. */
16203 if (!it->truncate_lines_p)
16204 {
16205 ascent = it->max_ascent;
16206 descent = it->max_descent;
16207 phys_ascent = it->max_phys_ascent;
16208 phys_descent = it->max_phys_descent;
16209 }
16210
16211 PRODUCE_GLYPHS (it);
16212
16213 /* If this display element was in marginal areas, continue with
16214 the next one. */
16215 if (it->area != TEXT_AREA)
16216 {
16217 row->ascent = max (row->ascent, it->max_ascent);
16218 row->height = max (row->height, it->max_ascent + it->max_descent);
16219 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16220 row->phys_height = max (row->phys_height,
16221 it->max_phys_ascent + it->max_phys_descent);
16222 row->extra_line_spacing = max (row->extra_line_spacing,
16223 it->max_extra_line_spacing);
16224 set_iterator_to_next (it, 1);
16225 continue;
16226 }
16227
16228 /* Does the display element fit on the line? If we truncate
16229 lines, we should draw past the right edge of the window. If
16230 we don't truncate, we want to stop so that we can display the
16231 continuation glyph before the right margin. If lines are
16232 continued, there are two possible strategies for characters
16233 resulting in more than 1 glyph (e.g. tabs): Display as many
16234 glyphs as possible in this line and leave the rest for the
16235 continuation line, or display the whole element in the next
16236 line. Original redisplay did the former, so we do it also. */
16237 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
16238 hpos_before = it->hpos;
16239 x_before = x;
16240
16241 if (/* Not a newline. */
16242 nglyphs > 0
16243 /* Glyphs produced fit entirely in the line. */
16244 && it->current_x < it->last_visible_x)
16245 {
16246 it->hpos += nglyphs;
16247 row->ascent = max (row->ascent, it->max_ascent);
16248 row->height = max (row->height, it->max_ascent + it->max_descent);
16249 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16250 row->phys_height = max (row->phys_height,
16251 it->max_phys_ascent + it->max_phys_descent);
16252 row->extra_line_spacing = max (row->extra_line_spacing,
16253 it->max_extra_line_spacing);
16254 if (it->current_x - it->pixel_width < it->first_visible_x)
16255 row->x = x - it->first_visible_x;
16256 }
16257 else
16258 {
16259 int new_x;
16260 struct glyph *glyph;
16261
16262 for (i = 0; i < nglyphs; ++i, x = new_x)
16263 {
16264 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16265 new_x = x + glyph->pixel_width;
16266
16267 if (/* Lines are continued. */
16268 !it->truncate_lines_p
16269 && (/* Glyph doesn't fit on the line. */
16270 new_x > it->last_visible_x
16271 /* Or it fits exactly on a window system frame. */
16272 || (new_x == it->last_visible_x
16273 && FRAME_WINDOW_P (it->f))))
16274 {
16275 /* End of a continued line. */
16276
16277 if (it->hpos == 0
16278 || (new_x == it->last_visible_x
16279 && FRAME_WINDOW_P (it->f)))
16280 {
16281 /* Current glyph is the only one on the line or
16282 fits exactly on the line. We must continue
16283 the line because we can't draw the cursor
16284 after the glyph. */
16285 row->continued_p = 1;
16286 it->current_x = new_x;
16287 it->continuation_lines_width += new_x;
16288 ++it->hpos;
16289 if (i == nglyphs - 1)
16290 {
16291 set_iterator_to_next (it, 1);
16292 #ifdef HAVE_WINDOW_SYSTEM
16293 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16294 {
16295 if (!get_next_display_element (it))
16296 {
16297 row->exact_window_width_line_p = 1;
16298 it->continuation_lines_width = 0;
16299 row->continued_p = 0;
16300 row->ends_at_zv_p = 1;
16301 }
16302 else if (ITERATOR_AT_END_OF_LINE_P (it))
16303 {
16304 row->continued_p = 0;
16305 row->exact_window_width_line_p = 1;
16306 }
16307 }
16308 #endif /* HAVE_WINDOW_SYSTEM */
16309 }
16310 }
16311 else if (CHAR_GLYPH_PADDING_P (*glyph)
16312 && !FRAME_WINDOW_P (it->f))
16313 {
16314 /* A padding glyph that doesn't fit on this line.
16315 This means the whole character doesn't fit
16316 on the line. */
16317 row->used[TEXT_AREA] = n_glyphs_before;
16318
16319 /* Fill the rest of the row with continuation
16320 glyphs like in 20.x. */
16321 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
16322 < row->glyphs[1 + TEXT_AREA])
16323 produce_special_glyphs (it, IT_CONTINUATION);
16324
16325 row->continued_p = 1;
16326 it->current_x = x_before;
16327 it->continuation_lines_width += x_before;
16328
16329 /* Restore the height to what it was before the
16330 element not fitting on the line. */
16331 it->max_ascent = ascent;
16332 it->max_descent = descent;
16333 it->max_phys_ascent = phys_ascent;
16334 it->max_phys_descent = phys_descent;
16335 }
16336 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
16337 {
16338 /* A TAB that extends past the right edge of the
16339 window. This produces a single glyph on
16340 window system frames. We leave the glyph in
16341 this row and let it fill the row, but don't
16342 consume the TAB. */
16343 it->continuation_lines_width += it->last_visible_x;
16344 row->ends_in_middle_of_char_p = 1;
16345 row->continued_p = 1;
16346 glyph->pixel_width = it->last_visible_x - x;
16347 it->starts_in_middle_of_char_p = 1;
16348 }
16349 else
16350 {
16351 /* Something other than a TAB that draws past
16352 the right edge of the window. Restore
16353 positions to values before the element. */
16354 row->used[TEXT_AREA] = n_glyphs_before + i;
16355
16356 /* Display continuation glyphs. */
16357 if (!FRAME_WINDOW_P (it->f))
16358 produce_special_glyphs (it, IT_CONTINUATION);
16359 row->continued_p = 1;
16360
16361 it->current_x = x_before;
16362 it->continuation_lines_width += x;
16363 extend_face_to_end_of_line (it);
16364
16365 if (nglyphs > 1 && i > 0)
16366 {
16367 row->ends_in_middle_of_char_p = 1;
16368 it->starts_in_middle_of_char_p = 1;
16369 }
16370
16371 /* Restore the height to what it was before the
16372 element not fitting on the line. */
16373 it->max_ascent = ascent;
16374 it->max_descent = descent;
16375 it->max_phys_ascent = phys_ascent;
16376 it->max_phys_descent = phys_descent;
16377 }
16378
16379 break;
16380 }
16381 else if (new_x > it->first_visible_x)
16382 {
16383 /* Increment number of glyphs actually displayed. */
16384 ++it->hpos;
16385
16386 if (x < it->first_visible_x)
16387 /* Glyph is partially visible, i.e. row starts at
16388 negative X position. */
16389 row->x = x - it->first_visible_x;
16390 }
16391 else
16392 {
16393 /* Glyph is completely off the left margin of the
16394 window. This should not happen because of the
16395 move_it_in_display_line at the start of this
16396 function, unless the text display area of the
16397 window is empty. */
16398 xassert (it->first_visible_x <= it->last_visible_x);
16399 }
16400 }
16401
16402 row->ascent = max (row->ascent, it->max_ascent);
16403 row->height = max (row->height, it->max_ascent + it->max_descent);
16404 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16405 row->phys_height = max (row->phys_height,
16406 it->max_phys_ascent + it->max_phys_descent);
16407 row->extra_line_spacing = max (row->extra_line_spacing,
16408 it->max_extra_line_spacing);
16409
16410 /* End of this display line if row is continued. */
16411 if (row->continued_p || row->ends_at_zv_p)
16412 break;
16413 }
16414
16415 at_end_of_line:
16416 /* Is this a line end? If yes, we're also done, after making
16417 sure that a non-default face is extended up to the right
16418 margin of the window. */
16419 if (ITERATOR_AT_END_OF_LINE_P (it))
16420 {
16421 int used_before = row->used[TEXT_AREA];
16422
16423 row->ends_in_newline_from_string_p = STRINGP (it->object);
16424
16425 #ifdef HAVE_WINDOW_SYSTEM
16426 /* Add a space at the end of the line that is used to
16427 display the cursor there. */
16428 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16429 append_space_for_newline (it, 0);
16430 #endif /* HAVE_WINDOW_SYSTEM */
16431
16432 /* Extend the face to the end of the line. */
16433 extend_face_to_end_of_line (it);
16434
16435 /* Make sure we have the position. */
16436 if (used_before == 0)
16437 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
16438
16439 /* Consume the line end. This skips over invisible lines. */
16440 set_iterator_to_next (it, 1);
16441 it->continuation_lines_width = 0;
16442 break;
16443 }
16444
16445 /* Proceed with next display element. Note that this skips
16446 over lines invisible because of selective display. */
16447 set_iterator_to_next (it, 1);
16448
16449 /* If we truncate lines, we are done when the last displayed
16450 glyphs reach past the right margin of the window. */
16451 if (it->truncate_lines_p
16452 && (FRAME_WINDOW_P (it->f)
16453 ? (it->current_x >= it->last_visible_x)
16454 : (it->current_x > it->last_visible_x)))
16455 {
16456 /* Maybe add truncation glyphs. */
16457 if (!FRAME_WINDOW_P (it->f))
16458 {
16459 int i, n;
16460
16461 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16462 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16463 break;
16464
16465 for (n = row->used[TEXT_AREA]; i < n; ++i)
16466 {
16467 row->used[TEXT_AREA] = i;
16468 produce_special_glyphs (it, IT_TRUNCATION);
16469 }
16470 }
16471 #ifdef HAVE_WINDOW_SYSTEM
16472 else
16473 {
16474 /* Don't truncate if we can overflow newline into fringe. */
16475 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16476 {
16477 if (!get_next_display_element (it))
16478 {
16479 it->continuation_lines_width = 0;
16480 row->ends_at_zv_p = 1;
16481 row->exact_window_width_line_p = 1;
16482 break;
16483 }
16484 if (ITERATOR_AT_END_OF_LINE_P (it))
16485 {
16486 row->exact_window_width_line_p = 1;
16487 goto at_end_of_line;
16488 }
16489 }
16490 }
16491 #endif /* HAVE_WINDOW_SYSTEM */
16492
16493 row->truncated_on_right_p = 1;
16494 it->continuation_lines_width = 0;
16495 reseat_at_next_visible_line_start (it, 0);
16496 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
16497 it->hpos = hpos_before;
16498 it->current_x = x_before;
16499 break;
16500 }
16501 }
16502
16503 /* If line is not empty and hscrolled, maybe insert truncation glyphs
16504 at the left window margin. */
16505 if (it->first_visible_x
16506 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
16507 {
16508 if (!FRAME_WINDOW_P (it->f))
16509 insert_left_trunc_glyphs (it);
16510 row->truncated_on_left_p = 1;
16511 }
16512
16513 /* If the start of this line is the overlay arrow-position, then
16514 mark this glyph row as the one containing the overlay arrow.
16515 This is clearly a mess with variable size fonts. It would be
16516 better to let it be displayed like cursors under X. */
16517 if ((row->displays_text_p || !overlay_arrow_seen)
16518 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
16519 !NILP (overlay_arrow_string)))
16520 {
16521 /* Overlay arrow in window redisplay is a fringe bitmap. */
16522 if (STRINGP (overlay_arrow_string))
16523 {
16524 struct glyph_row *arrow_row
16525 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
16526 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
16527 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
16528 struct glyph *p = row->glyphs[TEXT_AREA];
16529 struct glyph *p2, *end;
16530
16531 /* Copy the arrow glyphs. */
16532 while (glyph < arrow_end)
16533 *p++ = *glyph++;
16534
16535 /* Throw away padding glyphs. */
16536 p2 = p;
16537 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16538 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
16539 ++p2;
16540 if (p2 > p)
16541 {
16542 while (p2 < end)
16543 *p++ = *p2++;
16544 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
16545 }
16546 }
16547 else
16548 {
16549 xassert (INTEGERP (overlay_arrow_string));
16550 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
16551 }
16552 overlay_arrow_seen = 1;
16553 }
16554
16555 /* Compute pixel dimensions of this line. */
16556 compute_line_metrics (it);
16557
16558 /* Remember the position at which this line ends. */
16559 row->end = it->current;
16560
16561 /* Record whether this row ends inside an ellipsis. */
16562 row->ends_in_ellipsis_p
16563 = (it->method == GET_FROM_DISPLAY_VECTOR
16564 && it->ellipsis_p);
16565
16566 /* Save fringe bitmaps in this row. */
16567 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
16568 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
16569 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
16570 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
16571
16572 it->left_user_fringe_bitmap = 0;
16573 it->left_user_fringe_face_id = 0;
16574 it->right_user_fringe_bitmap = 0;
16575 it->right_user_fringe_face_id = 0;
16576
16577 /* Maybe set the cursor. */
16578 if (it->w->cursor.vpos < 0
16579 && PT >= MATRIX_ROW_START_CHARPOS (row)
16580 && PT <= MATRIX_ROW_END_CHARPOS (row)
16581 && cursor_row_p (it->w, row))
16582 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
16583
16584 /* Highlight trailing whitespace. */
16585 if (!NILP (Vshow_trailing_whitespace))
16586 highlight_trailing_whitespace (it->f, it->glyph_row);
16587
16588 /* Prepare for the next line. This line starts horizontally at (X
16589 HPOS) = (0 0). Vertical positions are incremented. As a
16590 convenience for the caller, IT->glyph_row is set to the next
16591 row to be used. */
16592 it->current_x = it->hpos = 0;
16593 it->current_y += row->height;
16594 ++it->vpos;
16595 ++it->glyph_row;
16596 it->start = it->current;
16597 return row->displays_text_p;
16598 }
16599
16600
16601 \f
16602 /***********************************************************************
16603 Menu Bar
16604 ***********************************************************************/
16605
16606 /* Redisplay the menu bar in the frame for window W.
16607
16608 The menu bar of X frames that don't have X toolkit support is
16609 displayed in a special window W->frame->menu_bar_window.
16610
16611 The menu bar of terminal frames is treated specially as far as
16612 glyph matrices are concerned. Menu bar lines are not part of
16613 windows, so the update is done directly on the frame matrix rows
16614 for the menu bar. */
16615
16616 static void
16617 display_menu_bar (w)
16618 struct window *w;
16619 {
16620 struct frame *f = XFRAME (WINDOW_FRAME (w));
16621 struct it it;
16622 Lisp_Object items;
16623 int i;
16624
16625 /* Don't do all this for graphical frames. */
16626 #ifdef HAVE_NTGUI
16627 if (FRAME_W32_P (f))
16628 return;
16629 #endif
16630 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
16631 if (FRAME_X_P (f))
16632 return;
16633 #endif
16634 #ifdef MAC_OS
16635 if (FRAME_MAC_P (f))
16636 return;
16637 #endif
16638
16639 #ifdef USE_X_TOOLKIT
16640 xassert (!FRAME_WINDOW_P (f));
16641 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
16642 it.first_visible_x = 0;
16643 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16644 #else /* not USE_X_TOOLKIT */
16645 if (FRAME_WINDOW_P (f))
16646 {
16647 /* Menu bar lines are displayed in the desired matrix of the
16648 dummy window menu_bar_window. */
16649 struct window *menu_w;
16650 xassert (WINDOWP (f->menu_bar_window));
16651 menu_w = XWINDOW (f->menu_bar_window);
16652 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
16653 MENU_FACE_ID);
16654 it.first_visible_x = 0;
16655 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16656 }
16657 else
16658 {
16659 /* This is a TTY frame, i.e. character hpos/vpos are used as
16660 pixel x/y. */
16661 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
16662 MENU_FACE_ID);
16663 it.first_visible_x = 0;
16664 it.last_visible_x = FRAME_COLS (f);
16665 }
16666 #endif /* not USE_X_TOOLKIT */
16667
16668 if (! mode_line_inverse_video)
16669 /* Force the menu-bar to be displayed in the default face. */
16670 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16671
16672 /* Clear all rows of the menu bar. */
16673 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
16674 {
16675 struct glyph_row *row = it.glyph_row + i;
16676 clear_glyph_row (row);
16677 row->enabled_p = 1;
16678 row->full_width_p = 1;
16679 }
16680
16681 /* Display all items of the menu bar. */
16682 items = FRAME_MENU_BAR_ITEMS (it.f);
16683 for (i = 0; i < XVECTOR (items)->size; i += 4)
16684 {
16685 Lisp_Object string;
16686
16687 /* Stop at nil string. */
16688 string = AREF (items, i + 1);
16689 if (NILP (string))
16690 break;
16691
16692 /* Remember where item was displayed. */
16693 AREF (items, i + 3) = make_number (it.hpos);
16694
16695 /* Display the item, pad with one space. */
16696 if (it.current_x < it.last_visible_x)
16697 display_string (NULL, string, Qnil, 0, 0, &it,
16698 SCHARS (string) + 1, 0, 0, -1);
16699 }
16700
16701 /* Fill out the line with spaces. */
16702 if (it.current_x < it.last_visible_x)
16703 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
16704
16705 /* Compute the total height of the lines. */
16706 compute_line_metrics (&it);
16707 }
16708
16709
16710 \f
16711 /***********************************************************************
16712 Mode Line
16713 ***********************************************************************/
16714
16715 /* Redisplay mode lines in the window tree whose root is WINDOW. If
16716 FORCE is non-zero, redisplay mode lines unconditionally.
16717 Otherwise, redisplay only mode lines that are garbaged. Value is
16718 the number of windows whose mode lines were redisplayed. */
16719
16720 static int
16721 redisplay_mode_lines (window, force)
16722 Lisp_Object window;
16723 int force;
16724 {
16725 int nwindows = 0;
16726
16727 while (!NILP (window))
16728 {
16729 struct window *w = XWINDOW (window);
16730
16731 if (WINDOWP (w->hchild))
16732 nwindows += redisplay_mode_lines (w->hchild, force);
16733 else if (WINDOWP (w->vchild))
16734 nwindows += redisplay_mode_lines (w->vchild, force);
16735 else if (force
16736 || FRAME_GARBAGED_P (XFRAME (w->frame))
16737 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
16738 {
16739 struct text_pos lpoint;
16740 struct buffer *old = current_buffer;
16741
16742 /* Set the window's buffer for the mode line display. */
16743 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16744 set_buffer_internal_1 (XBUFFER (w->buffer));
16745
16746 /* Point refers normally to the selected window. For any
16747 other window, set up appropriate value. */
16748 if (!EQ (window, selected_window))
16749 {
16750 struct text_pos pt;
16751
16752 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
16753 if (CHARPOS (pt) < BEGV)
16754 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16755 else if (CHARPOS (pt) > (ZV - 1))
16756 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
16757 else
16758 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
16759 }
16760
16761 /* Display mode lines. */
16762 clear_glyph_matrix (w->desired_matrix);
16763 if (display_mode_lines (w))
16764 {
16765 ++nwindows;
16766 w->must_be_updated_p = 1;
16767 }
16768
16769 /* Restore old settings. */
16770 set_buffer_internal_1 (old);
16771 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16772 }
16773
16774 window = w->next;
16775 }
16776
16777 return nwindows;
16778 }
16779
16780
16781 /* Display the mode and/or top line of window W. Value is the number
16782 of mode lines displayed. */
16783
16784 static int
16785 display_mode_lines (w)
16786 struct window *w;
16787 {
16788 Lisp_Object old_selected_window, old_selected_frame;
16789 int n = 0;
16790
16791 old_selected_frame = selected_frame;
16792 selected_frame = w->frame;
16793 old_selected_window = selected_window;
16794 XSETWINDOW (selected_window, w);
16795
16796 /* These will be set while the mode line specs are processed. */
16797 line_number_displayed = 0;
16798 w->column_number_displayed = Qnil;
16799
16800 if (WINDOW_WANTS_MODELINE_P (w))
16801 {
16802 struct window *sel_w = XWINDOW (old_selected_window);
16803
16804 /* Select mode line face based on the real selected window. */
16805 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
16806 current_buffer->mode_line_format);
16807 ++n;
16808 }
16809
16810 if (WINDOW_WANTS_HEADER_LINE_P (w))
16811 {
16812 display_mode_line (w, HEADER_LINE_FACE_ID,
16813 current_buffer->header_line_format);
16814 ++n;
16815 }
16816
16817 selected_frame = old_selected_frame;
16818 selected_window = old_selected_window;
16819 return n;
16820 }
16821
16822
16823 /* Display mode or top line of window W. FACE_ID specifies which line
16824 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
16825 FORMAT is the mode line format to display. Value is the pixel
16826 height of the mode line displayed. */
16827
16828 static int
16829 display_mode_line (w, face_id, format)
16830 struct window *w;
16831 enum face_id face_id;
16832 Lisp_Object format;
16833 {
16834 struct it it;
16835 struct face *face;
16836 int count = SPECPDL_INDEX ();
16837
16838 init_iterator (&it, w, -1, -1, NULL, face_id);
16839 /* Don't extend on a previously drawn mode-line.
16840 This may happen if called from pos_visible_p. */
16841 it.glyph_row->enabled_p = 0;
16842 prepare_desired_row (it.glyph_row);
16843
16844 it.glyph_row->mode_line_p = 1;
16845
16846 if (! mode_line_inverse_video)
16847 /* Force the mode-line to be displayed in the default face. */
16848 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16849
16850 record_unwind_protect (unwind_format_mode_line,
16851 format_mode_line_unwind_data (NULL, 0));
16852
16853 mode_line_target = MODE_LINE_DISPLAY;
16854
16855 /* Temporarily make frame's keyboard the current kboard so that
16856 kboard-local variables in the mode_line_format will get the right
16857 values. */
16858 push_kboard (FRAME_KBOARD (it.f));
16859 record_unwind_save_match_data ();
16860 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16861 pop_kboard ();
16862
16863 unbind_to (count, Qnil);
16864
16865 /* Fill up with spaces. */
16866 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
16867
16868 compute_line_metrics (&it);
16869 it.glyph_row->full_width_p = 1;
16870 it.glyph_row->continued_p = 0;
16871 it.glyph_row->truncated_on_left_p = 0;
16872 it.glyph_row->truncated_on_right_p = 0;
16873
16874 /* Make a 3D mode-line have a shadow at its right end. */
16875 face = FACE_FROM_ID (it.f, face_id);
16876 extend_face_to_end_of_line (&it);
16877 if (face->box != FACE_NO_BOX)
16878 {
16879 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
16880 + it.glyph_row->used[TEXT_AREA] - 1);
16881 last->right_box_line_p = 1;
16882 }
16883
16884 return it.glyph_row->height;
16885 }
16886
16887 /* Move element ELT in LIST to the front of LIST.
16888 Return the updated list. */
16889
16890 static Lisp_Object
16891 move_elt_to_front (elt, list)
16892 Lisp_Object elt, list;
16893 {
16894 register Lisp_Object tail, prev;
16895 register Lisp_Object tem;
16896
16897 tail = list;
16898 prev = Qnil;
16899 while (CONSP (tail))
16900 {
16901 tem = XCAR (tail);
16902
16903 if (EQ (elt, tem))
16904 {
16905 /* Splice out the link TAIL. */
16906 if (NILP (prev))
16907 list = XCDR (tail);
16908 else
16909 Fsetcdr (prev, XCDR (tail));
16910
16911 /* Now make it the first. */
16912 Fsetcdr (tail, list);
16913 return tail;
16914 }
16915 else
16916 prev = tail;
16917 tail = XCDR (tail);
16918 QUIT;
16919 }
16920
16921 /* Not found--return unchanged LIST. */
16922 return list;
16923 }
16924
16925 /* Contribute ELT to the mode line for window IT->w. How it
16926 translates into text depends on its data type.
16927
16928 IT describes the display environment in which we display, as usual.
16929
16930 DEPTH is the depth in recursion. It is used to prevent
16931 infinite recursion here.
16932
16933 FIELD_WIDTH is the number of characters the display of ELT should
16934 occupy in the mode line, and PRECISION is the maximum number of
16935 characters to display from ELT's representation. See
16936 display_string for details.
16937
16938 Returns the hpos of the end of the text generated by ELT.
16939
16940 PROPS is a property list to add to any string we encounter.
16941
16942 If RISKY is nonzero, remove (disregard) any properties in any string
16943 we encounter, and ignore :eval and :propertize.
16944
16945 The global variable `mode_line_target' determines whether the
16946 output is passed to `store_mode_line_noprop',
16947 `store_mode_line_string', or `display_string'. */
16948
16949 static int
16950 display_mode_element (it, depth, field_width, precision, elt, props, risky)
16951 struct it *it;
16952 int depth;
16953 int field_width, precision;
16954 Lisp_Object elt, props;
16955 int risky;
16956 {
16957 int n = 0, field, prec;
16958 int literal = 0;
16959
16960 tail_recurse:
16961 if (depth > 100)
16962 elt = build_string ("*too-deep*");
16963
16964 depth++;
16965
16966 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
16967 {
16968 case Lisp_String:
16969 {
16970 /* A string: output it and check for %-constructs within it. */
16971 unsigned char c;
16972 int offset = 0;
16973
16974 if (SCHARS (elt) > 0
16975 && (!NILP (props) || risky))
16976 {
16977 Lisp_Object oprops, aelt;
16978 oprops = Ftext_properties_at (make_number (0), elt);
16979
16980 /* If the starting string's properties are not what
16981 we want, translate the string. Also, if the string
16982 is risky, do that anyway. */
16983
16984 if (NILP (Fequal (props, oprops)) || risky)
16985 {
16986 /* If the starting string has properties,
16987 merge the specified ones onto the existing ones. */
16988 if (! NILP (oprops) && !risky)
16989 {
16990 Lisp_Object tem;
16991
16992 oprops = Fcopy_sequence (oprops);
16993 tem = props;
16994 while (CONSP (tem))
16995 {
16996 oprops = Fplist_put (oprops, XCAR (tem),
16997 XCAR (XCDR (tem)));
16998 tem = XCDR (XCDR (tem));
16999 }
17000 props = oprops;
17001 }
17002
17003 aelt = Fassoc (elt, mode_line_proptrans_alist);
17004 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
17005 {
17006 /* AELT is what we want. Move it to the front
17007 without consing. */
17008 elt = XCAR (aelt);
17009 mode_line_proptrans_alist
17010 = move_elt_to_front (aelt, mode_line_proptrans_alist);
17011 }
17012 else
17013 {
17014 Lisp_Object tem;
17015
17016 /* If AELT has the wrong props, it is useless.
17017 so get rid of it. */
17018 if (! NILP (aelt))
17019 mode_line_proptrans_alist
17020 = Fdelq (aelt, mode_line_proptrans_alist);
17021
17022 elt = Fcopy_sequence (elt);
17023 Fset_text_properties (make_number (0), Flength (elt),
17024 props, elt);
17025 /* Add this item to mode_line_proptrans_alist. */
17026 mode_line_proptrans_alist
17027 = Fcons (Fcons (elt, props),
17028 mode_line_proptrans_alist);
17029 /* Truncate mode_line_proptrans_alist
17030 to at most 50 elements. */
17031 tem = Fnthcdr (make_number (50),
17032 mode_line_proptrans_alist);
17033 if (! NILP (tem))
17034 XSETCDR (tem, Qnil);
17035 }
17036 }
17037 }
17038
17039 offset = 0;
17040
17041 if (literal)
17042 {
17043 prec = precision - n;
17044 switch (mode_line_target)
17045 {
17046 case MODE_LINE_NOPROP:
17047 case MODE_LINE_TITLE:
17048 n += store_mode_line_noprop (SDATA (elt), -1, prec);
17049 break;
17050 case MODE_LINE_STRING:
17051 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
17052 break;
17053 case MODE_LINE_DISPLAY:
17054 n += display_string (NULL, elt, Qnil, 0, 0, it,
17055 0, prec, 0, STRING_MULTIBYTE (elt));
17056 break;
17057 }
17058
17059 break;
17060 }
17061
17062 /* Handle the non-literal case. */
17063
17064 while ((precision <= 0 || n < precision)
17065 && SREF (elt, offset) != 0
17066 && (mode_line_target != MODE_LINE_DISPLAY
17067 || it->current_x < it->last_visible_x))
17068 {
17069 int last_offset = offset;
17070
17071 /* Advance to end of string or next format specifier. */
17072 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
17073 ;
17074
17075 if (offset - 1 != last_offset)
17076 {
17077 int nchars, nbytes;
17078
17079 /* Output to end of string or up to '%'. Field width
17080 is length of string. Don't output more than
17081 PRECISION allows us. */
17082 offset--;
17083
17084 prec = c_string_width (SDATA (elt) + last_offset,
17085 offset - last_offset, precision - n,
17086 &nchars, &nbytes);
17087
17088 switch (mode_line_target)
17089 {
17090 case MODE_LINE_NOPROP:
17091 case MODE_LINE_TITLE:
17092 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
17093 break;
17094 case MODE_LINE_STRING:
17095 {
17096 int bytepos = last_offset;
17097 int charpos = string_byte_to_char (elt, bytepos);
17098 int endpos = (precision <= 0
17099 ? string_byte_to_char (elt, offset)
17100 : charpos + nchars);
17101
17102 n += store_mode_line_string (NULL,
17103 Fsubstring (elt, make_number (charpos),
17104 make_number (endpos)),
17105 0, 0, 0, Qnil);
17106 }
17107 break;
17108 case MODE_LINE_DISPLAY:
17109 {
17110 int bytepos = last_offset;
17111 int charpos = string_byte_to_char (elt, bytepos);
17112
17113 if (precision <= 0)
17114 nchars = string_byte_to_char (elt, offset) - charpos;
17115 n += display_string (NULL, elt, Qnil, 0, charpos,
17116 it, 0, nchars, 0,
17117 STRING_MULTIBYTE (elt));
17118 }
17119 break;
17120 }
17121 }
17122 else /* c == '%' */
17123 {
17124 int percent_position = offset;
17125
17126 /* Get the specified minimum width. Zero means
17127 don't pad. */
17128 field = 0;
17129 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
17130 field = field * 10 + c - '0';
17131
17132 /* Don't pad beyond the total padding allowed. */
17133 if (field_width - n > 0 && field > field_width - n)
17134 field = field_width - n;
17135
17136 /* Note that either PRECISION <= 0 or N < PRECISION. */
17137 prec = precision - n;
17138
17139 if (c == 'M')
17140 n += display_mode_element (it, depth, field, prec,
17141 Vglobal_mode_string, props,
17142 risky);
17143 else if (c != 0)
17144 {
17145 int multibyte;
17146 int bytepos, charpos;
17147 unsigned char *spec;
17148
17149 bytepos = percent_position;
17150 charpos = (STRING_MULTIBYTE (elt)
17151 ? string_byte_to_char (elt, bytepos)
17152 : bytepos);
17153
17154 spec
17155 = decode_mode_spec (it->w, c, field, prec, &multibyte);
17156
17157 switch (mode_line_target)
17158 {
17159 case MODE_LINE_NOPROP:
17160 case MODE_LINE_TITLE:
17161 n += store_mode_line_noprop (spec, field, prec);
17162 break;
17163 case MODE_LINE_STRING:
17164 {
17165 int len = strlen (spec);
17166 Lisp_Object tem = make_string (spec, len);
17167 props = Ftext_properties_at (make_number (charpos), elt);
17168 /* Should only keep face property in props */
17169 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
17170 }
17171 break;
17172 case MODE_LINE_DISPLAY:
17173 {
17174 int nglyphs_before, nwritten;
17175
17176 nglyphs_before = it->glyph_row->used[TEXT_AREA];
17177 nwritten = display_string (spec, Qnil, elt,
17178 charpos, 0, it,
17179 field, prec, 0,
17180 multibyte);
17181
17182 /* Assign to the glyphs written above the
17183 string where the `%x' came from, position
17184 of the `%'. */
17185 if (nwritten > 0)
17186 {
17187 struct glyph *glyph
17188 = (it->glyph_row->glyphs[TEXT_AREA]
17189 + nglyphs_before);
17190 int i;
17191
17192 for (i = 0; i < nwritten; ++i)
17193 {
17194 glyph[i].object = elt;
17195 glyph[i].charpos = charpos;
17196 }
17197
17198 n += nwritten;
17199 }
17200 }
17201 break;
17202 }
17203 }
17204 else /* c == 0 */
17205 break;
17206 }
17207 }
17208 }
17209 break;
17210
17211 case Lisp_Symbol:
17212 /* A symbol: process the value of the symbol recursively
17213 as if it appeared here directly. Avoid error if symbol void.
17214 Special case: if value of symbol is a string, output the string
17215 literally. */
17216 {
17217 register Lisp_Object tem;
17218
17219 /* If the variable is not marked as risky to set
17220 then its contents are risky to use. */
17221 if (NILP (Fget (elt, Qrisky_local_variable)))
17222 risky = 1;
17223
17224 tem = Fboundp (elt);
17225 if (!NILP (tem))
17226 {
17227 tem = Fsymbol_value (elt);
17228 /* If value is a string, output that string literally:
17229 don't check for % within it. */
17230 if (STRINGP (tem))
17231 literal = 1;
17232
17233 if (!EQ (tem, elt))
17234 {
17235 /* Give up right away for nil or t. */
17236 elt = tem;
17237 goto tail_recurse;
17238 }
17239 }
17240 }
17241 break;
17242
17243 case Lisp_Cons:
17244 {
17245 register Lisp_Object car, tem;
17246
17247 /* A cons cell: five distinct cases.
17248 If first element is :eval or :propertize, do something special.
17249 If first element is a string or a cons, process all the elements
17250 and effectively concatenate them.
17251 If first element is a negative number, truncate displaying cdr to
17252 at most that many characters. If positive, pad (with spaces)
17253 to at least that many characters.
17254 If first element is a symbol, process the cadr or caddr recursively
17255 according to whether the symbol's value is non-nil or nil. */
17256 car = XCAR (elt);
17257 if (EQ (car, QCeval))
17258 {
17259 /* An element of the form (:eval FORM) means evaluate FORM
17260 and use the result as mode line elements. */
17261
17262 if (risky)
17263 break;
17264
17265 if (CONSP (XCDR (elt)))
17266 {
17267 Lisp_Object spec;
17268 spec = safe_eval (XCAR (XCDR (elt)));
17269 n += display_mode_element (it, depth, field_width - n,
17270 precision - n, spec, props,
17271 risky);
17272 }
17273 }
17274 else if (EQ (car, QCpropertize))
17275 {
17276 /* An element of the form (:propertize ELT PROPS...)
17277 means display ELT but applying properties PROPS. */
17278
17279 if (risky)
17280 break;
17281
17282 if (CONSP (XCDR (elt)))
17283 n += display_mode_element (it, depth, field_width - n,
17284 precision - n, XCAR (XCDR (elt)),
17285 XCDR (XCDR (elt)), risky);
17286 }
17287 else if (SYMBOLP (car))
17288 {
17289 tem = Fboundp (car);
17290 elt = XCDR (elt);
17291 if (!CONSP (elt))
17292 goto invalid;
17293 /* elt is now the cdr, and we know it is a cons cell.
17294 Use its car if CAR has a non-nil value. */
17295 if (!NILP (tem))
17296 {
17297 tem = Fsymbol_value (car);
17298 if (!NILP (tem))
17299 {
17300 elt = XCAR (elt);
17301 goto tail_recurse;
17302 }
17303 }
17304 /* Symbol's value is nil (or symbol is unbound)
17305 Get the cddr of the original list
17306 and if possible find the caddr and use that. */
17307 elt = XCDR (elt);
17308 if (NILP (elt))
17309 break;
17310 else if (!CONSP (elt))
17311 goto invalid;
17312 elt = XCAR (elt);
17313 goto tail_recurse;
17314 }
17315 else if (INTEGERP (car))
17316 {
17317 register int lim = XINT (car);
17318 elt = XCDR (elt);
17319 if (lim < 0)
17320 {
17321 /* Negative int means reduce maximum width. */
17322 if (precision <= 0)
17323 precision = -lim;
17324 else
17325 precision = min (precision, -lim);
17326 }
17327 else if (lim > 0)
17328 {
17329 /* Padding specified. Don't let it be more than
17330 current maximum. */
17331 if (precision > 0)
17332 lim = min (precision, lim);
17333
17334 /* If that's more padding than already wanted, queue it.
17335 But don't reduce padding already specified even if
17336 that is beyond the current truncation point. */
17337 field_width = max (lim, field_width);
17338 }
17339 goto tail_recurse;
17340 }
17341 else if (STRINGP (car) || CONSP (car))
17342 {
17343 register int limit = 50;
17344 /* Limit is to protect against circular lists. */
17345 while (CONSP (elt)
17346 && --limit > 0
17347 && (precision <= 0 || n < precision))
17348 {
17349 n += display_mode_element (it, depth,
17350 /* Do padding only after the last
17351 element in the list. */
17352 (! CONSP (XCDR (elt))
17353 ? field_width - n
17354 : 0),
17355 precision - n, XCAR (elt),
17356 props, risky);
17357 elt = XCDR (elt);
17358 }
17359 }
17360 }
17361 break;
17362
17363 default:
17364 invalid:
17365 elt = build_string ("*invalid*");
17366 goto tail_recurse;
17367 }
17368
17369 /* Pad to FIELD_WIDTH. */
17370 if (field_width > 0 && n < field_width)
17371 {
17372 switch (mode_line_target)
17373 {
17374 case MODE_LINE_NOPROP:
17375 case MODE_LINE_TITLE:
17376 n += store_mode_line_noprop ("", field_width - n, 0);
17377 break;
17378 case MODE_LINE_STRING:
17379 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
17380 break;
17381 case MODE_LINE_DISPLAY:
17382 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
17383 0, 0, 0);
17384 break;
17385 }
17386 }
17387
17388 return n;
17389 }
17390
17391 /* Store a mode-line string element in mode_line_string_list.
17392
17393 If STRING is non-null, display that C string. Otherwise, the Lisp
17394 string LISP_STRING is displayed.
17395
17396 FIELD_WIDTH is the minimum number of output glyphs to produce.
17397 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17398 with spaces. FIELD_WIDTH <= 0 means don't pad.
17399
17400 PRECISION is the maximum number of characters to output from
17401 STRING. PRECISION <= 0 means don't truncate the string.
17402
17403 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
17404 properties to the string.
17405
17406 PROPS are the properties to add to the string.
17407 The mode_line_string_face face property is always added to the string.
17408 */
17409
17410 static int
17411 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
17412 char *string;
17413 Lisp_Object lisp_string;
17414 int copy_string;
17415 int field_width;
17416 int precision;
17417 Lisp_Object props;
17418 {
17419 int len;
17420 int n = 0;
17421
17422 if (string != NULL)
17423 {
17424 len = strlen (string);
17425 if (precision > 0 && len > precision)
17426 len = precision;
17427 lisp_string = make_string (string, len);
17428 if (NILP (props))
17429 props = mode_line_string_face_prop;
17430 else if (!NILP (mode_line_string_face))
17431 {
17432 Lisp_Object face = Fplist_get (props, Qface);
17433 props = Fcopy_sequence (props);
17434 if (NILP (face))
17435 face = mode_line_string_face;
17436 else
17437 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17438 props = Fplist_put (props, Qface, face);
17439 }
17440 Fadd_text_properties (make_number (0), make_number (len),
17441 props, lisp_string);
17442 }
17443 else
17444 {
17445 len = XFASTINT (Flength (lisp_string));
17446 if (precision > 0 && len > precision)
17447 {
17448 len = precision;
17449 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
17450 precision = -1;
17451 }
17452 if (!NILP (mode_line_string_face))
17453 {
17454 Lisp_Object face;
17455 if (NILP (props))
17456 props = Ftext_properties_at (make_number (0), lisp_string);
17457 face = Fplist_get (props, Qface);
17458 if (NILP (face))
17459 face = mode_line_string_face;
17460 else
17461 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17462 props = Fcons (Qface, Fcons (face, Qnil));
17463 if (copy_string)
17464 lisp_string = Fcopy_sequence (lisp_string);
17465 }
17466 if (!NILP (props))
17467 Fadd_text_properties (make_number (0), make_number (len),
17468 props, lisp_string);
17469 }
17470
17471 if (len > 0)
17472 {
17473 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17474 n += len;
17475 }
17476
17477 if (field_width > len)
17478 {
17479 field_width -= len;
17480 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
17481 if (!NILP (props))
17482 Fadd_text_properties (make_number (0), make_number (field_width),
17483 props, lisp_string);
17484 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17485 n += field_width;
17486 }
17487
17488 return n;
17489 }
17490
17491
17492 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
17493 1, 4, 0,
17494 doc: /* Format a string out of a mode line format specification.
17495 First arg FORMAT specifies the mode line format (see `mode-line-format'
17496 for details) to use.
17497
17498 Optional second arg FACE specifies the face property to put
17499 on all characters for which no face is specified.
17500 The value t means whatever face the window's mode line currently uses
17501 \(either `mode-line' or `mode-line-inactive', depending).
17502 A value of nil means the default is no face property.
17503 If FACE is an integer, the value string has no text properties.
17504
17505 Optional third and fourth args WINDOW and BUFFER specify the window
17506 and buffer to use as the context for the formatting (defaults
17507 are the selected window and the window's buffer). */)
17508 (format, face, window, buffer)
17509 Lisp_Object format, face, window, buffer;
17510 {
17511 struct it it;
17512 int len;
17513 struct window *w;
17514 struct buffer *old_buffer = NULL;
17515 int face_id = -1;
17516 int no_props = INTEGERP (face);
17517 int count = SPECPDL_INDEX ();
17518 Lisp_Object str;
17519 int string_start = 0;
17520
17521 if (NILP (window))
17522 window = selected_window;
17523 CHECK_WINDOW (window);
17524 w = XWINDOW (window);
17525
17526 if (NILP (buffer))
17527 buffer = w->buffer;
17528 CHECK_BUFFER (buffer);
17529
17530 if (NILP (format))
17531 return empty_unibyte_string;
17532
17533 if (no_props)
17534 face = Qnil;
17535
17536 if (!NILP (face))
17537 {
17538 if (EQ (face, Qt))
17539 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
17540 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
17541 }
17542
17543 if (face_id < 0)
17544 face_id = DEFAULT_FACE_ID;
17545
17546 if (XBUFFER (buffer) != current_buffer)
17547 old_buffer = current_buffer;
17548
17549 /* Save things including mode_line_proptrans_alist,
17550 and set that to nil so that we don't alter the outer value. */
17551 record_unwind_protect (unwind_format_mode_line,
17552 format_mode_line_unwind_data (old_buffer, 1));
17553 mode_line_proptrans_alist = Qnil;
17554
17555 if (old_buffer)
17556 set_buffer_internal_1 (XBUFFER (buffer));
17557
17558 init_iterator (&it, w, -1, -1, NULL, face_id);
17559
17560 if (no_props)
17561 {
17562 mode_line_target = MODE_LINE_NOPROP;
17563 mode_line_string_face_prop = Qnil;
17564 mode_line_string_list = Qnil;
17565 string_start = MODE_LINE_NOPROP_LEN (0);
17566 }
17567 else
17568 {
17569 mode_line_target = MODE_LINE_STRING;
17570 mode_line_string_list = Qnil;
17571 mode_line_string_face = face;
17572 mode_line_string_face_prop
17573 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
17574 }
17575
17576 push_kboard (FRAME_KBOARD (it.f));
17577 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
17578 pop_kboard ();
17579
17580 if (no_props)
17581 {
17582 len = MODE_LINE_NOPROP_LEN (string_start);
17583 str = make_string (mode_line_noprop_buf + string_start, len);
17584 }
17585 else
17586 {
17587 mode_line_string_list = Fnreverse (mode_line_string_list);
17588 str = Fmapconcat (intern ("identity"), mode_line_string_list,
17589 empty_unibyte_string);
17590 }
17591
17592 unbind_to (count, Qnil);
17593 return str;
17594 }
17595
17596 /* Write a null-terminated, right justified decimal representation of
17597 the positive integer D to BUF using a minimal field width WIDTH. */
17598
17599 static void
17600 pint2str (buf, width, d)
17601 register char *buf;
17602 register int width;
17603 register int d;
17604 {
17605 register char *p = buf;
17606
17607 if (d <= 0)
17608 *p++ = '0';
17609 else
17610 {
17611 while (d > 0)
17612 {
17613 *p++ = d % 10 + '0';
17614 d /= 10;
17615 }
17616 }
17617
17618 for (width -= (int) (p - buf); width > 0; --width)
17619 *p++ = ' ';
17620 *p-- = '\0';
17621 while (p > buf)
17622 {
17623 d = *buf;
17624 *buf++ = *p;
17625 *p-- = d;
17626 }
17627 }
17628
17629 /* Write a null-terminated, right justified decimal and "human
17630 readable" representation of the nonnegative integer D to BUF using
17631 a minimal field width WIDTH. D should be smaller than 999.5e24. */
17632
17633 static const char power_letter[] =
17634 {
17635 0, /* not used */
17636 'k', /* kilo */
17637 'M', /* mega */
17638 'G', /* giga */
17639 'T', /* tera */
17640 'P', /* peta */
17641 'E', /* exa */
17642 'Z', /* zetta */
17643 'Y' /* yotta */
17644 };
17645
17646 static void
17647 pint2hrstr (buf, width, d)
17648 char *buf;
17649 int width;
17650 int d;
17651 {
17652 /* We aim to represent the nonnegative integer D as
17653 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
17654 int quotient = d;
17655 int remainder = 0;
17656 /* -1 means: do not use TENTHS. */
17657 int tenths = -1;
17658 int exponent = 0;
17659
17660 /* Length of QUOTIENT.TENTHS as a string. */
17661 int length;
17662
17663 char * psuffix;
17664 char * p;
17665
17666 if (1000 <= quotient)
17667 {
17668 /* Scale to the appropriate EXPONENT. */
17669 do
17670 {
17671 remainder = quotient % 1000;
17672 quotient /= 1000;
17673 exponent++;
17674 }
17675 while (1000 <= quotient);
17676
17677 /* Round to nearest and decide whether to use TENTHS or not. */
17678 if (quotient <= 9)
17679 {
17680 tenths = remainder / 100;
17681 if (50 <= remainder % 100)
17682 {
17683 if (tenths < 9)
17684 tenths++;
17685 else
17686 {
17687 quotient++;
17688 if (quotient == 10)
17689 tenths = -1;
17690 else
17691 tenths = 0;
17692 }
17693 }
17694 }
17695 else
17696 if (500 <= remainder)
17697 {
17698 if (quotient < 999)
17699 quotient++;
17700 else
17701 {
17702 quotient = 1;
17703 exponent++;
17704 tenths = 0;
17705 }
17706 }
17707 }
17708
17709 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
17710 if (tenths == -1 && quotient <= 99)
17711 if (quotient <= 9)
17712 length = 1;
17713 else
17714 length = 2;
17715 else
17716 length = 3;
17717 p = psuffix = buf + max (width, length);
17718
17719 /* Print EXPONENT. */
17720 if (exponent)
17721 *psuffix++ = power_letter[exponent];
17722 *psuffix = '\0';
17723
17724 /* Print TENTHS. */
17725 if (tenths >= 0)
17726 {
17727 *--p = '0' + tenths;
17728 *--p = '.';
17729 }
17730
17731 /* Print QUOTIENT. */
17732 do
17733 {
17734 int digit = quotient % 10;
17735 *--p = '0' + digit;
17736 }
17737 while ((quotient /= 10) != 0);
17738
17739 /* Print leading spaces. */
17740 while (buf < p)
17741 *--p = ' ';
17742 }
17743
17744 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
17745 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
17746 type of CODING_SYSTEM. Return updated pointer into BUF. */
17747
17748 static unsigned char invalid_eol_type[] = "(*invalid*)";
17749
17750 static char *
17751 decode_mode_spec_coding (coding_system, buf, eol_flag)
17752 Lisp_Object coding_system;
17753 register char *buf;
17754 int eol_flag;
17755 {
17756 Lisp_Object val;
17757 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
17758 const unsigned char *eol_str;
17759 int eol_str_len;
17760 /* The EOL conversion we are using. */
17761 Lisp_Object eoltype;
17762
17763 val = CODING_SYSTEM_SPEC (coding_system);
17764 eoltype = Qnil;
17765
17766 if (!VECTORP (val)) /* Not yet decided. */
17767 {
17768 if (multibyte)
17769 *buf++ = '-';
17770 if (eol_flag)
17771 eoltype = eol_mnemonic_undecided;
17772 /* Don't mention EOL conversion if it isn't decided. */
17773 }
17774 else
17775 {
17776 Lisp_Object attrs;
17777 Lisp_Object eolvalue;
17778
17779 attrs = AREF (val, 0);
17780 eolvalue = AREF (val, 2);
17781
17782 if (multibyte)
17783 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
17784
17785 if (eol_flag)
17786 {
17787 /* The EOL conversion that is normal on this system. */
17788
17789 if (NILP (eolvalue)) /* Not yet decided. */
17790 eoltype = eol_mnemonic_undecided;
17791 else if (VECTORP (eolvalue)) /* Not yet decided. */
17792 eoltype = eol_mnemonic_undecided;
17793 else /* eolvalue is Qunix, Qdos, or Qmac. */
17794 eoltype = (EQ (eolvalue, Qunix)
17795 ? eol_mnemonic_unix
17796 : (EQ (eolvalue, Qdos) == 1
17797 ? eol_mnemonic_dos : eol_mnemonic_mac));
17798 }
17799 }
17800
17801 if (eol_flag)
17802 {
17803 /* Mention the EOL conversion if it is not the usual one. */
17804 if (STRINGP (eoltype))
17805 {
17806 eol_str = SDATA (eoltype);
17807 eol_str_len = SBYTES (eoltype);
17808 }
17809 else if (CHARACTERP (eoltype))
17810 {
17811 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
17812 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
17813 eol_str = tmp;
17814 }
17815 else
17816 {
17817 eol_str = invalid_eol_type;
17818 eol_str_len = sizeof (invalid_eol_type) - 1;
17819 }
17820 bcopy (eol_str, buf, eol_str_len);
17821 buf += eol_str_len;
17822 }
17823
17824 return buf;
17825 }
17826
17827 /* Return a string for the output of a mode line %-spec for window W,
17828 generated by character C. PRECISION >= 0 means don't return a
17829 string longer than that value. FIELD_WIDTH > 0 means pad the
17830 string returned with spaces to that value. Return 1 in *MULTIBYTE
17831 if the result is multibyte text.
17832
17833 Note we operate on the current buffer for most purposes,
17834 the exception being w->base_line_pos. */
17835
17836 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
17837
17838 static char *
17839 decode_mode_spec (w, c, field_width, precision, multibyte)
17840 struct window *w;
17841 register int c;
17842 int field_width, precision;
17843 int *multibyte;
17844 {
17845 Lisp_Object obj;
17846 struct frame *f = XFRAME (WINDOW_FRAME (w));
17847 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
17848 struct buffer *b = current_buffer;
17849
17850 obj = Qnil;
17851 *multibyte = 0;
17852
17853 switch (c)
17854 {
17855 case '*':
17856 if (!NILP (b->read_only))
17857 return "%";
17858 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17859 return "*";
17860 return "-";
17861
17862 case '+':
17863 /* This differs from %* only for a modified read-only buffer. */
17864 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17865 return "*";
17866 if (!NILP (b->read_only))
17867 return "%";
17868 return "-";
17869
17870 case '&':
17871 /* This differs from %* in ignoring read-only-ness. */
17872 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17873 return "*";
17874 return "-";
17875
17876 case '%':
17877 return "%";
17878
17879 case '[':
17880 {
17881 int i;
17882 char *p;
17883
17884 if (command_loop_level > 5)
17885 return "[[[... ";
17886 p = decode_mode_spec_buf;
17887 for (i = 0; i < command_loop_level; i++)
17888 *p++ = '[';
17889 *p = 0;
17890 return decode_mode_spec_buf;
17891 }
17892
17893 case ']':
17894 {
17895 int i;
17896 char *p;
17897
17898 if (command_loop_level > 5)
17899 return " ...]]]";
17900 p = decode_mode_spec_buf;
17901 for (i = 0; i < command_loop_level; i++)
17902 *p++ = ']';
17903 *p = 0;
17904 return decode_mode_spec_buf;
17905 }
17906
17907 case '-':
17908 {
17909 register int i;
17910
17911 /* Let lots_of_dashes be a string of infinite length. */
17912 if (mode_line_target == MODE_LINE_NOPROP ||
17913 mode_line_target == MODE_LINE_STRING)
17914 return "--";
17915 if (field_width <= 0
17916 || field_width > sizeof (lots_of_dashes))
17917 {
17918 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
17919 decode_mode_spec_buf[i] = '-';
17920 decode_mode_spec_buf[i] = '\0';
17921 return decode_mode_spec_buf;
17922 }
17923 else
17924 return lots_of_dashes;
17925 }
17926
17927 case 'b':
17928 obj = b->name;
17929 break;
17930
17931 case 'c':
17932 /* %c and %l are ignored in `frame-title-format'.
17933 (In redisplay_internal, the frame title is drawn _before_ the
17934 windows are updated, so the stuff which depends on actual
17935 window contents (such as %l) may fail to render properly, or
17936 even crash emacs.) */
17937 if (mode_line_target == MODE_LINE_TITLE)
17938 return "";
17939 else
17940 {
17941 int col = (int) current_column (); /* iftc */
17942 w->column_number_displayed = make_number (col);
17943 pint2str (decode_mode_spec_buf, field_width, col);
17944 return decode_mode_spec_buf;
17945 }
17946
17947 case 'e':
17948 #ifndef SYSTEM_MALLOC
17949 {
17950 if (NILP (Vmemory_full))
17951 return "";
17952 else
17953 return "!MEM FULL! ";
17954 }
17955 #else
17956 return "";
17957 #endif
17958
17959 case 'F':
17960 /* %F displays the frame name. */
17961 if (!NILP (f->title))
17962 return (char *) SDATA (f->title);
17963 if (f->explicit_name || ! FRAME_WINDOW_P (f))
17964 return (char *) SDATA (f->name);
17965 return "Emacs";
17966
17967 case 'f':
17968 obj = b->filename;
17969 break;
17970
17971 case 'i':
17972 {
17973 int size = ZV - BEGV;
17974 pint2str (decode_mode_spec_buf, field_width, size);
17975 return decode_mode_spec_buf;
17976 }
17977
17978 case 'I':
17979 {
17980 int size = ZV - BEGV;
17981 pint2hrstr (decode_mode_spec_buf, field_width, size);
17982 return decode_mode_spec_buf;
17983 }
17984
17985 case 'l':
17986 {
17987 int startpos, startpos_byte, line, linepos, linepos_byte;
17988 int topline, nlines, junk, height;
17989
17990 /* %c and %l are ignored in `frame-title-format'. */
17991 if (mode_line_target == MODE_LINE_TITLE)
17992 return "";
17993
17994 startpos = XMARKER (w->start)->charpos;
17995 startpos_byte = marker_byte_position (w->start);
17996 height = WINDOW_TOTAL_LINES (w);
17997
17998 /* If we decided that this buffer isn't suitable for line numbers,
17999 don't forget that too fast. */
18000 if (EQ (w->base_line_pos, w->buffer))
18001 goto no_value;
18002 /* But do forget it, if the window shows a different buffer now. */
18003 else if (BUFFERP (w->base_line_pos))
18004 w->base_line_pos = Qnil;
18005
18006 /* If the buffer is very big, don't waste time. */
18007 if (INTEGERP (Vline_number_display_limit)
18008 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
18009 {
18010 w->base_line_pos = Qnil;
18011 w->base_line_number = Qnil;
18012 goto no_value;
18013 }
18014
18015 if (!NILP (w->base_line_number)
18016 && !NILP (w->base_line_pos)
18017 && XFASTINT (w->base_line_pos) <= startpos)
18018 {
18019 line = XFASTINT (w->base_line_number);
18020 linepos = XFASTINT (w->base_line_pos);
18021 linepos_byte = buf_charpos_to_bytepos (b, linepos);
18022 }
18023 else
18024 {
18025 line = 1;
18026 linepos = BUF_BEGV (b);
18027 linepos_byte = BUF_BEGV_BYTE (b);
18028 }
18029
18030 /* Count lines from base line to window start position. */
18031 nlines = display_count_lines (linepos, linepos_byte,
18032 startpos_byte,
18033 startpos, &junk);
18034
18035 topline = nlines + line;
18036
18037 /* Determine a new base line, if the old one is too close
18038 or too far away, or if we did not have one.
18039 "Too close" means it's plausible a scroll-down would
18040 go back past it. */
18041 if (startpos == BUF_BEGV (b))
18042 {
18043 w->base_line_number = make_number (topline);
18044 w->base_line_pos = make_number (BUF_BEGV (b));
18045 }
18046 else if (nlines < height + 25 || nlines > height * 3 + 50
18047 || linepos == BUF_BEGV (b))
18048 {
18049 int limit = BUF_BEGV (b);
18050 int limit_byte = BUF_BEGV_BYTE (b);
18051 int position;
18052 int distance = (height * 2 + 30) * line_number_display_limit_width;
18053
18054 if (startpos - distance > limit)
18055 {
18056 limit = startpos - distance;
18057 limit_byte = CHAR_TO_BYTE (limit);
18058 }
18059
18060 nlines = display_count_lines (startpos, startpos_byte,
18061 limit_byte,
18062 - (height * 2 + 30),
18063 &position);
18064 /* If we couldn't find the lines we wanted within
18065 line_number_display_limit_width chars per line,
18066 give up on line numbers for this window. */
18067 if (position == limit_byte && limit == startpos - distance)
18068 {
18069 w->base_line_pos = w->buffer;
18070 w->base_line_number = Qnil;
18071 goto no_value;
18072 }
18073
18074 w->base_line_number = make_number (topline - nlines);
18075 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
18076 }
18077
18078 /* Now count lines from the start pos to point. */
18079 nlines = display_count_lines (startpos, startpos_byte,
18080 PT_BYTE, PT, &junk);
18081
18082 /* Record that we did display the line number. */
18083 line_number_displayed = 1;
18084
18085 /* Make the string to show. */
18086 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
18087 return decode_mode_spec_buf;
18088 no_value:
18089 {
18090 char* p = decode_mode_spec_buf;
18091 int pad = field_width - 2;
18092 while (pad-- > 0)
18093 *p++ = ' ';
18094 *p++ = '?';
18095 *p++ = '?';
18096 *p = '\0';
18097 return decode_mode_spec_buf;
18098 }
18099 }
18100 break;
18101
18102 case 'm':
18103 obj = b->mode_name;
18104 break;
18105
18106 case 'n':
18107 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
18108 return " Narrow";
18109 break;
18110
18111 case 'p':
18112 {
18113 int pos = marker_position (w->start);
18114 int total = BUF_ZV (b) - BUF_BEGV (b);
18115
18116 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
18117 {
18118 if (pos <= BUF_BEGV (b))
18119 return "All";
18120 else
18121 return "Bottom";
18122 }
18123 else if (pos <= BUF_BEGV (b))
18124 return "Top";
18125 else
18126 {
18127 if (total > 1000000)
18128 /* Do it differently for a large value, to avoid overflow. */
18129 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18130 else
18131 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
18132 /* We can't normally display a 3-digit number,
18133 so get us a 2-digit number that is close. */
18134 if (total == 100)
18135 total = 99;
18136 sprintf (decode_mode_spec_buf, "%2d%%", total);
18137 return decode_mode_spec_buf;
18138 }
18139 }
18140
18141 /* Display percentage of size above the bottom of the screen. */
18142 case 'P':
18143 {
18144 int toppos = marker_position (w->start);
18145 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
18146 int total = BUF_ZV (b) - BUF_BEGV (b);
18147
18148 if (botpos >= BUF_ZV (b))
18149 {
18150 if (toppos <= BUF_BEGV (b))
18151 return "All";
18152 else
18153 return "Bottom";
18154 }
18155 else
18156 {
18157 if (total > 1000000)
18158 /* Do it differently for a large value, to avoid overflow. */
18159 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18160 else
18161 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
18162 /* We can't normally display a 3-digit number,
18163 so get us a 2-digit number that is close. */
18164 if (total == 100)
18165 total = 99;
18166 if (toppos <= BUF_BEGV (b))
18167 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
18168 else
18169 sprintf (decode_mode_spec_buf, "%2d%%", total);
18170 return decode_mode_spec_buf;
18171 }
18172 }
18173
18174 case 's':
18175 /* status of process */
18176 obj = Fget_buffer_process (Fcurrent_buffer ());
18177 if (NILP (obj))
18178 return "no process";
18179 #ifdef subprocesses
18180 obj = Fsymbol_name (Fprocess_status (obj));
18181 #endif
18182 break;
18183
18184 case '@':
18185 {
18186 Lisp_Object val;
18187 val = call1 (intern ("file-remote-p"), current_buffer->directory);
18188 if (NILP (val))
18189 return "-";
18190 else
18191 return "@";
18192 }
18193
18194 case 't': /* indicate TEXT or BINARY */
18195 #ifdef MODE_LINE_BINARY_TEXT
18196 return MODE_LINE_BINARY_TEXT (b);
18197 #else
18198 return "T";
18199 #endif
18200
18201 case 'z':
18202 /* coding-system (not including end-of-line format) */
18203 case 'Z':
18204 /* coding-system (including end-of-line type) */
18205 {
18206 int eol_flag = (c == 'Z');
18207 char *p = decode_mode_spec_buf;
18208
18209 if (! FRAME_WINDOW_P (f))
18210 {
18211 /* No need to mention EOL here--the terminal never needs
18212 to do EOL conversion. */
18213 p = decode_mode_spec_coding (CODING_ID_NAME
18214 (FRAME_KEYBOARD_CODING (f)->id),
18215 p, 0);
18216 p = decode_mode_spec_coding (CODING_ID_NAME
18217 (FRAME_TERMINAL_CODING (f)->id),
18218 p, 0);
18219 }
18220 p = decode_mode_spec_coding (b->buffer_file_coding_system,
18221 p, eol_flag);
18222
18223 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
18224 #ifdef subprocesses
18225 obj = Fget_buffer_process (Fcurrent_buffer ());
18226 if (PROCESSP (obj))
18227 {
18228 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
18229 p, eol_flag);
18230 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
18231 p, eol_flag);
18232 }
18233 #endif /* subprocesses */
18234 #endif /* 0 */
18235 *p = 0;
18236 return decode_mode_spec_buf;
18237 }
18238 }
18239
18240 if (STRINGP (obj))
18241 {
18242 *multibyte = STRING_MULTIBYTE (obj);
18243 return (char *) SDATA (obj);
18244 }
18245 else
18246 return "";
18247 }
18248
18249
18250 /* Count up to COUNT lines starting from START / START_BYTE.
18251 But don't go beyond LIMIT_BYTE.
18252 Return the number of lines thus found (always nonnegative).
18253
18254 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
18255
18256 static int
18257 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
18258 int start, start_byte, limit_byte, count;
18259 int *byte_pos_ptr;
18260 {
18261 register unsigned char *cursor;
18262 unsigned char *base;
18263
18264 register int ceiling;
18265 register unsigned char *ceiling_addr;
18266 int orig_count = count;
18267
18268 /* If we are not in selective display mode,
18269 check only for newlines. */
18270 int selective_display = (!NILP (current_buffer->selective_display)
18271 && !INTEGERP (current_buffer->selective_display));
18272
18273 if (count > 0)
18274 {
18275 while (start_byte < limit_byte)
18276 {
18277 ceiling = BUFFER_CEILING_OF (start_byte);
18278 ceiling = min (limit_byte - 1, ceiling);
18279 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
18280 base = (cursor = BYTE_POS_ADDR (start_byte));
18281 while (1)
18282 {
18283 if (selective_display)
18284 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
18285 ;
18286 else
18287 while (*cursor != '\n' && ++cursor != ceiling_addr)
18288 ;
18289
18290 if (cursor != ceiling_addr)
18291 {
18292 if (--count == 0)
18293 {
18294 start_byte += cursor - base + 1;
18295 *byte_pos_ptr = start_byte;
18296 return orig_count;
18297 }
18298 else
18299 if (++cursor == ceiling_addr)
18300 break;
18301 }
18302 else
18303 break;
18304 }
18305 start_byte += cursor - base;
18306 }
18307 }
18308 else
18309 {
18310 while (start_byte > limit_byte)
18311 {
18312 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
18313 ceiling = max (limit_byte, ceiling);
18314 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
18315 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
18316 while (1)
18317 {
18318 if (selective_display)
18319 while (--cursor != ceiling_addr
18320 && *cursor != '\n' && *cursor != 015)
18321 ;
18322 else
18323 while (--cursor != ceiling_addr && *cursor != '\n')
18324 ;
18325
18326 if (cursor != ceiling_addr)
18327 {
18328 if (++count == 0)
18329 {
18330 start_byte += cursor - base + 1;
18331 *byte_pos_ptr = start_byte;
18332 /* When scanning backwards, we should
18333 not count the newline posterior to which we stop. */
18334 return - orig_count - 1;
18335 }
18336 }
18337 else
18338 break;
18339 }
18340 /* Here we add 1 to compensate for the last decrement
18341 of CURSOR, which took it past the valid range. */
18342 start_byte += cursor - base + 1;
18343 }
18344 }
18345
18346 *byte_pos_ptr = limit_byte;
18347
18348 if (count < 0)
18349 return - orig_count + count;
18350 return orig_count - count;
18351
18352 }
18353
18354
18355 \f
18356 /***********************************************************************
18357 Displaying strings
18358 ***********************************************************************/
18359
18360 /* Display a NUL-terminated string, starting with index START.
18361
18362 If STRING is non-null, display that C string. Otherwise, the Lisp
18363 string LISP_STRING is displayed.
18364
18365 If FACE_STRING is not nil, FACE_STRING_POS is a position in
18366 FACE_STRING. Display STRING or LISP_STRING with the face at
18367 FACE_STRING_POS in FACE_STRING:
18368
18369 Display the string in the environment given by IT, but use the
18370 standard display table, temporarily.
18371
18372 FIELD_WIDTH is the minimum number of output glyphs to produce.
18373 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18374 with spaces. If STRING has more characters, more than FIELD_WIDTH
18375 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
18376
18377 PRECISION is the maximum number of characters to output from
18378 STRING. PRECISION < 0 means don't truncate the string.
18379
18380 This is roughly equivalent to printf format specifiers:
18381
18382 FIELD_WIDTH PRECISION PRINTF
18383 ----------------------------------------
18384 -1 -1 %s
18385 -1 10 %.10s
18386 10 -1 %10s
18387 20 10 %20.10s
18388
18389 MULTIBYTE zero means do not display multibyte chars, > 0 means do
18390 display them, and < 0 means obey the current buffer's value of
18391 enable_multibyte_characters.
18392
18393 Value is the number of columns displayed. */
18394
18395 static int
18396 display_string (string, lisp_string, face_string, face_string_pos,
18397 start, it, field_width, precision, max_x, multibyte)
18398 unsigned char *string;
18399 Lisp_Object lisp_string;
18400 Lisp_Object face_string;
18401 int face_string_pos;
18402 int start;
18403 struct it *it;
18404 int field_width, precision, max_x;
18405 int multibyte;
18406 {
18407 int hpos_at_start = it->hpos;
18408 int saved_face_id = it->face_id;
18409 struct glyph_row *row = it->glyph_row;
18410
18411 /* Initialize the iterator IT for iteration over STRING beginning
18412 with index START. */
18413 reseat_to_string (it, string, lisp_string, start,
18414 precision, field_width, multibyte);
18415
18416 /* If displaying STRING, set up the face of the iterator
18417 from LISP_STRING, if that's given. */
18418 if (STRINGP (face_string))
18419 {
18420 int endptr;
18421 struct face *face;
18422
18423 it->face_id
18424 = face_at_string_position (it->w, face_string, face_string_pos,
18425 0, it->region_beg_charpos,
18426 it->region_end_charpos,
18427 &endptr, it->base_face_id, 0);
18428 face = FACE_FROM_ID (it->f, it->face_id);
18429 it->face_box_p = face->box != FACE_NO_BOX;
18430 }
18431
18432 /* Set max_x to the maximum allowed X position. Don't let it go
18433 beyond the right edge of the window. */
18434 if (max_x <= 0)
18435 max_x = it->last_visible_x;
18436 else
18437 max_x = min (max_x, it->last_visible_x);
18438
18439 /* Skip over display elements that are not visible. because IT->w is
18440 hscrolled. */
18441 if (it->current_x < it->first_visible_x)
18442 move_it_in_display_line_to (it, 100000, it->first_visible_x,
18443 MOVE_TO_POS | MOVE_TO_X);
18444
18445 row->ascent = it->max_ascent;
18446 row->height = it->max_ascent + it->max_descent;
18447 row->phys_ascent = it->max_phys_ascent;
18448 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18449 row->extra_line_spacing = it->max_extra_line_spacing;
18450
18451 /* This condition is for the case that we are called with current_x
18452 past last_visible_x. */
18453 while (it->current_x < max_x)
18454 {
18455 int x_before, x, n_glyphs_before, i, nglyphs;
18456
18457 /* Get the next display element. */
18458 if (!get_next_display_element (it))
18459 break;
18460
18461 /* Produce glyphs. */
18462 x_before = it->current_x;
18463 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
18464 PRODUCE_GLYPHS (it);
18465
18466 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
18467 i = 0;
18468 x = x_before;
18469 while (i < nglyphs)
18470 {
18471 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18472
18473 if (!it->truncate_lines_p
18474 && x + glyph->pixel_width > max_x)
18475 {
18476 /* End of continued line or max_x reached. */
18477 if (CHAR_GLYPH_PADDING_P (*glyph))
18478 {
18479 /* A wide character is unbreakable. */
18480 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
18481 it->current_x = x_before;
18482 }
18483 else
18484 {
18485 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
18486 it->current_x = x;
18487 }
18488 break;
18489 }
18490 else if (x + glyph->pixel_width >= it->first_visible_x)
18491 {
18492 /* Glyph is at least partially visible. */
18493 ++it->hpos;
18494 if (x < it->first_visible_x)
18495 it->glyph_row->x = x - it->first_visible_x;
18496 }
18497 else
18498 {
18499 /* Glyph is off the left margin of the display area.
18500 Should not happen. */
18501 abort ();
18502 }
18503
18504 row->ascent = max (row->ascent, it->max_ascent);
18505 row->height = max (row->height, it->max_ascent + it->max_descent);
18506 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18507 row->phys_height = max (row->phys_height,
18508 it->max_phys_ascent + it->max_phys_descent);
18509 row->extra_line_spacing = max (row->extra_line_spacing,
18510 it->max_extra_line_spacing);
18511 x += glyph->pixel_width;
18512 ++i;
18513 }
18514
18515 /* Stop if max_x reached. */
18516 if (i < nglyphs)
18517 break;
18518
18519 /* Stop at line ends. */
18520 if (ITERATOR_AT_END_OF_LINE_P (it))
18521 {
18522 it->continuation_lines_width = 0;
18523 break;
18524 }
18525
18526 set_iterator_to_next (it, 1);
18527
18528 /* Stop if truncating at the right edge. */
18529 if (it->truncate_lines_p
18530 && it->current_x >= it->last_visible_x)
18531 {
18532 /* Add truncation mark, but don't do it if the line is
18533 truncated at a padding space. */
18534 if (IT_CHARPOS (*it) < it->string_nchars)
18535 {
18536 if (!FRAME_WINDOW_P (it->f))
18537 {
18538 int i, n;
18539
18540 if (it->current_x > it->last_visible_x)
18541 {
18542 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
18543 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18544 break;
18545 for (n = row->used[TEXT_AREA]; i < n; ++i)
18546 {
18547 row->used[TEXT_AREA] = i;
18548 produce_special_glyphs (it, IT_TRUNCATION);
18549 }
18550 }
18551 produce_special_glyphs (it, IT_TRUNCATION);
18552 }
18553 it->glyph_row->truncated_on_right_p = 1;
18554 }
18555 break;
18556 }
18557 }
18558
18559 /* Maybe insert a truncation at the left. */
18560 if (it->first_visible_x
18561 && IT_CHARPOS (*it) > 0)
18562 {
18563 if (!FRAME_WINDOW_P (it->f))
18564 insert_left_trunc_glyphs (it);
18565 it->glyph_row->truncated_on_left_p = 1;
18566 }
18567
18568 it->face_id = saved_face_id;
18569
18570 /* Value is number of columns displayed. */
18571 return it->hpos - hpos_at_start;
18572 }
18573
18574
18575 \f
18576 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
18577 appears as an element of LIST or as the car of an element of LIST.
18578 If PROPVAL is a list, compare each element against LIST in that
18579 way, and return 1/2 if any element of PROPVAL is found in LIST.
18580 Otherwise return 0. This function cannot quit.
18581 The return value is 2 if the text is invisible but with an ellipsis
18582 and 1 if it's invisible and without an ellipsis. */
18583
18584 int
18585 invisible_p (propval, list)
18586 register Lisp_Object propval;
18587 Lisp_Object list;
18588 {
18589 register Lisp_Object tail, proptail;
18590
18591 for (tail = list; CONSP (tail); tail = XCDR (tail))
18592 {
18593 register Lisp_Object tem;
18594 tem = XCAR (tail);
18595 if (EQ (propval, tem))
18596 return 1;
18597 if (CONSP (tem) && EQ (propval, XCAR (tem)))
18598 return NILP (XCDR (tem)) ? 1 : 2;
18599 }
18600
18601 if (CONSP (propval))
18602 {
18603 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
18604 {
18605 Lisp_Object propelt;
18606 propelt = XCAR (proptail);
18607 for (tail = list; CONSP (tail); tail = XCDR (tail))
18608 {
18609 register Lisp_Object tem;
18610 tem = XCAR (tail);
18611 if (EQ (propelt, tem))
18612 return 1;
18613 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
18614 return NILP (XCDR (tem)) ? 1 : 2;
18615 }
18616 }
18617 }
18618
18619 return 0;
18620 }
18621
18622 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
18623 doc: /* Non-nil if the property makes the text invisible.
18624 POS-OR-PROP can be a marker or number, in which case it is taken to be
18625 a position in the current buffer and the value of the `invisible' property
18626 is checked; or it can be some other value, which is then presumed to be the
18627 value of the `invisible' property of the text of interest.
18628 The non-nil value returned can be t for truly invisible text or something
18629 else if the text is replaced by an ellipsis. */)
18630 (pos_or_prop)
18631 Lisp_Object pos_or_prop;
18632 {
18633 Lisp_Object prop
18634 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
18635 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
18636 : pos_or_prop);
18637 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
18638 return (invis == 0 ? Qnil
18639 : invis == 1 ? Qt
18640 : make_number (invis));
18641 }
18642
18643 /* Calculate a width or height in pixels from a specification using
18644 the following elements:
18645
18646 SPEC ::=
18647 NUM - a (fractional) multiple of the default font width/height
18648 (NUM) - specifies exactly NUM pixels
18649 UNIT - a fixed number of pixels, see below.
18650 ELEMENT - size of a display element in pixels, see below.
18651 (NUM . SPEC) - equals NUM * SPEC
18652 (+ SPEC SPEC ...) - add pixel values
18653 (- SPEC SPEC ...) - subtract pixel values
18654 (- SPEC) - negate pixel value
18655
18656 NUM ::=
18657 INT or FLOAT - a number constant
18658 SYMBOL - use symbol's (buffer local) variable binding.
18659
18660 UNIT ::=
18661 in - pixels per inch *)
18662 mm - pixels per 1/1000 meter *)
18663 cm - pixels per 1/100 meter *)
18664 width - width of current font in pixels.
18665 height - height of current font in pixels.
18666
18667 *) using the ratio(s) defined in display-pixels-per-inch.
18668
18669 ELEMENT ::=
18670
18671 left-fringe - left fringe width in pixels
18672 right-fringe - right fringe width in pixels
18673
18674 left-margin - left margin width in pixels
18675 right-margin - right margin width in pixels
18676
18677 scroll-bar - scroll-bar area width in pixels
18678
18679 Examples:
18680
18681 Pixels corresponding to 5 inches:
18682 (5 . in)
18683
18684 Total width of non-text areas on left side of window (if scroll-bar is on left):
18685 '(space :width (+ left-fringe left-margin scroll-bar))
18686
18687 Align to first text column (in header line):
18688 '(space :align-to 0)
18689
18690 Align to middle of text area minus half the width of variable `my-image'
18691 containing a loaded image:
18692 '(space :align-to (0.5 . (- text my-image)))
18693
18694 Width of left margin minus width of 1 character in the default font:
18695 '(space :width (- left-margin 1))
18696
18697 Width of left margin minus width of 2 characters in the current font:
18698 '(space :width (- left-margin (2 . width)))
18699
18700 Center 1 character over left-margin (in header line):
18701 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
18702
18703 Different ways to express width of left fringe plus left margin minus one pixel:
18704 '(space :width (- (+ left-fringe left-margin) (1)))
18705 '(space :width (+ left-fringe left-margin (- (1))))
18706 '(space :width (+ left-fringe left-margin (-1)))
18707
18708 */
18709
18710 #define NUMVAL(X) \
18711 ((INTEGERP (X) || FLOATP (X)) \
18712 ? XFLOATINT (X) \
18713 : - 1)
18714
18715 int
18716 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
18717 double *res;
18718 struct it *it;
18719 Lisp_Object prop;
18720 void *font;
18721 int width_p, *align_to;
18722 {
18723 double pixels;
18724
18725 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
18726 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
18727
18728 if (NILP (prop))
18729 return OK_PIXELS (0);
18730
18731 xassert (FRAME_LIVE_P (it->f));
18732
18733 if (SYMBOLP (prop))
18734 {
18735 if (SCHARS (SYMBOL_NAME (prop)) == 2)
18736 {
18737 char *unit = SDATA (SYMBOL_NAME (prop));
18738
18739 if (unit[0] == 'i' && unit[1] == 'n')
18740 pixels = 1.0;
18741 else if (unit[0] == 'm' && unit[1] == 'm')
18742 pixels = 25.4;
18743 else if (unit[0] == 'c' && unit[1] == 'm')
18744 pixels = 2.54;
18745 else
18746 pixels = 0;
18747 if (pixels > 0)
18748 {
18749 double ppi;
18750 #ifdef HAVE_WINDOW_SYSTEM
18751 if (FRAME_WINDOW_P (it->f)
18752 && (ppi = (width_p
18753 ? FRAME_X_DISPLAY_INFO (it->f)->resx
18754 : FRAME_X_DISPLAY_INFO (it->f)->resy),
18755 ppi > 0))
18756 return OK_PIXELS (ppi / pixels);
18757 #endif
18758
18759 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
18760 || (CONSP (Vdisplay_pixels_per_inch)
18761 && (ppi = (width_p
18762 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
18763 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
18764 ppi > 0)))
18765 return OK_PIXELS (ppi / pixels);
18766
18767 return 0;
18768 }
18769 }
18770
18771 #ifdef HAVE_WINDOW_SYSTEM
18772 if (EQ (prop, Qheight))
18773 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
18774 if (EQ (prop, Qwidth))
18775 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
18776 #else
18777 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
18778 return OK_PIXELS (1);
18779 #endif
18780
18781 if (EQ (prop, Qtext))
18782 return OK_PIXELS (width_p
18783 ? window_box_width (it->w, TEXT_AREA)
18784 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
18785
18786 if (align_to && *align_to < 0)
18787 {
18788 *res = 0;
18789 if (EQ (prop, Qleft))
18790 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
18791 if (EQ (prop, Qright))
18792 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
18793 if (EQ (prop, Qcenter))
18794 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
18795 + window_box_width (it->w, TEXT_AREA) / 2);
18796 if (EQ (prop, Qleft_fringe))
18797 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18798 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
18799 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
18800 if (EQ (prop, Qright_fringe))
18801 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18802 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18803 : window_box_right_offset (it->w, TEXT_AREA));
18804 if (EQ (prop, Qleft_margin))
18805 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
18806 if (EQ (prop, Qright_margin))
18807 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
18808 if (EQ (prop, Qscroll_bar))
18809 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18810 ? 0
18811 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18812 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18813 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18814 : 0)));
18815 }
18816 else
18817 {
18818 if (EQ (prop, Qleft_fringe))
18819 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
18820 if (EQ (prop, Qright_fringe))
18821 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
18822 if (EQ (prop, Qleft_margin))
18823 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
18824 if (EQ (prop, Qright_margin))
18825 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
18826 if (EQ (prop, Qscroll_bar))
18827 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
18828 }
18829
18830 prop = Fbuffer_local_value (prop, it->w->buffer);
18831 }
18832
18833 if (INTEGERP (prop) || FLOATP (prop))
18834 {
18835 int base_unit = (width_p
18836 ? FRAME_COLUMN_WIDTH (it->f)
18837 : FRAME_LINE_HEIGHT (it->f));
18838 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18839 }
18840
18841 if (CONSP (prop))
18842 {
18843 Lisp_Object car = XCAR (prop);
18844 Lisp_Object cdr = XCDR (prop);
18845
18846 if (SYMBOLP (car))
18847 {
18848 #ifdef HAVE_WINDOW_SYSTEM
18849 if (FRAME_WINDOW_P (it->f)
18850 && valid_image_p (prop))
18851 {
18852 int id = lookup_image (it->f, prop);
18853 struct image *img = IMAGE_FROM_ID (it->f, id);
18854
18855 return OK_PIXELS (width_p ? img->width : img->height);
18856 }
18857 #endif
18858 if (EQ (car, Qplus) || EQ (car, Qminus))
18859 {
18860 int first = 1;
18861 double px;
18862
18863 pixels = 0;
18864 while (CONSP (cdr))
18865 {
18866 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
18867 font, width_p, align_to))
18868 return 0;
18869 if (first)
18870 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18871 else
18872 pixels += px;
18873 cdr = XCDR (cdr);
18874 }
18875 if (EQ (car, Qminus))
18876 pixels = -pixels;
18877 return OK_PIXELS (pixels);
18878 }
18879
18880 car = Fbuffer_local_value (car, it->w->buffer);
18881 }
18882
18883 if (INTEGERP (car) || FLOATP (car))
18884 {
18885 double fact;
18886 pixels = XFLOATINT (car);
18887 if (NILP (cdr))
18888 return OK_PIXELS (pixels);
18889 if (calc_pixel_width_or_height (&fact, it, cdr,
18890 font, width_p, align_to))
18891 return OK_PIXELS (pixels * fact);
18892 return 0;
18893 }
18894
18895 return 0;
18896 }
18897
18898 return 0;
18899 }
18900
18901 \f
18902 /***********************************************************************
18903 Glyph Display
18904 ***********************************************************************/
18905
18906 #ifdef HAVE_WINDOW_SYSTEM
18907
18908 #if GLYPH_DEBUG
18909
18910 void
18911 dump_glyph_string (s)
18912 struct glyph_string *s;
18913 {
18914 fprintf (stderr, "glyph string\n");
18915 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
18916 s->x, s->y, s->width, s->height);
18917 fprintf (stderr, " ybase = %d\n", s->ybase);
18918 fprintf (stderr, " hl = %d\n", s->hl);
18919 fprintf (stderr, " left overhang = %d, right = %d\n",
18920 s->left_overhang, s->right_overhang);
18921 fprintf (stderr, " nchars = %d\n", s->nchars);
18922 fprintf (stderr, " extends to end of line = %d\n",
18923 s->extends_to_end_of_line_p);
18924 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
18925 fprintf (stderr, " bg width = %d\n", s->background_width);
18926 }
18927
18928 #endif /* GLYPH_DEBUG */
18929
18930 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
18931 of XChar2b structures for S; it can't be allocated in
18932 init_glyph_string because it must be allocated via `alloca'. W
18933 is the window on which S is drawn. ROW and AREA are the glyph row
18934 and area within the row from which S is constructed. START is the
18935 index of the first glyph structure covered by S. HL is a
18936 face-override for drawing S. */
18937
18938 #ifdef HAVE_NTGUI
18939 #define OPTIONAL_HDC(hdc) hdc,
18940 #define DECLARE_HDC(hdc) HDC hdc;
18941 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
18942 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
18943 #endif
18944
18945 #ifndef OPTIONAL_HDC
18946 #define OPTIONAL_HDC(hdc)
18947 #define DECLARE_HDC(hdc)
18948 #define ALLOCATE_HDC(hdc, f)
18949 #define RELEASE_HDC(hdc, f)
18950 #endif
18951
18952 static void
18953 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
18954 struct glyph_string *s;
18955 DECLARE_HDC (hdc)
18956 XChar2b *char2b;
18957 struct window *w;
18958 struct glyph_row *row;
18959 enum glyph_row_area area;
18960 int start;
18961 enum draw_glyphs_face hl;
18962 {
18963 bzero (s, sizeof *s);
18964 s->w = w;
18965 s->f = XFRAME (w->frame);
18966 #ifdef HAVE_NTGUI
18967 s->hdc = hdc;
18968 #endif
18969 s->display = FRAME_X_DISPLAY (s->f);
18970 s->window = FRAME_X_WINDOW (s->f);
18971 s->char2b = char2b;
18972 s->hl = hl;
18973 s->row = row;
18974 s->area = area;
18975 s->first_glyph = row->glyphs[area] + start;
18976 s->height = row->height;
18977 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
18978
18979 /* Display the internal border below the tool-bar window. */
18980 if (WINDOWP (s->f->tool_bar_window)
18981 && s->w == XWINDOW (s->f->tool_bar_window))
18982 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
18983
18984 s->ybase = s->y + row->ascent;
18985 }
18986
18987
18988 /* Append the list of glyph strings with head H and tail T to the list
18989 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
18990
18991 static INLINE void
18992 append_glyph_string_lists (head, tail, h, t)
18993 struct glyph_string **head, **tail;
18994 struct glyph_string *h, *t;
18995 {
18996 if (h)
18997 {
18998 if (*head)
18999 (*tail)->next = h;
19000 else
19001 *head = h;
19002 h->prev = *tail;
19003 *tail = t;
19004 }
19005 }
19006
19007
19008 /* Prepend the list of glyph strings with head H and tail T to the
19009 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
19010 result. */
19011
19012 static INLINE void
19013 prepend_glyph_string_lists (head, tail, h, t)
19014 struct glyph_string **head, **tail;
19015 struct glyph_string *h, *t;
19016 {
19017 if (h)
19018 {
19019 if (*head)
19020 (*head)->prev = t;
19021 else
19022 *tail = t;
19023 t->next = *head;
19024 *head = h;
19025 }
19026 }
19027
19028
19029 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
19030 Set *HEAD and *TAIL to the resulting list. */
19031
19032 static INLINE void
19033 append_glyph_string (head, tail, s)
19034 struct glyph_string **head, **tail;
19035 struct glyph_string *s;
19036 {
19037 s->next = s->prev = NULL;
19038 append_glyph_string_lists (head, tail, s, s);
19039 }
19040
19041
19042 /* Get face and two-byte form of character C in face FACE_ID on frame
19043 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
19044 means we want to display multibyte text. DISPLAY_P non-zero means
19045 make sure that X resources for the face returned are allocated.
19046 Value is a pointer to a realized face that is ready for display if
19047 DISPLAY_P is non-zero. */
19048
19049 static INLINE struct face *
19050 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
19051 struct frame *f;
19052 int c, face_id;
19053 XChar2b *char2b;
19054 int multibyte_p, display_p;
19055 {
19056 struct face *face = FACE_FROM_ID (f, face_id);
19057
19058 #ifdef USE_FONT_BACKEND
19059 if (enable_font_backend)
19060 {
19061 struct font *font = (struct font *) face->font_info;
19062
19063 if (font)
19064 {
19065 unsigned code = font->driver->encode_char (font, c);
19066
19067 if (code != FONT_INVALID_CODE)
19068 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19069 else
19070 STORE_XCHAR2B (char2b, 0, 0);
19071 }
19072 }
19073 else
19074 #endif /* USE_FONT_BACKEND */
19075 if (!multibyte_p)
19076 {
19077 /* Unibyte case. We don't have to encode, but we have to make
19078 sure to use a face suitable for unibyte. */
19079 STORE_XCHAR2B (char2b, 0, c);
19080 face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
19081 face = FACE_FROM_ID (f, face_id);
19082 }
19083 else if (c < 128)
19084 {
19085 /* Case of ASCII in a face known to fit ASCII. */
19086 STORE_XCHAR2B (char2b, 0, c);
19087 }
19088 else if (face->font != NULL)
19089 {
19090 struct font_info *font_info
19091 = FONT_INFO_FROM_ID (f, face->font_info_id);
19092 struct charset *charset = CHARSET_FROM_ID (font_info->charset);
19093 unsigned code = ENCODE_CHAR (charset, c);
19094
19095 if (CHARSET_DIMENSION (charset) == 1)
19096 STORE_XCHAR2B (char2b, 0, code);
19097 else
19098 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19099 /* Maybe encode the character in *CHAR2B. */
19100 FRAME_RIF (f)->encode_char (c, char2b, font_info, charset, NULL);
19101 }
19102
19103 /* Make sure X resources of the face are allocated. */
19104 #ifdef HAVE_X_WINDOWS
19105 if (display_p)
19106 #endif
19107 {
19108 xassert (face != NULL);
19109 PREPARE_FACE_FOR_DISPLAY (f, face);
19110 }
19111
19112 return face;
19113 }
19114
19115
19116 /* Get face and two-byte form of character glyph GLYPH on frame F.
19117 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
19118 a pointer to a realized face that is ready for display. */
19119
19120 static INLINE struct face *
19121 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
19122 struct frame *f;
19123 struct glyph *glyph;
19124 XChar2b *char2b;
19125 int *two_byte_p;
19126 {
19127 struct face *face;
19128
19129 xassert (glyph->type == CHAR_GLYPH);
19130 face = FACE_FROM_ID (f, glyph->face_id);
19131
19132 if (two_byte_p)
19133 *two_byte_p = 0;
19134
19135 #ifdef USE_FONT_BACKEND
19136 if (enable_font_backend)
19137 {
19138 struct font *font = (struct font *) face->font_info;
19139
19140 if (font)
19141 {
19142 unsigned code = font->driver->encode_char (font, glyph->u.ch);
19143
19144 if (code != FONT_INVALID_CODE)
19145 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19146 else
19147 STORE_XCHAR2B (char2b, 0, code);
19148 }
19149 }
19150 else
19151 #endif /* USE_FONT_BACKEND */
19152 if (!glyph->multibyte_p)
19153 {
19154 /* Unibyte case. We don't have to encode, but we have to make
19155 sure to use a face suitable for unibyte. */
19156 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
19157 }
19158 else if (glyph->u.ch < 128)
19159 {
19160 /* Case of ASCII in a face known to fit ASCII. */
19161 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
19162 }
19163 else
19164 {
19165 struct font_info *font_info
19166 = FONT_INFO_FROM_ID (f, face->font_info_id);
19167 if (font_info)
19168 {
19169 struct charset *charset = CHARSET_FROM_ID (font_info->charset);
19170 unsigned code = ENCODE_CHAR (charset, glyph->u.ch);
19171
19172 if (CHARSET_DIMENSION (charset) == 1)
19173 STORE_XCHAR2B (char2b, 0, code);
19174 else
19175 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19176
19177 /* Maybe encode the character in *CHAR2B. */
19178 if (CHARSET_ID (charset) != charset_ascii)
19179 {
19180 glyph->font_type
19181 = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info,
19182 charset, two_byte_p);
19183 }
19184 }
19185 }
19186
19187 /* Make sure X resources of the face are allocated. */
19188 xassert (face != NULL);
19189 PREPARE_FACE_FOR_DISPLAY (f, face);
19190 return face;
19191 }
19192
19193
19194 /* Fill glyph string S with composition components specified by S->cmp.
19195
19196 BASE_FACE is the base face of the composition.
19197 S->gidx is the index of the first component for S.
19198
19199 OVERLAPS non-zero means S should draw the foreground only, and use
19200 its physical height for clipping. See also draw_glyphs.
19201
19202 Value is the index of a component not in S. */
19203
19204 static int
19205 fill_composite_glyph_string (s, base_face, overlaps)
19206 struct glyph_string *s;
19207 struct face *base_face;
19208 int overlaps;
19209 {
19210 int i;
19211
19212 xassert (s);
19213
19214 s->for_overlaps = overlaps;
19215
19216 #ifdef USE_FONT_BACKEND
19217 if (enable_font_backend && s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
19218 {
19219 Lisp_Object gstring
19220 = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
19221 s->cmp->hash_index * 2);
19222
19223 s->face = base_face;
19224 s->font_info = s->cmp->font;
19225 s->font = s->font_info->font;
19226 for (i = 0, s->nchars = 0; i < s->cmp->glyph_len; i++, s->nchars++)
19227 {
19228 Lisp_Object g = LGSTRING_GLYPH (gstring, i);
19229 unsigned code;
19230 XChar2b * store_pos;
19231 if (NILP (LGLYPH_FROM (g)))
19232 break;
19233 code = XUINT (LGLYPH_CODE (g));
19234 store_pos = s->char2b + i;
19235 STORE_XCHAR2B (store_pos, code >> 8, code & 0xFF);
19236 }
19237 s->width = s->cmp->pixel_width;
19238 }
19239 else
19240 #endif /* USE_FONT_BACKEND */
19241 {
19242 /* For all glyphs of this composition, starting at the offset
19243 S->gidx, until we reach the end of the definition or encounter a
19244 glyph that requires the different face, add it to S. */
19245 struct face *face;
19246
19247 s->face = NULL;
19248 s->font = NULL;
19249 s->font_info = NULL;
19250 for (i = s->gidx; i < s->cmp->glyph_len; i++)
19251 {
19252 int c = COMPOSITION_GLYPH (s->cmp, i);
19253
19254 if (c != '\t')
19255 {
19256 int face_id = FACE_FOR_CHAR (s->f, base_face, c, -1, Qnil);
19257
19258 face = get_char_face_and_encoding (s->f, c, face_id,
19259 s->char2b + i, 1, 1);
19260 if (face)
19261 {
19262 if (! s->face)
19263 {
19264 s->face = face;
19265 s->font = s->face->font;
19266 s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
19267 }
19268 else if (s->face != face)
19269 break;
19270 }
19271 }
19272 ++s->nchars;
19273 }
19274
19275 /* All glyph strings for the same composition has the same width,
19276 i.e. the width set for the first component of the composition. */
19277 s->width = s->first_glyph->pixel_width;
19278 }
19279
19280 /* If the specified font could not be loaded, use the frame's
19281 default font, but record the fact that we couldn't load it in
19282 the glyph string so that we can draw rectangles for the
19283 characters of the glyph string. */
19284 if (s->font == NULL)
19285 {
19286 s->font_not_found_p = 1;
19287 s->font = FRAME_FONT (s->f);
19288 }
19289
19290 /* Adjust base line for subscript/superscript text. */
19291 s->ybase += s->first_glyph->voffset;
19292
19293 /* This glyph string must always be drawn with 16-bit functions. */
19294 s->two_byte_p = 1;
19295
19296 return s->gidx + s->nchars;
19297 }
19298
19299
19300 /* Fill glyph string S from a sequence of character glyphs.
19301
19302 FACE_ID is the face id of the string. START is the index of the
19303 first glyph to consider, END is the index of the last + 1.
19304 OVERLAPS non-zero means S should draw the foreground only, and use
19305 its physical height for clipping. See also draw_glyphs.
19306
19307 Value is the index of the first glyph not in S. */
19308
19309 static int
19310 fill_glyph_string (s, face_id, start, end, overlaps)
19311 struct glyph_string *s;
19312 int face_id;
19313 int start, end, overlaps;
19314 {
19315 struct glyph *glyph, *last;
19316 int voffset;
19317 int glyph_not_available_p;
19318
19319 xassert (s->f == XFRAME (s->w->frame));
19320 xassert (s->nchars == 0);
19321 xassert (start >= 0 && end > start);
19322
19323 s->for_overlaps = overlaps,
19324 glyph = s->row->glyphs[s->area] + start;
19325 last = s->row->glyphs[s->area] + end;
19326 voffset = glyph->voffset;
19327
19328 glyph_not_available_p = glyph->glyph_not_available_p;
19329
19330 while (glyph < last
19331 && glyph->type == CHAR_GLYPH
19332 && glyph->voffset == voffset
19333 /* Same face id implies same font, nowadays. */
19334 && glyph->face_id == face_id
19335 && glyph->glyph_not_available_p == glyph_not_available_p)
19336 {
19337 int two_byte_p;
19338
19339 s->face = get_glyph_face_and_encoding (s->f, glyph,
19340 s->char2b + s->nchars,
19341 &two_byte_p);
19342 s->two_byte_p = two_byte_p;
19343 ++s->nchars;
19344 xassert (s->nchars <= end - start);
19345 s->width += glyph->pixel_width;
19346 ++glyph;
19347 }
19348
19349 s->font = s->face->font;
19350 s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
19351
19352 /* If the specified font could not be loaded, use the frame's font,
19353 but record the fact that we couldn't load it in
19354 S->font_not_found_p so that we can draw rectangles for the
19355 characters of the glyph string. */
19356 if (s->font == NULL || glyph_not_available_p)
19357 {
19358 s->font_not_found_p = 1;
19359 s->font = FRAME_FONT (s->f);
19360 }
19361
19362 /* Adjust base line for subscript/superscript text. */
19363 s->ybase += voffset;
19364
19365 xassert (s->face && s->face->gc);
19366 return glyph - s->row->glyphs[s->area];
19367 }
19368
19369
19370 /* Fill glyph string S from image glyph S->first_glyph. */
19371
19372 static void
19373 fill_image_glyph_string (s)
19374 struct glyph_string *s;
19375 {
19376 xassert (s->first_glyph->type == IMAGE_GLYPH);
19377 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
19378 xassert (s->img);
19379 s->slice = s->first_glyph->slice;
19380 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
19381 s->font = s->face->font;
19382 s->width = s->first_glyph->pixel_width;
19383
19384 /* Adjust base line for subscript/superscript text. */
19385 s->ybase += s->first_glyph->voffset;
19386 }
19387
19388
19389 /* Fill glyph string S from a sequence of stretch glyphs.
19390
19391 ROW is the glyph row in which the glyphs are found, AREA is the
19392 area within the row. START is the index of the first glyph to
19393 consider, END is the index of the last + 1.
19394
19395 Value is the index of the first glyph not in S. */
19396
19397 static int
19398 fill_stretch_glyph_string (s, row, area, start, end)
19399 struct glyph_string *s;
19400 struct glyph_row *row;
19401 enum glyph_row_area area;
19402 int start, end;
19403 {
19404 struct glyph *glyph, *last;
19405 int voffset, face_id;
19406
19407 xassert (s->first_glyph->type == STRETCH_GLYPH);
19408
19409 glyph = s->row->glyphs[s->area] + start;
19410 last = s->row->glyphs[s->area] + end;
19411 face_id = glyph->face_id;
19412 s->face = FACE_FROM_ID (s->f, face_id);
19413 s->font = s->face->font;
19414 s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
19415 s->width = glyph->pixel_width;
19416 s->nchars = 1;
19417 voffset = glyph->voffset;
19418
19419 for (++glyph;
19420 (glyph < last
19421 && glyph->type == STRETCH_GLYPH
19422 && glyph->voffset == voffset
19423 && glyph->face_id == face_id);
19424 ++glyph)
19425 s->width += glyph->pixel_width;
19426
19427 /* Adjust base line for subscript/superscript text. */
19428 s->ybase += voffset;
19429
19430 /* The case that face->gc == 0 is handled when drawing the glyph
19431 string by calling PREPARE_FACE_FOR_DISPLAY. */
19432 xassert (s->face);
19433 return glyph - s->row->glyphs[s->area];
19434 }
19435
19436 static XCharStruct *
19437 get_per_char_metric (f, font, font_info, char2b, font_type)
19438 struct frame *f;
19439 XFontStruct *font;
19440 struct font_info *font_info;
19441 XChar2b *char2b;
19442 int font_type;
19443 {
19444 #ifdef USE_FONT_BACKEND
19445 if (enable_font_backend)
19446 {
19447 static XCharStruct pcm_value;
19448 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
19449 struct font *fontp;
19450 struct font_metrics metrics;
19451
19452 if (! font_info || code == FONT_INVALID_CODE)
19453 return NULL;
19454 fontp = (struct font *) font_info;
19455 fontp->driver->text_extents (fontp, &code, 1, &metrics);
19456 pcm_value.lbearing = metrics.lbearing;
19457 pcm_value.rbearing = metrics.rbearing;
19458 pcm_value.ascent = metrics.ascent;
19459 pcm_value.descent = metrics.descent;
19460 pcm_value.width = metrics.width;
19461 return &pcm_value;
19462 }
19463 #endif /* USE_FONT_BACKEND */
19464 return FRAME_RIF (f)->per_char_metric (font, char2b, font_type);
19465 }
19466
19467 /* EXPORT for RIF:
19468 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
19469 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
19470 assumed to be zero. */
19471
19472 void
19473 x_get_glyph_overhangs (glyph, f, left, right)
19474 struct glyph *glyph;
19475 struct frame *f;
19476 int *left, *right;
19477 {
19478 *left = *right = 0;
19479
19480 if (glyph->type == CHAR_GLYPH)
19481 {
19482 XFontStruct *font;
19483 struct face *face;
19484 struct font_info *font_info;
19485 XChar2b char2b;
19486 XCharStruct *pcm;
19487
19488 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
19489 font = face->font;
19490 font_info = FONT_INFO_FROM_FACE (f, face);
19491 if (font /* ++KFS: Should this be font_info ? */
19492 && (pcm = get_per_char_metric (f, font, font_info, &char2b, glyph->font_type)))
19493 {
19494 if (pcm->rbearing > pcm->width)
19495 *right = pcm->rbearing - pcm->width;
19496 if (pcm->lbearing < 0)
19497 *left = -pcm->lbearing;
19498 }
19499 }
19500 else if (glyph->type == COMPOSITE_GLYPH)
19501 {
19502 struct composition *cmp = composition_table[glyph->u.cmp_id];
19503
19504 *right = cmp->rbearing - cmp->pixel_width;
19505 *left = - cmp->lbearing;
19506 }
19507 }
19508
19509
19510 /* Return the index of the first glyph preceding glyph string S that
19511 is overwritten by S because of S's left overhang. Value is -1
19512 if no glyphs are overwritten. */
19513
19514 static int
19515 left_overwritten (s)
19516 struct glyph_string *s;
19517 {
19518 int k;
19519
19520 if (s->left_overhang)
19521 {
19522 int x = 0, i;
19523 struct glyph *glyphs = s->row->glyphs[s->area];
19524 int first = s->first_glyph - glyphs;
19525
19526 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
19527 x -= glyphs[i].pixel_width;
19528
19529 k = i + 1;
19530 }
19531 else
19532 k = -1;
19533
19534 return k;
19535 }
19536
19537
19538 /* Return the index of the first glyph preceding glyph string S that
19539 is overwriting S because of its right overhang. Value is -1 if no
19540 glyph in front of S overwrites S. */
19541
19542 static int
19543 left_overwriting (s)
19544 struct glyph_string *s;
19545 {
19546 int i, k, x;
19547 struct glyph *glyphs = s->row->glyphs[s->area];
19548 int first = s->first_glyph - glyphs;
19549
19550 k = -1;
19551 x = 0;
19552 for (i = first - 1; i >= 0; --i)
19553 {
19554 int left, right;
19555 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19556 if (x + right > 0)
19557 k = i;
19558 x -= glyphs[i].pixel_width;
19559 }
19560
19561 return k;
19562 }
19563
19564
19565 /* Return the index of the last glyph following glyph string S that is
19566 not overwritten by S because of S's right overhang. Value is -1 if
19567 no such glyph is found. */
19568
19569 static int
19570 right_overwritten (s)
19571 struct glyph_string *s;
19572 {
19573 int k = -1;
19574
19575 if (s->right_overhang)
19576 {
19577 int x = 0, i;
19578 struct glyph *glyphs = s->row->glyphs[s->area];
19579 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19580 int end = s->row->used[s->area];
19581
19582 for (i = first; i < end && s->right_overhang > x; ++i)
19583 x += glyphs[i].pixel_width;
19584
19585 k = i;
19586 }
19587
19588 return k;
19589 }
19590
19591
19592 /* Return the index of the last glyph following glyph string S that
19593 overwrites S because of its left overhang. Value is negative
19594 if no such glyph is found. */
19595
19596 static int
19597 right_overwriting (s)
19598 struct glyph_string *s;
19599 {
19600 int i, k, x;
19601 int end = s->row->used[s->area];
19602 struct glyph *glyphs = s->row->glyphs[s->area];
19603 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19604
19605 k = -1;
19606 x = 0;
19607 for (i = first; i < end; ++i)
19608 {
19609 int left, right;
19610 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19611 if (x - left < 0)
19612 k = i;
19613 x += glyphs[i].pixel_width;
19614 }
19615
19616 return k;
19617 }
19618
19619
19620 /* Set background width of glyph string S. START is the index of the
19621 first glyph following S. LAST_X is the right-most x-position + 1
19622 in the drawing area. */
19623
19624 static INLINE void
19625 set_glyph_string_background_width (s, start, last_x)
19626 struct glyph_string *s;
19627 int start;
19628 int last_x;
19629 {
19630 /* If the face of this glyph string has to be drawn to the end of
19631 the drawing area, set S->extends_to_end_of_line_p. */
19632
19633 if (start == s->row->used[s->area]
19634 && s->area == TEXT_AREA
19635 && ((s->row->fill_line_p
19636 && (s->hl == DRAW_NORMAL_TEXT
19637 || s->hl == DRAW_IMAGE_RAISED
19638 || s->hl == DRAW_IMAGE_SUNKEN))
19639 || s->hl == DRAW_MOUSE_FACE))
19640 s->extends_to_end_of_line_p = 1;
19641
19642 /* If S extends its face to the end of the line, set its
19643 background_width to the distance to the right edge of the drawing
19644 area. */
19645 if (s->extends_to_end_of_line_p)
19646 s->background_width = last_x - s->x + 1;
19647 else
19648 s->background_width = s->width;
19649 }
19650
19651
19652 /* Compute overhangs and x-positions for glyph string S and its
19653 predecessors, or successors. X is the starting x-position for S.
19654 BACKWARD_P non-zero means process predecessors. */
19655
19656 static void
19657 compute_overhangs_and_x (s, x, backward_p)
19658 struct glyph_string *s;
19659 int x;
19660 int backward_p;
19661 {
19662 if (backward_p)
19663 {
19664 while (s)
19665 {
19666 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
19667 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
19668 x -= s->width;
19669 s->x = x;
19670 s = s->prev;
19671 }
19672 }
19673 else
19674 {
19675 while (s)
19676 {
19677 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
19678 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
19679 s->x = x;
19680 x += s->width;
19681 s = s->next;
19682 }
19683 }
19684 }
19685
19686
19687
19688 /* The following macros are only called from draw_glyphs below.
19689 They reference the following parameters of that function directly:
19690 `w', `row', `area', and `overlap_p'
19691 as well as the following local variables:
19692 `s', `f', and `hdc' (in W32) */
19693
19694 #ifdef HAVE_NTGUI
19695 /* On W32, silently add local `hdc' variable to argument list of
19696 init_glyph_string. */
19697 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19698 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
19699 #else
19700 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19701 init_glyph_string (s, char2b, w, row, area, start, hl)
19702 #endif
19703
19704 /* Add a glyph string for a stretch glyph to the list of strings
19705 between HEAD and TAIL. START is the index of the stretch glyph in
19706 row area AREA of glyph row ROW. END is the index of the last glyph
19707 in that glyph row area. X is the current output position assigned
19708 to the new glyph string constructed. HL overrides that face of the
19709 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19710 is the right-most x-position of the drawing area. */
19711
19712 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
19713 and below -- keep them on one line. */
19714 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19715 do \
19716 { \
19717 s = (struct glyph_string *) alloca (sizeof *s); \
19718 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19719 START = fill_stretch_glyph_string (s, row, area, START, END); \
19720 append_glyph_string (&HEAD, &TAIL, s); \
19721 s->x = (X); \
19722 } \
19723 while (0)
19724
19725
19726 /* Add a glyph string for an image glyph to the list of strings
19727 between HEAD and TAIL. START is the index of the image glyph in
19728 row area AREA of glyph row ROW. END is the index of the last glyph
19729 in that glyph row area. X is the current output position assigned
19730 to the new glyph string constructed. HL overrides that face of the
19731 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19732 is the right-most x-position of the drawing area. */
19733
19734 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19735 do \
19736 { \
19737 s = (struct glyph_string *) alloca (sizeof *s); \
19738 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19739 fill_image_glyph_string (s); \
19740 append_glyph_string (&HEAD, &TAIL, s); \
19741 ++START; \
19742 s->x = (X); \
19743 } \
19744 while (0)
19745
19746
19747 /* Add a glyph string for a sequence of character glyphs to the list
19748 of strings between HEAD and TAIL. START is the index of the first
19749 glyph in row area AREA of glyph row ROW that is part of the new
19750 glyph string. END is the index of the last glyph in that glyph row
19751 area. X is the current output position assigned to the new glyph
19752 string constructed. HL overrides that face of the glyph; e.g. it
19753 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
19754 right-most x-position of the drawing area. */
19755
19756 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19757 do \
19758 { \
19759 int face_id; \
19760 XChar2b *char2b; \
19761 \
19762 face_id = (row)->glyphs[area][START].face_id; \
19763 \
19764 s = (struct glyph_string *) alloca (sizeof *s); \
19765 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
19766 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
19767 append_glyph_string (&HEAD, &TAIL, s); \
19768 s->x = (X); \
19769 START = fill_glyph_string (s, face_id, START, END, overlaps); \
19770 } \
19771 while (0)
19772
19773
19774 /* Add a glyph string for a composite sequence to the list of strings
19775 between HEAD and TAIL. START is the index of the first glyph in
19776 row area AREA of glyph row ROW that is part of the new glyph
19777 string. END is the index of the last glyph in that glyph row area.
19778 X is the current output position assigned to the new glyph string
19779 constructed. HL overrides that face of the glyph; e.g. it is
19780 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
19781 x-position of the drawing area. */
19782
19783 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19784 do { \
19785 int face_id = (row)->glyphs[area][START].face_id; \
19786 struct face *base_face = FACE_FROM_ID (f, face_id); \
19787 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
19788 struct composition *cmp = composition_table[cmp_id]; \
19789 XChar2b *char2b; \
19790 struct glyph_string *first_s; \
19791 int n; \
19792 \
19793 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
19794 base_face = base_face->ascii_face; \
19795 \
19796 /* Make glyph_strings for each glyph sequence that is drawable by \
19797 the same face, and append them to HEAD/TAIL. */ \
19798 for (n = 0; n < cmp->glyph_len;) \
19799 { \
19800 s = (struct glyph_string *) alloca (sizeof *s); \
19801 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
19802 append_glyph_string (&(HEAD), &(TAIL), s); \
19803 s->cmp = cmp; \
19804 s->gidx = n; \
19805 s->x = (X); \
19806 if (n == 0) \
19807 first_s = s; \
19808 n = fill_composite_glyph_string (s, base_face, overlaps); \
19809 } \
19810 \
19811 ++START; \
19812 s = first_s; \
19813 } while (0)
19814
19815
19816 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
19817 of AREA of glyph row ROW on window W between indices START and END.
19818 HL overrides the face for drawing glyph strings, e.g. it is
19819 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
19820 x-positions of the drawing area.
19821
19822 This is an ugly monster macro construct because we must use alloca
19823 to allocate glyph strings (because draw_glyphs can be called
19824 asynchronously). */
19825
19826 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19827 do \
19828 { \
19829 HEAD = TAIL = NULL; \
19830 while (START < END) \
19831 { \
19832 struct glyph *first_glyph = (row)->glyphs[area] + START; \
19833 switch (first_glyph->type) \
19834 { \
19835 case CHAR_GLYPH: \
19836 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
19837 HL, X, LAST_X); \
19838 break; \
19839 \
19840 case COMPOSITE_GLYPH: \
19841 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
19842 HL, X, LAST_X); \
19843 break; \
19844 \
19845 case STRETCH_GLYPH: \
19846 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
19847 HL, X, LAST_X); \
19848 break; \
19849 \
19850 case IMAGE_GLYPH: \
19851 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
19852 HL, X, LAST_X); \
19853 break; \
19854 \
19855 default: \
19856 abort (); \
19857 } \
19858 \
19859 if (s) \
19860 { \
19861 set_glyph_string_background_width (s, START, LAST_X); \
19862 (X) += s->width; \
19863 } \
19864 } \
19865 } \
19866 while (0)
19867
19868
19869 /* Draw glyphs between START and END in AREA of ROW on window W,
19870 starting at x-position X. X is relative to AREA in W. HL is a
19871 face-override with the following meaning:
19872
19873 DRAW_NORMAL_TEXT draw normally
19874 DRAW_CURSOR draw in cursor face
19875 DRAW_MOUSE_FACE draw in mouse face.
19876 DRAW_INVERSE_VIDEO draw in mode line face
19877 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
19878 DRAW_IMAGE_RAISED draw an image with a raised relief around it
19879
19880 If OVERLAPS is non-zero, draw only the foreground of characters and
19881 clip to the physical height of ROW. Non-zero value also defines
19882 the overlapping part to be drawn:
19883
19884 OVERLAPS_PRED overlap with preceding rows
19885 OVERLAPS_SUCC overlap with succeeding rows
19886 OVERLAPS_BOTH overlap with both preceding/succeeding rows
19887 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
19888
19889 Value is the x-position reached, relative to AREA of W. */
19890
19891 static int
19892 draw_glyphs (w, x, row, area, start, end, hl, overlaps)
19893 struct window *w;
19894 int x;
19895 struct glyph_row *row;
19896 enum glyph_row_area area;
19897 EMACS_INT start, end;
19898 enum draw_glyphs_face hl;
19899 int overlaps;
19900 {
19901 struct glyph_string *head, *tail;
19902 struct glyph_string *s;
19903 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
19904 int last_x, area_width;
19905 int x_reached;
19906 int i, j;
19907 struct frame *f = XFRAME (WINDOW_FRAME (w));
19908 DECLARE_HDC (hdc);
19909
19910 ALLOCATE_HDC (hdc, f);
19911
19912 /* Let's rather be paranoid than getting a SEGV. */
19913 end = min (end, row->used[area]);
19914 start = max (0, start);
19915 start = min (end, start);
19916
19917 /* Translate X to frame coordinates. Set last_x to the right
19918 end of the drawing area. */
19919 if (row->full_width_p)
19920 {
19921 /* X is relative to the left edge of W, without scroll bars
19922 or fringes. */
19923 x += WINDOW_LEFT_EDGE_X (w);
19924 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
19925 }
19926 else
19927 {
19928 int area_left = window_box_left (w, area);
19929 x += area_left;
19930 area_width = window_box_width (w, area);
19931 last_x = area_left + area_width;
19932 }
19933
19934 /* Build a doubly-linked list of glyph_string structures between
19935 head and tail from what we have to draw. Note that the macro
19936 BUILD_GLYPH_STRINGS will modify its start parameter. That's
19937 the reason we use a separate variable `i'. */
19938 i = start;
19939 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
19940 if (tail)
19941 x_reached = tail->x + tail->background_width;
19942 else
19943 x_reached = x;
19944
19945 /* If there are any glyphs with lbearing < 0 or rbearing > width in
19946 the row, redraw some glyphs in front or following the glyph
19947 strings built above. */
19948 if (head && !overlaps && row->contains_overlapping_glyphs_p)
19949 {
19950 int dummy_x = 0;
19951 struct glyph_string *h, *t;
19952
19953 /* Compute overhangs for all glyph strings. */
19954 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
19955 for (s = head; s; s = s->next)
19956 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
19957
19958 /* Prepend glyph strings for glyphs in front of the first glyph
19959 string that are overwritten because of the first glyph
19960 string's left overhang. The background of all strings
19961 prepended must be drawn because the first glyph string
19962 draws over it. */
19963 i = left_overwritten (head);
19964 if (i >= 0)
19965 {
19966 j = i;
19967 BUILD_GLYPH_STRINGS (j, start, h, t,
19968 DRAW_NORMAL_TEXT, dummy_x, last_x);
19969 start = i;
19970 compute_overhangs_and_x (t, head->x, 1);
19971 prepend_glyph_string_lists (&head, &tail, h, t);
19972 clip_head = head;
19973 }
19974
19975 /* Prepend glyph strings for glyphs in front of the first glyph
19976 string that overwrite that glyph string because of their
19977 right overhang. For these strings, only the foreground must
19978 be drawn, because it draws over the glyph string at `head'.
19979 The background must not be drawn because this would overwrite
19980 right overhangs of preceding glyphs for which no glyph
19981 strings exist. */
19982 i = left_overwriting (head);
19983 if (i >= 0)
19984 {
19985 clip_head = head;
19986 BUILD_GLYPH_STRINGS (i, start, h, t,
19987 DRAW_NORMAL_TEXT, dummy_x, last_x);
19988 for (s = h; s; s = s->next)
19989 s->background_filled_p = 1;
19990 compute_overhangs_and_x (t, head->x, 1);
19991 prepend_glyph_string_lists (&head, &tail, h, t);
19992 }
19993
19994 /* Append glyphs strings for glyphs following the last glyph
19995 string tail that are overwritten by tail. The background of
19996 these strings has to be drawn because tail's foreground draws
19997 over it. */
19998 i = right_overwritten (tail);
19999 if (i >= 0)
20000 {
20001 BUILD_GLYPH_STRINGS (end, i, h, t,
20002 DRAW_NORMAL_TEXT, x, last_x);
20003 compute_overhangs_and_x (h, tail->x + tail->width, 0);
20004 append_glyph_string_lists (&head, &tail, h, t);
20005 clip_tail = tail;
20006 }
20007
20008 /* Append glyph strings for glyphs following the last glyph
20009 string tail that overwrite tail. The foreground of such
20010 glyphs has to be drawn because it writes into the background
20011 of tail. The background must not be drawn because it could
20012 paint over the foreground of following glyphs. */
20013 i = right_overwriting (tail);
20014 if (i >= 0)
20015 {
20016 clip_tail = tail;
20017 i++; /* We must include the Ith glyph. */
20018 BUILD_GLYPH_STRINGS (end, i, h, t,
20019 DRAW_NORMAL_TEXT, x, last_x);
20020 for (s = h; s; s = s->next)
20021 s->background_filled_p = 1;
20022 compute_overhangs_and_x (h, tail->x + tail->width, 0);
20023 append_glyph_string_lists (&head, &tail, h, t);
20024 }
20025 if (clip_head || clip_tail)
20026 for (s = head; s; s = s->next)
20027 {
20028 s->clip_head = clip_head;
20029 s->clip_tail = clip_tail;
20030 }
20031 }
20032
20033 /* Draw all strings. */
20034 for (s = head; s; s = s->next)
20035 FRAME_RIF (f)->draw_glyph_string (s);
20036
20037 if (area == TEXT_AREA
20038 && !row->full_width_p
20039 /* When drawing overlapping rows, only the glyph strings'
20040 foreground is drawn, which doesn't erase a cursor
20041 completely. */
20042 && !overlaps)
20043 {
20044 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
20045 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
20046 : (tail ? tail->x + tail->background_width : x));
20047
20048 int text_left = window_box_left (w, TEXT_AREA);
20049 x0 -= text_left;
20050 x1 -= text_left;
20051
20052 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
20053 row->y, MATRIX_ROW_BOTTOM_Y (row));
20054 }
20055
20056 /* Value is the x-position up to which drawn, relative to AREA of W.
20057 This doesn't include parts drawn because of overhangs. */
20058 if (row->full_width_p)
20059 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
20060 else
20061 x_reached -= window_box_left (w, area);
20062
20063 RELEASE_HDC (hdc, f);
20064
20065 return x_reached;
20066 }
20067
20068 /* Expand row matrix if too narrow. Don't expand if area
20069 is not present. */
20070
20071 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
20072 { \
20073 if (!fonts_changed_p \
20074 && (it->glyph_row->glyphs[area] \
20075 < it->glyph_row->glyphs[area + 1])) \
20076 { \
20077 it->w->ncols_scale_factor++; \
20078 fonts_changed_p = 1; \
20079 } \
20080 }
20081
20082 /* Store one glyph for IT->char_to_display in IT->glyph_row.
20083 Called from x_produce_glyphs when IT->glyph_row is non-null. */
20084
20085 static INLINE void
20086 append_glyph (it)
20087 struct it *it;
20088 {
20089 struct glyph *glyph;
20090 enum glyph_row_area area = it->area;
20091
20092 xassert (it->glyph_row);
20093 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
20094
20095 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20096 if (glyph < it->glyph_row->glyphs[area + 1])
20097 {
20098 glyph->charpos = CHARPOS (it->position);
20099 glyph->object = it->object;
20100 glyph->pixel_width = it->pixel_width;
20101 glyph->ascent = it->ascent;
20102 glyph->descent = it->descent;
20103 glyph->voffset = it->voffset;
20104 glyph->type = CHAR_GLYPH;
20105 glyph->multibyte_p = it->multibyte_p;
20106 glyph->left_box_line_p = it->start_of_box_run_p;
20107 glyph->right_box_line_p = it->end_of_box_run_p;
20108 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
20109 || it->phys_descent > it->descent);
20110 glyph->padding_p = 0;
20111 glyph->glyph_not_available_p = it->glyph_not_available_p;
20112 glyph->face_id = it->face_id;
20113 glyph->u.ch = it->char_to_display;
20114 glyph->slice = null_glyph_slice;
20115 glyph->font_type = FONT_TYPE_UNKNOWN;
20116 ++it->glyph_row->used[area];
20117 }
20118 else
20119 IT_EXPAND_MATRIX_WIDTH (it, area);
20120 }
20121
20122 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
20123 Called from x_produce_glyphs when IT->glyph_row is non-null. */
20124
20125 static INLINE void
20126 append_composite_glyph (it)
20127 struct it *it;
20128 {
20129 struct glyph *glyph;
20130 enum glyph_row_area area = it->area;
20131
20132 xassert (it->glyph_row);
20133
20134 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20135 if (glyph < it->glyph_row->glyphs[area + 1])
20136 {
20137 glyph->charpos = CHARPOS (it->position);
20138 glyph->object = it->object;
20139 glyph->pixel_width = it->pixel_width;
20140 glyph->ascent = it->ascent;
20141 glyph->descent = it->descent;
20142 glyph->voffset = it->voffset;
20143 glyph->type = COMPOSITE_GLYPH;
20144 glyph->multibyte_p = it->multibyte_p;
20145 glyph->left_box_line_p = it->start_of_box_run_p;
20146 glyph->right_box_line_p = it->end_of_box_run_p;
20147 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
20148 || it->phys_descent > it->descent);
20149 glyph->padding_p = 0;
20150 glyph->glyph_not_available_p = 0;
20151 glyph->face_id = it->face_id;
20152 glyph->u.cmp_id = it->cmp_id;
20153 glyph->slice = null_glyph_slice;
20154 glyph->font_type = FONT_TYPE_UNKNOWN;
20155 ++it->glyph_row->used[area];
20156 }
20157 else
20158 IT_EXPAND_MATRIX_WIDTH (it, area);
20159 }
20160
20161
20162 /* Change IT->ascent and IT->height according to the setting of
20163 IT->voffset. */
20164
20165 static INLINE void
20166 take_vertical_position_into_account (it)
20167 struct it *it;
20168 {
20169 if (it->voffset)
20170 {
20171 if (it->voffset < 0)
20172 /* Increase the ascent so that we can display the text higher
20173 in the line. */
20174 it->ascent -= it->voffset;
20175 else
20176 /* Increase the descent so that we can display the text lower
20177 in the line. */
20178 it->descent += it->voffset;
20179 }
20180 }
20181
20182
20183 /* Produce glyphs/get display metrics for the image IT is loaded with.
20184 See the description of struct display_iterator in dispextern.h for
20185 an overview of struct display_iterator. */
20186
20187 static void
20188 produce_image_glyph (it)
20189 struct it *it;
20190 {
20191 struct image *img;
20192 struct face *face;
20193 int glyph_ascent, crop;
20194 struct glyph_slice slice;
20195
20196 xassert (it->what == IT_IMAGE);
20197
20198 face = FACE_FROM_ID (it->f, it->face_id);
20199 xassert (face);
20200 /* Make sure X resources of the face is loaded. */
20201 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20202
20203 if (it->image_id < 0)
20204 {
20205 /* Fringe bitmap. */
20206 it->ascent = it->phys_ascent = 0;
20207 it->descent = it->phys_descent = 0;
20208 it->pixel_width = 0;
20209 it->nglyphs = 0;
20210 return;
20211 }
20212
20213 img = IMAGE_FROM_ID (it->f, it->image_id);
20214 xassert (img);
20215 /* Make sure X resources of the image is loaded. */
20216 prepare_image_for_display (it->f, img);
20217
20218 slice.x = slice.y = 0;
20219 slice.width = img->width;
20220 slice.height = img->height;
20221
20222 if (INTEGERP (it->slice.x))
20223 slice.x = XINT (it->slice.x);
20224 else if (FLOATP (it->slice.x))
20225 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
20226
20227 if (INTEGERP (it->slice.y))
20228 slice.y = XINT (it->slice.y);
20229 else if (FLOATP (it->slice.y))
20230 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
20231
20232 if (INTEGERP (it->slice.width))
20233 slice.width = XINT (it->slice.width);
20234 else if (FLOATP (it->slice.width))
20235 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
20236
20237 if (INTEGERP (it->slice.height))
20238 slice.height = XINT (it->slice.height);
20239 else if (FLOATP (it->slice.height))
20240 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
20241
20242 if (slice.x >= img->width)
20243 slice.x = img->width;
20244 if (slice.y >= img->height)
20245 slice.y = img->height;
20246 if (slice.x + slice.width >= img->width)
20247 slice.width = img->width - slice.x;
20248 if (slice.y + slice.height > img->height)
20249 slice.height = img->height - slice.y;
20250
20251 if (slice.width == 0 || slice.height == 0)
20252 return;
20253
20254 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
20255
20256 it->descent = slice.height - glyph_ascent;
20257 if (slice.y == 0)
20258 it->descent += img->vmargin;
20259 if (slice.y + slice.height == img->height)
20260 it->descent += img->vmargin;
20261 it->phys_descent = it->descent;
20262
20263 it->pixel_width = slice.width;
20264 if (slice.x == 0)
20265 it->pixel_width += img->hmargin;
20266 if (slice.x + slice.width == img->width)
20267 it->pixel_width += img->hmargin;
20268
20269 /* It's quite possible for images to have an ascent greater than
20270 their height, so don't get confused in that case. */
20271 if (it->descent < 0)
20272 it->descent = 0;
20273
20274 #if 0 /* this breaks image tiling */
20275 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
20276 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
20277 if (face_ascent > it->ascent)
20278 it->ascent = it->phys_ascent = face_ascent;
20279 #endif
20280
20281 it->nglyphs = 1;
20282
20283 if (face->box != FACE_NO_BOX)
20284 {
20285 if (face->box_line_width > 0)
20286 {
20287 if (slice.y == 0)
20288 it->ascent += face->box_line_width;
20289 if (slice.y + slice.height == img->height)
20290 it->descent += face->box_line_width;
20291 }
20292
20293 if (it->start_of_box_run_p && slice.x == 0)
20294 it->pixel_width += abs (face->box_line_width);
20295 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
20296 it->pixel_width += abs (face->box_line_width);
20297 }
20298
20299 take_vertical_position_into_account (it);
20300
20301 /* Automatically crop wide image glyphs at right edge so we can
20302 draw the cursor on same display row. */
20303 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
20304 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
20305 {
20306 it->pixel_width -= crop;
20307 slice.width -= crop;
20308 }
20309
20310 if (it->glyph_row)
20311 {
20312 struct glyph *glyph;
20313 enum glyph_row_area area = it->area;
20314
20315 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20316 if (glyph < it->glyph_row->glyphs[area + 1])
20317 {
20318 glyph->charpos = CHARPOS (it->position);
20319 glyph->object = it->object;
20320 glyph->pixel_width = it->pixel_width;
20321 glyph->ascent = glyph_ascent;
20322 glyph->descent = it->descent;
20323 glyph->voffset = it->voffset;
20324 glyph->type = IMAGE_GLYPH;
20325 glyph->multibyte_p = it->multibyte_p;
20326 glyph->left_box_line_p = it->start_of_box_run_p;
20327 glyph->right_box_line_p = it->end_of_box_run_p;
20328 glyph->overlaps_vertically_p = 0;
20329 glyph->padding_p = 0;
20330 glyph->glyph_not_available_p = 0;
20331 glyph->face_id = it->face_id;
20332 glyph->u.img_id = img->id;
20333 glyph->slice = slice;
20334 glyph->font_type = FONT_TYPE_UNKNOWN;
20335 ++it->glyph_row->used[area];
20336 }
20337 else
20338 IT_EXPAND_MATRIX_WIDTH (it, area);
20339 }
20340 }
20341
20342
20343 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
20344 of the glyph, WIDTH and HEIGHT are the width and height of the
20345 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
20346
20347 static void
20348 append_stretch_glyph (it, object, width, height, ascent)
20349 struct it *it;
20350 Lisp_Object object;
20351 int width, height;
20352 int ascent;
20353 {
20354 struct glyph *glyph;
20355 enum glyph_row_area area = it->area;
20356
20357 xassert (ascent >= 0 && ascent <= height);
20358
20359 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20360 if (glyph < it->glyph_row->glyphs[area + 1])
20361 {
20362 glyph->charpos = CHARPOS (it->position);
20363 glyph->object = object;
20364 glyph->pixel_width = width;
20365 glyph->ascent = ascent;
20366 glyph->descent = height - ascent;
20367 glyph->voffset = it->voffset;
20368 glyph->type = STRETCH_GLYPH;
20369 glyph->multibyte_p = it->multibyte_p;
20370 glyph->left_box_line_p = it->start_of_box_run_p;
20371 glyph->right_box_line_p = it->end_of_box_run_p;
20372 glyph->overlaps_vertically_p = 0;
20373 glyph->padding_p = 0;
20374 glyph->glyph_not_available_p = 0;
20375 glyph->face_id = it->face_id;
20376 glyph->u.stretch.ascent = ascent;
20377 glyph->u.stretch.height = height;
20378 glyph->slice = null_glyph_slice;
20379 glyph->font_type = FONT_TYPE_UNKNOWN;
20380 ++it->glyph_row->used[area];
20381 }
20382 else
20383 IT_EXPAND_MATRIX_WIDTH (it, area);
20384 }
20385
20386
20387 /* Produce a stretch glyph for iterator IT. IT->object is the value
20388 of the glyph property displayed. The value must be a list
20389 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
20390 being recognized:
20391
20392 1. `:width WIDTH' specifies that the space should be WIDTH *
20393 canonical char width wide. WIDTH may be an integer or floating
20394 point number.
20395
20396 2. `:relative-width FACTOR' specifies that the width of the stretch
20397 should be computed from the width of the first character having the
20398 `glyph' property, and should be FACTOR times that width.
20399
20400 3. `:align-to HPOS' specifies that the space should be wide enough
20401 to reach HPOS, a value in canonical character units.
20402
20403 Exactly one of the above pairs must be present.
20404
20405 4. `:height HEIGHT' specifies that the height of the stretch produced
20406 should be HEIGHT, measured in canonical character units.
20407
20408 5. `:relative-height FACTOR' specifies that the height of the
20409 stretch should be FACTOR times the height of the characters having
20410 the glyph property.
20411
20412 Either none or exactly one of 4 or 5 must be present.
20413
20414 6. `:ascent ASCENT' specifies that ASCENT percent of the height
20415 of the stretch should be used for the ascent of the stretch.
20416 ASCENT must be in the range 0 <= ASCENT <= 100. */
20417
20418 static void
20419 produce_stretch_glyph (it)
20420 struct it *it;
20421 {
20422 /* (space :width WIDTH :height HEIGHT ...) */
20423 Lisp_Object prop, plist;
20424 int width = 0, height = 0, align_to = -1;
20425 int zero_width_ok_p = 0, zero_height_ok_p = 0;
20426 int ascent = 0;
20427 double tem;
20428 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20429 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
20430
20431 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20432
20433 /* List should start with `space'. */
20434 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
20435 plist = XCDR (it->object);
20436
20437 /* Compute the width of the stretch. */
20438 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
20439 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
20440 {
20441 /* Absolute width `:width WIDTH' specified and valid. */
20442 zero_width_ok_p = 1;
20443 width = (int)tem;
20444 }
20445 else if (prop = Fplist_get (plist, QCrelative_width),
20446 NUMVAL (prop) > 0)
20447 {
20448 /* Relative width `:relative-width FACTOR' specified and valid.
20449 Compute the width of the characters having the `glyph'
20450 property. */
20451 struct it it2;
20452 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
20453
20454 it2 = *it;
20455 if (it->multibyte_p)
20456 {
20457 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
20458 - IT_BYTEPOS (*it));
20459 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
20460 }
20461 else
20462 it2.c = *p, it2.len = 1;
20463
20464 it2.glyph_row = NULL;
20465 it2.what = IT_CHARACTER;
20466 x_produce_glyphs (&it2);
20467 width = NUMVAL (prop) * it2.pixel_width;
20468 }
20469 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
20470 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
20471 {
20472 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
20473 align_to = (align_to < 0
20474 ? 0
20475 : align_to - window_box_left_offset (it->w, TEXT_AREA));
20476 else if (align_to < 0)
20477 align_to = window_box_left_offset (it->w, TEXT_AREA);
20478 width = max (0, (int)tem + align_to - it->current_x);
20479 zero_width_ok_p = 1;
20480 }
20481 else
20482 /* Nothing specified -> width defaults to canonical char width. */
20483 width = FRAME_COLUMN_WIDTH (it->f);
20484
20485 if (width <= 0 && (width < 0 || !zero_width_ok_p))
20486 width = 1;
20487
20488 /* Compute height. */
20489 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
20490 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20491 {
20492 height = (int)tem;
20493 zero_height_ok_p = 1;
20494 }
20495 else if (prop = Fplist_get (plist, QCrelative_height),
20496 NUMVAL (prop) > 0)
20497 height = FONT_HEIGHT (font) * NUMVAL (prop);
20498 else
20499 height = FONT_HEIGHT (font);
20500
20501 if (height <= 0 && (height < 0 || !zero_height_ok_p))
20502 height = 1;
20503
20504 /* Compute percentage of height used for ascent. If
20505 `:ascent ASCENT' is present and valid, use that. Otherwise,
20506 derive the ascent from the font in use. */
20507 if (prop = Fplist_get (plist, QCascent),
20508 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
20509 ascent = height * NUMVAL (prop) / 100.0;
20510 else if (!NILP (prop)
20511 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20512 ascent = min (max (0, (int)tem), height);
20513 else
20514 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
20515
20516 if (width > 0 && !it->truncate_lines_p
20517 && it->current_x + width > it->last_visible_x)
20518 width = it->last_visible_x - it->current_x - 1;
20519
20520 if (width > 0 && height > 0 && it->glyph_row)
20521 {
20522 Lisp_Object object = it->stack[it->sp - 1].string;
20523 if (!STRINGP (object))
20524 object = it->w->buffer;
20525 append_stretch_glyph (it, object, width, height, ascent);
20526 }
20527
20528 it->pixel_width = width;
20529 it->ascent = it->phys_ascent = ascent;
20530 it->descent = it->phys_descent = height - it->ascent;
20531 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
20532
20533 take_vertical_position_into_account (it);
20534 }
20535
20536 /* Get line-height and line-spacing property at point.
20537 If line-height has format (HEIGHT TOTAL), return TOTAL
20538 in TOTAL_HEIGHT. */
20539
20540 static Lisp_Object
20541 get_line_height_property (it, prop)
20542 struct it *it;
20543 Lisp_Object prop;
20544 {
20545 Lisp_Object position;
20546
20547 if (STRINGP (it->object))
20548 position = make_number (IT_STRING_CHARPOS (*it));
20549 else if (BUFFERP (it->object))
20550 position = make_number (IT_CHARPOS (*it));
20551 else
20552 return Qnil;
20553
20554 return Fget_char_property (position, prop, it->object);
20555 }
20556
20557 /* Calculate line-height and line-spacing properties.
20558 An integer value specifies explicit pixel value.
20559 A float value specifies relative value to current face height.
20560 A cons (float . face-name) specifies relative value to
20561 height of specified face font.
20562
20563 Returns height in pixels, or nil. */
20564
20565
20566 static Lisp_Object
20567 calc_line_height_property (it, val, font, boff, override)
20568 struct it *it;
20569 Lisp_Object val;
20570 XFontStruct *font;
20571 int boff, override;
20572 {
20573 Lisp_Object face_name = Qnil;
20574 int ascent, descent, height;
20575
20576 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
20577 return val;
20578
20579 if (CONSP (val))
20580 {
20581 face_name = XCAR (val);
20582 val = XCDR (val);
20583 if (!NUMBERP (val))
20584 val = make_number (1);
20585 if (NILP (face_name))
20586 {
20587 height = it->ascent + it->descent;
20588 goto scale;
20589 }
20590 }
20591
20592 if (NILP (face_name))
20593 {
20594 font = FRAME_FONT (it->f);
20595 boff = FRAME_BASELINE_OFFSET (it->f);
20596 }
20597 else if (EQ (face_name, Qt))
20598 {
20599 override = 0;
20600 }
20601 else
20602 {
20603 int face_id;
20604 struct face *face;
20605 struct font_info *font_info;
20606
20607 face_id = lookup_named_face (it->f, face_name, 0);
20608 if (face_id < 0)
20609 return make_number (-1);
20610
20611 face = FACE_FROM_ID (it->f, face_id);
20612 font = face->font;
20613 if (font == NULL)
20614 return make_number (-1);
20615
20616 font_info = FONT_INFO_FROM_FACE (it->f, face);
20617 boff = font_info->baseline_offset;
20618 if (font_info->vertical_centering)
20619 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20620 }
20621
20622 ascent = FONT_BASE (font) + boff;
20623 descent = FONT_DESCENT (font) - boff;
20624
20625 if (override)
20626 {
20627 it->override_ascent = ascent;
20628 it->override_descent = descent;
20629 it->override_boff = boff;
20630 }
20631
20632 height = ascent + descent;
20633
20634 scale:
20635 if (FLOATP (val))
20636 height = (int)(XFLOAT_DATA (val) * height);
20637 else if (INTEGERP (val))
20638 height *= XINT (val);
20639
20640 return make_number (height);
20641 }
20642
20643
20644 /* RIF:
20645 Produce glyphs/get display metrics for the display element IT is
20646 loaded with. See the description of struct it in dispextern.h
20647 for an overview of struct it. */
20648
20649 void
20650 x_produce_glyphs (it)
20651 struct it *it;
20652 {
20653 int extra_line_spacing = it->extra_line_spacing;
20654
20655 it->glyph_not_available_p = 0;
20656
20657 if (it->what == IT_CHARACTER)
20658 {
20659 XChar2b char2b;
20660 XFontStruct *font;
20661 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20662 XCharStruct *pcm;
20663 int font_not_found_p;
20664 struct font_info *font_info;
20665 int boff; /* baseline offset */
20666 /* We may change it->multibyte_p upon unibyte<->multibyte
20667 conversion. So, save the current value now and restore it
20668 later.
20669
20670 Note: It seems that we don't have to record multibyte_p in
20671 struct glyph because the character code itself tells if or
20672 not the character is multibyte. Thus, in the future, we must
20673 consider eliminating the field `multibyte_p' in the struct
20674 glyph. */
20675 int saved_multibyte_p = it->multibyte_p;
20676
20677 /* Maybe translate single-byte characters to multibyte, or the
20678 other way. */
20679 it->char_to_display = it->c;
20680 if (!ASCII_BYTE_P (it->c)
20681 && ! it->multibyte_p)
20682 {
20683 if (SINGLE_BYTE_CHAR_P (it->c)
20684 && unibyte_display_via_language_environment)
20685 it->char_to_display = unibyte_char_to_multibyte (it->c);
20686 if (! SINGLE_BYTE_CHAR_P (it->char_to_display))
20687 {
20688 it->multibyte_p = 1;
20689 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
20690 -1, Qnil);
20691 face = FACE_FROM_ID (it->f, it->face_id);
20692 }
20693 }
20694
20695 /* Get font to use. Encode IT->char_to_display. */
20696 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20697 &char2b, it->multibyte_p, 0);
20698 font = face->font;
20699
20700 /* When no suitable font found, use the default font. */
20701 font_not_found_p = font == NULL;
20702 if (font_not_found_p)
20703 {
20704 font = FRAME_FONT (it->f);
20705 boff = FRAME_BASELINE_OFFSET (it->f);
20706 font_info = NULL;
20707 }
20708 else
20709 {
20710 font_info = FONT_INFO_FROM_FACE (it->f, face);
20711 boff = font_info->baseline_offset;
20712 if (font_info->vertical_centering)
20713 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20714 }
20715
20716 if (it->char_to_display >= ' '
20717 && (!it->multibyte_p || it->char_to_display < 128))
20718 {
20719 /* Either unibyte or ASCII. */
20720 int stretched_p;
20721
20722 it->nglyphs = 1;
20723
20724 pcm = get_per_char_metric (it->f, font, font_info, &char2b,
20725 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
20726
20727 if (it->override_ascent >= 0)
20728 {
20729 it->ascent = it->override_ascent;
20730 it->descent = it->override_descent;
20731 boff = it->override_boff;
20732 }
20733 else
20734 {
20735 it->ascent = FONT_BASE (font) + boff;
20736 it->descent = FONT_DESCENT (font) - boff;
20737 }
20738
20739 if (pcm)
20740 {
20741 it->phys_ascent = pcm->ascent + boff;
20742 it->phys_descent = pcm->descent - boff;
20743 it->pixel_width = pcm->width;
20744 }
20745 else
20746 {
20747 it->glyph_not_available_p = 1;
20748 it->phys_ascent = it->ascent;
20749 it->phys_descent = it->descent;
20750 it->pixel_width = FONT_WIDTH (font);
20751 }
20752
20753 if (it->constrain_row_ascent_descent_p)
20754 {
20755 if (it->descent > it->max_descent)
20756 {
20757 it->ascent += it->descent - it->max_descent;
20758 it->descent = it->max_descent;
20759 }
20760 if (it->ascent > it->max_ascent)
20761 {
20762 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20763 it->ascent = it->max_ascent;
20764 }
20765 it->phys_ascent = min (it->phys_ascent, it->ascent);
20766 it->phys_descent = min (it->phys_descent, it->descent);
20767 extra_line_spacing = 0;
20768 }
20769
20770 /* If this is a space inside a region of text with
20771 `space-width' property, change its width. */
20772 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
20773 if (stretched_p)
20774 it->pixel_width *= XFLOATINT (it->space_width);
20775
20776 /* If face has a box, add the box thickness to the character
20777 height. If character has a box line to the left and/or
20778 right, add the box line width to the character's width. */
20779 if (face->box != FACE_NO_BOX)
20780 {
20781 int thick = face->box_line_width;
20782
20783 if (thick > 0)
20784 {
20785 it->ascent += thick;
20786 it->descent += thick;
20787 }
20788 else
20789 thick = -thick;
20790
20791 if (it->start_of_box_run_p)
20792 it->pixel_width += thick;
20793 if (it->end_of_box_run_p)
20794 it->pixel_width += thick;
20795 }
20796
20797 /* If face has an overline, add the height of the overline
20798 (1 pixel) and a 1 pixel margin to the character height. */
20799 if (face->overline_p)
20800 it->ascent += overline_margin;
20801
20802 if (it->constrain_row_ascent_descent_p)
20803 {
20804 if (it->ascent > it->max_ascent)
20805 it->ascent = it->max_ascent;
20806 if (it->descent > it->max_descent)
20807 it->descent = it->max_descent;
20808 }
20809
20810 take_vertical_position_into_account (it);
20811
20812 /* If we have to actually produce glyphs, do it. */
20813 if (it->glyph_row)
20814 {
20815 if (stretched_p)
20816 {
20817 /* Translate a space with a `space-width' property
20818 into a stretch glyph. */
20819 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
20820 / FONT_HEIGHT (font));
20821 append_stretch_glyph (it, it->object, it->pixel_width,
20822 it->ascent + it->descent, ascent);
20823 }
20824 else
20825 append_glyph (it);
20826
20827 /* If characters with lbearing or rbearing are displayed
20828 in this line, record that fact in a flag of the
20829 glyph row. This is used to optimize X output code. */
20830 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
20831 it->glyph_row->contains_overlapping_glyphs_p = 1;
20832 }
20833 }
20834 else if (it->char_to_display == '\n')
20835 {
20836 /* A newline has no width but we need the height of the line.
20837 But if previous part of the line set a height, don't
20838 increase that height */
20839
20840 Lisp_Object height;
20841 Lisp_Object total_height = Qnil;
20842
20843 it->override_ascent = -1;
20844 it->pixel_width = 0;
20845 it->nglyphs = 0;
20846
20847 height = get_line_height_property(it, Qline_height);
20848 /* Split (line-height total-height) list */
20849 if (CONSP (height)
20850 && CONSP (XCDR (height))
20851 && NILP (XCDR (XCDR (height))))
20852 {
20853 total_height = XCAR (XCDR (height));
20854 height = XCAR (height);
20855 }
20856 height = calc_line_height_property(it, height, font, boff, 1);
20857
20858 if (it->override_ascent >= 0)
20859 {
20860 it->ascent = it->override_ascent;
20861 it->descent = it->override_descent;
20862 boff = it->override_boff;
20863 }
20864 else
20865 {
20866 it->ascent = FONT_BASE (font) + boff;
20867 it->descent = FONT_DESCENT (font) - boff;
20868 }
20869
20870 if (EQ (height, Qt))
20871 {
20872 if (it->descent > it->max_descent)
20873 {
20874 it->ascent += it->descent - it->max_descent;
20875 it->descent = it->max_descent;
20876 }
20877 if (it->ascent > it->max_ascent)
20878 {
20879 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20880 it->ascent = it->max_ascent;
20881 }
20882 it->phys_ascent = min (it->phys_ascent, it->ascent);
20883 it->phys_descent = min (it->phys_descent, it->descent);
20884 it->constrain_row_ascent_descent_p = 1;
20885 extra_line_spacing = 0;
20886 }
20887 else
20888 {
20889 Lisp_Object spacing;
20890
20891 it->phys_ascent = it->ascent;
20892 it->phys_descent = it->descent;
20893
20894 if ((it->max_ascent > 0 || it->max_descent > 0)
20895 && face->box != FACE_NO_BOX
20896 && face->box_line_width > 0)
20897 {
20898 it->ascent += face->box_line_width;
20899 it->descent += face->box_line_width;
20900 }
20901 if (!NILP (height)
20902 && XINT (height) > it->ascent + it->descent)
20903 it->ascent = XINT (height) - it->descent;
20904
20905 if (!NILP (total_height))
20906 spacing = calc_line_height_property(it, total_height, font, boff, 0);
20907 else
20908 {
20909 spacing = get_line_height_property(it, Qline_spacing);
20910 spacing = calc_line_height_property(it, spacing, font, boff, 0);
20911 }
20912 if (INTEGERP (spacing))
20913 {
20914 extra_line_spacing = XINT (spacing);
20915 if (!NILP (total_height))
20916 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20917 }
20918 }
20919 }
20920 else if (it->char_to_display == '\t')
20921 {
20922 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
20923 int x = it->current_x + it->continuation_lines_width;
20924 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
20925
20926 /* If the distance from the current position to the next tab
20927 stop is less than a space character width, use the
20928 tab stop after that. */
20929 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
20930 next_tab_x += tab_width;
20931
20932 it->pixel_width = next_tab_x - x;
20933 it->nglyphs = 1;
20934 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
20935 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
20936
20937 if (it->glyph_row)
20938 {
20939 append_stretch_glyph (it, it->object, it->pixel_width,
20940 it->ascent + it->descent, it->ascent);
20941 }
20942 }
20943 else
20944 {
20945 /* A multi-byte character. Assume that the display width of the
20946 character is the width of the character multiplied by the
20947 width of the font. */
20948
20949 /* If we found a font, this font should give us the right
20950 metrics. If we didn't find a font, use the frame's
20951 default font and calculate the width of the character by
20952 multiplying the width of font by the width of the
20953 character. */
20954
20955 pcm = get_per_char_metric (it->f, font, font_info, &char2b,
20956 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
20957
20958 if (font_not_found_p || !pcm)
20959 {
20960 int char_width = CHAR_WIDTH (it->char_to_display);
20961
20962 if (char_width == 0)
20963 /* This is a non spacing character. But, as we are
20964 going to display an empty box, the box must occupy
20965 at least one column. */
20966 char_width = 1;
20967 it->glyph_not_available_p = 1;
20968 it->pixel_width = FRAME_COLUMN_WIDTH (it->f) * char_width;
20969 it->phys_ascent = FONT_BASE (font) + boff;
20970 it->phys_descent = FONT_DESCENT (font) - boff;
20971 }
20972 else
20973 {
20974 it->pixel_width = pcm->width;
20975 it->phys_ascent = pcm->ascent + boff;
20976 it->phys_descent = pcm->descent - boff;
20977 if (it->glyph_row
20978 && (pcm->lbearing < 0
20979 || pcm->rbearing > pcm->width))
20980 it->glyph_row->contains_overlapping_glyphs_p = 1;
20981 }
20982 it->nglyphs = 1;
20983 it->ascent = FONT_BASE (font) + boff;
20984 it->descent = FONT_DESCENT (font) - boff;
20985 if (face->box != FACE_NO_BOX)
20986 {
20987 int thick = face->box_line_width;
20988
20989 if (thick > 0)
20990 {
20991 it->ascent += thick;
20992 it->descent += thick;
20993 }
20994 else
20995 thick = - thick;
20996
20997 if (it->start_of_box_run_p)
20998 it->pixel_width += thick;
20999 if (it->end_of_box_run_p)
21000 it->pixel_width += thick;
21001 }
21002
21003 /* If face has an overline, add the height of the overline
21004 (1 pixel) and a 1 pixel margin to the character height. */
21005 if (face->overline_p)
21006 it->ascent += overline_margin;
21007
21008 take_vertical_position_into_account (it);
21009
21010 if (it->glyph_row)
21011 append_glyph (it);
21012 }
21013 it->multibyte_p = saved_multibyte_p;
21014 }
21015 else if (it->what == IT_COMPOSITION)
21016 {
21017 /* Note: A composition is represented as one glyph in the
21018 glyph matrix. There are no padding glyphs.
21019
21020 Important is that pixel_width, ascent, and descent are the
21021 values of what is drawn by draw_glyphs (i.e. the values of
21022 the overall glyphs composed). */
21023 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21024 int boff; /* baseline offset */
21025 struct composition *cmp = composition_table[it->cmp_id];
21026 int glyph_len = cmp->glyph_len;
21027 XFontStruct *font = face->font;
21028
21029 it->nglyphs = 1;
21030
21031 #ifdef USE_FONT_BACKEND
21032 if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
21033 {
21034 if (! cmp->font || cmp->font != font)
21035 font_prepare_composition (cmp);
21036 }
21037 else
21038 #endif /* USE_FONT_BACKEND */
21039 /* If we have not yet calculated pixel size data of glyphs of
21040 the composition for the current face font, calculate them
21041 now. Theoretically, we have to check all fonts for the
21042 glyphs, but that requires much time and memory space. So,
21043 here we check only the font of the first glyph. This leads
21044 to incorrect display, but it's very rare, and C-l (recenter)
21045 can correct the display anyway. */
21046 if (! cmp->font || cmp->font != font)
21047 {
21048 /* Ascent and descent of the font of the first character
21049 of this composition (adjusted by baseline offset).
21050 Ascent and descent of overall glyphs should not be less
21051 than them respectively. */
21052 int font_ascent, font_descent, font_height;
21053 /* Bounding box of the overall glyphs. */
21054 int leftmost, rightmost, lowest, highest;
21055 int lbearing, rbearing;
21056 int i, width, ascent, descent;
21057 int left_padded = 0, right_padded = 0;
21058 int face_id;
21059 int c;
21060 XChar2b char2b;
21061 XCharStruct *pcm;
21062 int font_not_found_p;
21063 struct font_info *font_info;
21064 int pos;
21065
21066 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
21067 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
21068 break;
21069 if (glyph_len < cmp->glyph_len)
21070 right_padded = 1;
21071 for (i = 0; i < glyph_len; i++)
21072 {
21073 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
21074 break;
21075 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
21076 }
21077 if (i > 0)
21078 left_padded = 1;
21079
21080 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
21081 : IT_CHARPOS (*it));
21082 /* When no suitable font found, use the default font. */
21083 font_not_found_p = font == NULL;
21084 if (font_not_found_p)
21085 {
21086 face = face->ascii_face;
21087 font = face->font;
21088 }
21089 font_info = FONT_INFO_FROM_FACE (it->f, face);
21090 boff = font_info->baseline_offset;
21091 if (font_info->vertical_centering)
21092 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21093 font_ascent = FONT_BASE (font) + boff;
21094 font_descent = FONT_DESCENT (font) - boff;
21095 font_height = FONT_HEIGHT (font);
21096
21097 cmp->font = (void *) font;
21098
21099 pcm = NULL;
21100 if (! font_not_found_p)
21101 {
21102 get_char_face_and_encoding (it->f, c, it->face_id,
21103 &char2b, it->multibyte_p, 0);
21104 pcm = get_per_char_metric (it->f, font, font_info, &char2b,
21105 FONT_TYPE_FOR_MULTIBYTE (font, c));
21106 }
21107
21108 /* Initialize the bounding box. */
21109 if (pcm)
21110 {
21111 width = pcm->width;
21112 ascent = pcm->ascent;
21113 descent = pcm->descent;
21114 lbearing = pcm->lbearing;
21115 rbearing = pcm->rbearing;
21116 }
21117 else
21118 {
21119 width = FONT_WIDTH (font);
21120 ascent = FONT_BASE (font);
21121 descent = FONT_DESCENT (font);
21122 lbearing = 0;
21123 rbearing = width;
21124 }
21125
21126 rightmost = width;
21127 leftmost = 0;
21128 lowest = - descent + boff;
21129 highest = ascent + boff;
21130
21131 if (! font_not_found_p
21132 && font_info->default_ascent
21133 && CHAR_TABLE_P (Vuse_default_ascent)
21134 && !NILP (Faref (Vuse_default_ascent,
21135 make_number (it->char_to_display))))
21136 highest = font_info->default_ascent + boff;
21137
21138 /* Draw the first glyph at the normal position. It may be
21139 shifted to right later if some other glyphs are drawn
21140 at the left. */
21141 cmp->offsets[i * 2] = 0;
21142 cmp->offsets[i * 2 + 1] = boff;
21143 cmp->lbearing = lbearing;
21144 cmp->rbearing = rbearing;
21145
21146 /* Set cmp->offsets for the remaining glyphs. */
21147 for (i++; i < glyph_len; i++)
21148 {
21149 int left, right, btm, top;
21150 int ch = COMPOSITION_GLYPH (cmp, i);
21151 int face_id;
21152 struct face *this_face;
21153 int this_boff;
21154
21155 if (ch == '\t')
21156 ch = ' ';
21157 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
21158 this_face = FACE_FROM_ID (it->f, face_id);
21159 font = this_face->font;
21160
21161 if (font == NULL)
21162 pcm = NULL;
21163 else
21164 {
21165 font_info = FONT_INFO_FROM_FACE (it->f, this_face);
21166 this_boff = font_info->baseline_offset;
21167 if (font_info->vertical_centering)
21168 this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21169 get_char_face_and_encoding (it->f, ch, face_id,
21170 &char2b, it->multibyte_p, 0);
21171 pcm = get_per_char_metric (it->f, font, font_info, &char2b,
21172 FONT_TYPE_FOR_MULTIBYTE (font,
21173 ch));
21174 }
21175 if (! pcm)
21176 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
21177 else
21178 {
21179 width = pcm->width;
21180 ascent = pcm->ascent;
21181 descent = pcm->descent;
21182 lbearing = pcm->lbearing;
21183 rbearing = pcm->rbearing;
21184 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
21185 {
21186 /* Relative composition with or without
21187 alternate chars. */
21188 left = (leftmost + rightmost - width) / 2;
21189 btm = - descent + boff;
21190 if (font_info->relative_compose
21191 && (! CHAR_TABLE_P (Vignore_relative_composition)
21192 || NILP (Faref (Vignore_relative_composition,
21193 make_number (ch)))))
21194 {
21195
21196 if (- descent >= font_info->relative_compose)
21197 /* One extra pixel between two glyphs. */
21198 btm = highest + 1;
21199 else if (ascent <= 0)
21200 /* One extra pixel between two glyphs. */
21201 btm = lowest - 1 - ascent - descent;
21202 }
21203 }
21204 else
21205 {
21206 /* A composition rule is specified by an integer
21207 value that encodes global and new reference
21208 points (GREF and NREF). GREF and NREF are
21209 specified by numbers as below:
21210
21211 0---1---2 -- ascent
21212 | |
21213 | |
21214 | |
21215 9--10--11 -- center
21216 | |
21217 ---3---4---5--- baseline
21218 | |
21219 6---7---8 -- descent
21220 */
21221 int rule = COMPOSITION_RULE (cmp, i);
21222 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
21223
21224 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
21225 grefx = gref % 3, nrefx = nref % 3;
21226 grefy = gref / 3, nrefy = nref / 3;
21227 if (xoff)
21228 xoff = font_height * (xoff - 128) / 256;
21229 if (yoff)
21230 yoff = font_height * (yoff - 128) / 256;
21231
21232 left = (leftmost
21233 + grefx * (rightmost - leftmost) / 2
21234 - nrefx * width / 2
21235 + xoff);
21236
21237 btm = ((grefy == 0 ? highest
21238 : grefy == 1 ? 0
21239 : grefy == 2 ? lowest
21240 : (highest + lowest) / 2)
21241 - (nrefy == 0 ? ascent + descent
21242 : nrefy == 1 ? descent - boff
21243 : nrefy == 2 ? 0
21244 : (ascent + descent) / 2)
21245 + yoff);
21246 }
21247
21248 cmp->offsets[i * 2] = left;
21249 cmp->offsets[i * 2 + 1] = btm + descent;
21250
21251 /* Update the bounding box of the overall glyphs. */
21252 if (width > 0)
21253 {
21254 right = left + width;
21255 if (left < leftmost)
21256 leftmost = left;
21257 if (right > rightmost)
21258 rightmost = right;
21259 }
21260 top = btm + descent + ascent;
21261 if (top > highest)
21262 highest = top;
21263 if (btm < lowest)
21264 lowest = btm;
21265
21266 if (cmp->lbearing > left + lbearing)
21267 cmp->lbearing = left + lbearing;
21268 if (cmp->rbearing < left + rbearing)
21269 cmp->rbearing = left + rbearing;
21270 }
21271 }
21272
21273 /* If there are glyphs whose x-offsets are negative,
21274 shift all glyphs to the right and make all x-offsets
21275 non-negative. */
21276 if (leftmost < 0)
21277 {
21278 for (i = 0; i < cmp->glyph_len; i++)
21279 cmp->offsets[i * 2] -= leftmost;
21280 rightmost -= leftmost;
21281 cmp->lbearing -= leftmost;
21282 cmp->rbearing -= leftmost;
21283 }
21284
21285 if (left_padded && cmp->lbearing < 0)
21286 {
21287 for (i = 0; i < cmp->glyph_len; i++)
21288 cmp->offsets[i * 2] -= cmp->lbearing;
21289 rightmost -= cmp->lbearing;
21290 cmp->rbearing -= cmp->lbearing;
21291 cmp->lbearing = 0;
21292 }
21293 if (right_padded && rightmost < cmp->rbearing)
21294 {
21295 rightmost = cmp->rbearing;
21296 }
21297
21298 cmp->pixel_width = rightmost;
21299 cmp->ascent = highest;
21300 cmp->descent = - lowest;
21301 if (cmp->ascent < font_ascent)
21302 cmp->ascent = font_ascent;
21303 if (cmp->descent < font_descent)
21304 cmp->descent = font_descent;
21305 }
21306
21307 if (it->glyph_row
21308 && (cmp->lbearing < 0
21309 || cmp->rbearing > cmp->pixel_width))
21310 it->glyph_row->contains_overlapping_glyphs_p = 1;
21311
21312 it->pixel_width = cmp->pixel_width;
21313 it->ascent = it->phys_ascent = cmp->ascent;
21314 it->descent = it->phys_descent = cmp->descent;
21315
21316 if (face->box != FACE_NO_BOX)
21317 {
21318 int thick = face->box_line_width;
21319
21320 if (thick > 0)
21321 {
21322 it->ascent += thick;
21323 it->descent += thick;
21324 }
21325 else
21326 thick = - thick;
21327
21328 if (it->start_of_box_run_p)
21329 it->pixel_width += thick;
21330 if (it->end_of_box_run_p)
21331 it->pixel_width += thick;
21332 }
21333
21334 /* If face has an overline, add the height of the overline
21335 (1 pixel) and a 1 pixel margin to the character height. */
21336 if (face->overline_p)
21337 it->ascent += overline_margin;
21338
21339 take_vertical_position_into_account (it);
21340
21341 if (it->glyph_row)
21342 append_composite_glyph (it);
21343 }
21344 else if (it->what == IT_IMAGE)
21345 produce_image_glyph (it);
21346 else if (it->what == IT_STRETCH)
21347 produce_stretch_glyph (it);
21348
21349 /* Accumulate dimensions. Note: can't assume that it->descent > 0
21350 because this isn't true for images with `:ascent 100'. */
21351 xassert (it->ascent >= 0 && it->descent >= 0);
21352 if (it->area == TEXT_AREA)
21353 it->current_x += it->pixel_width;
21354
21355 if (extra_line_spacing > 0)
21356 {
21357 it->descent += extra_line_spacing;
21358 if (extra_line_spacing > it->max_extra_line_spacing)
21359 it->max_extra_line_spacing = extra_line_spacing;
21360 }
21361
21362 it->max_ascent = max (it->max_ascent, it->ascent);
21363 it->max_descent = max (it->max_descent, it->descent);
21364 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
21365 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
21366 }
21367
21368 /* EXPORT for RIF:
21369 Output LEN glyphs starting at START at the nominal cursor position.
21370 Advance the nominal cursor over the text. The global variable
21371 updated_window contains the window being updated, updated_row is
21372 the glyph row being updated, and updated_area is the area of that
21373 row being updated. */
21374
21375 void
21376 x_write_glyphs (start, len)
21377 struct glyph *start;
21378 int len;
21379 {
21380 int x, hpos;
21381
21382 xassert (updated_window && updated_row);
21383 BLOCK_INPUT;
21384
21385 /* Write glyphs. */
21386
21387 hpos = start - updated_row->glyphs[updated_area];
21388 x = draw_glyphs (updated_window, output_cursor.x,
21389 updated_row, updated_area,
21390 hpos, hpos + len,
21391 DRAW_NORMAL_TEXT, 0);
21392
21393 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
21394 if (updated_area == TEXT_AREA
21395 && updated_window->phys_cursor_on_p
21396 && updated_window->phys_cursor.vpos == output_cursor.vpos
21397 && updated_window->phys_cursor.hpos >= hpos
21398 && updated_window->phys_cursor.hpos < hpos + len)
21399 updated_window->phys_cursor_on_p = 0;
21400
21401 UNBLOCK_INPUT;
21402
21403 /* Advance the output cursor. */
21404 output_cursor.hpos += len;
21405 output_cursor.x = x;
21406 }
21407
21408
21409 /* EXPORT for RIF:
21410 Insert LEN glyphs from START at the nominal cursor position. */
21411
21412 void
21413 x_insert_glyphs (start, len)
21414 struct glyph *start;
21415 int len;
21416 {
21417 struct frame *f;
21418 struct window *w;
21419 int line_height, shift_by_width, shifted_region_width;
21420 struct glyph_row *row;
21421 struct glyph *glyph;
21422 int frame_x, frame_y;
21423 EMACS_INT hpos;
21424
21425 xassert (updated_window && updated_row);
21426 BLOCK_INPUT;
21427 w = updated_window;
21428 f = XFRAME (WINDOW_FRAME (w));
21429
21430 /* Get the height of the line we are in. */
21431 row = updated_row;
21432 line_height = row->height;
21433
21434 /* Get the width of the glyphs to insert. */
21435 shift_by_width = 0;
21436 for (glyph = start; glyph < start + len; ++glyph)
21437 shift_by_width += glyph->pixel_width;
21438
21439 /* Get the width of the region to shift right. */
21440 shifted_region_width = (window_box_width (w, updated_area)
21441 - output_cursor.x
21442 - shift_by_width);
21443
21444 /* Shift right. */
21445 frame_x = window_box_left (w, updated_area) + output_cursor.x;
21446 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
21447
21448 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
21449 line_height, shift_by_width);
21450
21451 /* Write the glyphs. */
21452 hpos = start - row->glyphs[updated_area];
21453 draw_glyphs (w, output_cursor.x, row, updated_area,
21454 hpos, hpos + len,
21455 DRAW_NORMAL_TEXT, 0);
21456
21457 /* Advance the output cursor. */
21458 output_cursor.hpos += len;
21459 output_cursor.x += shift_by_width;
21460 UNBLOCK_INPUT;
21461 }
21462
21463
21464 /* EXPORT for RIF:
21465 Erase the current text line from the nominal cursor position
21466 (inclusive) to pixel column TO_X (exclusive). The idea is that
21467 everything from TO_X onward is already erased.
21468
21469 TO_X is a pixel position relative to updated_area of
21470 updated_window. TO_X == -1 means clear to the end of this area. */
21471
21472 void
21473 x_clear_end_of_line (to_x)
21474 int to_x;
21475 {
21476 struct frame *f;
21477 struct window *w = updated_window;
21478 int max_x, min_y, max_y;
21479 int from_x, from_y, to_y;
21480
21481 xassert (updated_window && updated_row);
21482 f = XFRAME (w->frame);
21483
21484 if (updated_row->full_width_p)
21485 max_x = WINDOW_TOTAL_WIDTH (w);
21486 else
21487 max_x = window_box_width (w, updated_area);
21488 max_y = window_text_bottom_y (w);
21489
21490 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
21491 of window. For TO_X > 0, truncate to end of drawing area. */
21492 if (to_x == 0)
21493 return;
21494 else if (to_x < 0)
21495 to_x = max_x;
21496 else
21497 to_x = min (to_x, max_x);
21498
21499 to_y = min (max_y, output_cursor.y + updated_row->height);
21500
21501 /* Notice if the cursor will be cleared by this operation. */
21502 if (!updated_row->full_width_p)
21503 notice_overwritten_cursor (w, updated_area,
21504 output_cursor.x, -1,
21505 updated_row->y,
21506 MATRIX_ROW_BOTTOM_Y (updated_row));
21507
21508 from_x = output_cursor.x;
21509
21510 /* Translate to frame coordinates. */
21511 if (updated_row->full_width_p)
21512 {
21513 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
21514 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
21515 }
21516 else
21517 {
21518 int area_left = window_box_left (w, updated_area);
21519 from_x += area_left;
21520 to_x += area_left;
21521 }
21522
21523 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
21524 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
21525 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
21526
21527 /* Prevent inadvertently clearing to end of the X window. */
21528 if (to_x > from_x && to_y > from_y)
21529 {
21530 BLOCK_INPUT;
21531 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
21532 to_x - from_x, to_y - from_y);
21533 UNBLOCK_INPUT;
21534 }
21535 }
21536
21537 #endif /* HAVE_WINDOW_SYSTEM */
21538
21539
21540 \f
21541 /***********************************************************************
21542 Cursor types
21543 ***********************************************************************/
21544
21545 /* Value is the internal representation of the specified cursor type
21546 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
21547 of the bar cursor. */
21548
21549 static enum text_cursor_kinds
21550 get_specified_cursor_type (arg, width)
21551 Lisp_Object arg;
21552 int *width;
21553 {
21554 enum text_cursor_kinds type;
21555
21556 if (NILP (arg))
21557 return NO_CURSOR;
21558
21559 if (EQ (arg, Qbox))
21560 return FILLED_BOX_CURSOR;
21561
21562 if (EQ (arg, Qhollow))
21563 return HOLLOW_BOX_CURSOR;
21564
21565 if (EQ (arg, Qbar))
21566 {
21567 *width = 2;
21568 return BAR_CURSOR;
21569 }
21570
21571 if (CONSP (arg)
21572 && EQ (XCAR (arg), Qbar)
21573 && INTEGERP (XCDR (arg))
21574 && XINT (XCDR (arg)) >= 0)
21575 {
21576 *width = XINT (XCDR (arg));
21577 return BAR_CURSOR;
21578 }
21579
21580 if (EQ (arg, Qhbar))
21581 {
21582 *width = 2;
21583 return HBAR_CURSOR;
21584 }
21585
21586 if (CONSP (arg)
21587 && EQ (XCAR (arg), Qhbar)
21588 && INTEGERP (XCDR (arg))
21589 && XINT (XCDR (arg)) >= 0)
21590 {
21591 *width = XINT (XCDR (arg));
21592 return HBAR_CURSOR;
21593 }
21594
21595 /* Treat anything unknown as "hollow box cursor".
21596 It was bad to signal an error; people have trouble fixing
21597 .Xdefaults with Emacs, when it has something bad in it. */
21598 type = HOLLOW_BOX_CURSOR;
21599
21600 return type;
21601 }
21602
21603 /* Set the default cursor types for specified frame. */
21604 void
21605 set_frame_cursor_types (f, arg)
21606 struct frame *f;
21607 Lisp_Object arg;
21608 {
21609 int width;
21610 Lisp_Object tem;
21611
21612 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
21613 FRAME_CURSOR_WIDTH (f) = width;
21614
21615 /* By default, set up the blink-off state depending on the on-state. */
21616
21617 tem = Fassoc (arg, Vblink_cursor_alist);
21618 if (!NILP (tem))
21619 {
21620 FRAME_BLINK_OFF_CURSOR (f)
21621 = get_specified_cursor_type (XCDR (tem), &width);
21622 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
21623 }
21624 else
21625 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
21626 }
21627
21628
21629 /* Return the cursor we want to be displayed in window W. Return
21630 width of bar/hbar cursor through WIDTH arg. Return with
21631 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
21632 (i.e. if the `system caret' should track this cursor).
21633
21634 In a mini-buffer window, we want the cursor only to appear if we
21635 are reading input from this window. For the selected window, we
21636 want the cursor type given by the frame parameter or buffer local
21637 setting of cursor-type. If explicitly marked off, draw no cursor.
21638 In all other cases, we want a hollow box cursor. */
21639
21640 static enum text_cursor_kinds
21641 get_window_cursor_type (w, glyph, width, active_cursor)
21642 struct window *w;
21643 struct glyph *glyph;
21644 int *width;
21645 int *active_cursor;
21646 {
21647 struct frame *f = XFRAME (w->frame);
21648 struct buffer *b = XBUFFER (w->buffer);
21649 int cursor_type = DEFAULT_CURSOR;
21650 Lisp_Object alt_cursor;
21651 int non_selected = 0;
21652
21653 *active_cursor = 1;
21654
21655 /* Echo area */
21656 if (cursor_in_echo_area
21657 && FRAME_HAS_MINIBUF_P (f)
21658 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
21659 {
21660 if (w == XWINDOW (echo_area_window))
21661 {
21662 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
21663 {
21664 *width = FRAME_CURSOR_WIDTH (f);
21665 return FRAME_DESIRED_CURSOR (f);
21666 }
21667 else
21668 return get_specified_cursor_type (b->cursor_type, width);
21669 }
21670
21671 *active_cursor = 0;
21672 non_selected = 1;
21673 }
21674
21675 /* Detect a nonselected window or nonselected frame. */
21676 else if (w != XWINDOW (f->selected_window)
21677 #ifdef HAVE_WINDOW_SYSTEM
21678 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
21679 #endif
21680 )
21681 {
21682 *active_cursor = 0;
21683
21684 if (MINI_WINDOW_P (w) && minibuf_level == 0)
21685 return NO_CURSOR;
21686
21687 non_selected = 1;
21688 }
21689
21690 /* Never display a cursor in a window in which cursor-type is nil. */
21691 if (NILP (b->cursor_type))
21692 return NO_CURSOR;
21693
21694 /* Get the normal cursor type for this window. */
21695 if (EQ (b->cursor_type, Qt))
21696 {
21697 cursor_type = FRAME_DESIRED_CURSOR (f);
21698 *width = FRAME_CURSOR_WIDTH (f);
21699 }
21700 else
21701 cursor_type = get_specified_cursor_type (b->cursor_type, width);
21702
21703 /* Use cursor-in-non-selected-windows instead
21704 for non-selected window or frame. */
21705 if (non_selected)
21706 {
21707 alt_cursor = b->cursor_in_non_selected_windows;
21708 if (!EQ (Qt, alt_cursor))
21709 return get_specified_cursor_type (alt_cursor, width);
21710 /* t means modify the normal cursor type. */
21711 if (cursor_type == FILLED_BOX_CURSOR)
21712 cursor_type = HOLLOW_BOX_CURSOR;
21713 else if (cursor_type == BAR_CURSOR && *width > 1)
21714 --*width;
21715 return cursor_type;
21716 }
21717
21718 /* Use normal cursor if not blinked off. */
21719 if (!w->cursor_off_p)
21720 {
21721 #ifdef HAVE_WINDOW_SYSTEM
21722 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21723 {
21724 if (cursor_type == FILLED_BOX_CURSOR)
21725 {
21726 /* Using a block cursor on large images can be very annoying.
21727 So use a hollow cursor for "large" images.
21728 If image is not transparent (no mask), also use hollow cursor. */
21729 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21730 if (img != NULL && IMAGEP (img->spec))
21731 {
21732 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
21733 where N = size of default frame font size.
21734 This should cover most of the "tiny" icons people may use. */
21735 if (!img->mask
21736 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
21737 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
21738 cursor_type = HOLLOW_BOX_CURSOR;
21739 }
21740 }
21741 else if (cursor_type != NO_CURSOR)
21742 {
21743 /* Display current only supports BOX and HOLLOW cursors for images.
21744 So for now, unconditionally use a HOLLOW cursor when cursor is
21745 not a solid box cursor. */
21746 cursor_type = HOLLOW_BOX_CURSOR;
21747 }
21748 }
21749 #endif
21750 return cursor_type;
21751 }
21752
21753 /* Cursor is blinked off, so determine how to "toggle" it. */
21754
21755 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
21756 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
21757 return get_specified_cursor_type (XCDR (alt_cursor), width);
21758
21759 /* Then see if frame has specified a specific blink off cursor type. */
21760 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
21761 {
21762 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
21763 return FRAME_BLINK_OFF_CURSOR (f);
21764 }
21765
21766 #if 0
21767 /* Some people liked having a permanently visible blinking cursor,
21768 while others had very strong opinions against it. So it was
21769 decided to remove it. KFS 2003-09-03 */
21770
21771 /* Finally perform built-in cursor blinking:
21772 filled box <-> hollow box
21773 wide [h]bar <-> narrow [h]bar
21774 narrow [h]bar <-> no cursor
21775 other type <-> no cursor */
21776
21777 if (cursor_type == FILLED_BOX_CURSOR)
21778 return HOLLOW_BOX_CURSOR;
21779
21780 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
21781 {
21782 *width = 1;
21783 return cursor_type;
21784 }
21785 #endif
21786
21787 return NO_CURSOR;
21788 }
21789
21790
21791 #ifdef HAVE_WINDOW_SYSTEM
21792
21793 /* Notice when the text cursor of window W has been completely
21794 overwritten by a drawing operation that outputs glyphs in AREA
21795 starting at X0 and ending at X1 in the line starting at Y0 and
21796 ending at Y1. X coordinates are area-relative. X1 < 0 means all
21797 the rest of the line after X0 has been written. Y coordinates
21798 are window-relative. */
21799
21800 static void
21801 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
21802 struct window *w;
21803 enum glyph_row_area area;
21804 int x0, y0, x1, y1;
21805 {
21806 int cx0, cx1, cy0, cy1;
21807 struct glyph_row *row;
21808
21809 if (!w->phys_cursor_on_p)
21810 return;
21811 if (area != TEXT_AREA)
21812 return;
21813
21814 if (w->phys_cursor.vpos < 0
21815 || w->phys_cursor.vpos >= w->current_matrix->nrows
21816 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
21817 !(row->enabled_p && row->displays_text_p)))
21818 return;
21819
21820 if (row->cursor_in_fringe_p)
21821 {
21822 row->cursor_in_fringe_p = 0;
21823 draw_fringe_bitmap (w, row, 0);
21824 w->phys_cursor_on_p = 0;
21825 return;
21826 }
21827
21828 cx0 = w->phys_cursor.x;
21829 cx1 = cx0 + w->phys_cursor_width;
21830 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
21831 return;
21832
21833 /* The cursor image will be completely removed from the
21834 screen if the output area intersects the cursor area in
21835 y-direction. When we draw in [y0 y1[, and some part of
21836 the cursor is at y < y0, that part must have been drawn
21837 before. When scrolling, the cursor is erased before
21838 actually scrolling, so we don't come here. When not
21839 scrolling, the rows above the old cursor row must have
21840 changed, and in this case these rows must have written
21841 over the cursor image.
21842
21843 Likewise if part of the cursor is below y1, with the
21844 exception of the cursor being in the first blank row at
21845 the buffer and window end because update_text_area
21846 doesn't draw that row. (Except when it does, but
21847 that's handled in update_text_area.) */
21848
21849 cy0 = w->phys_cursor.y;
21850 cy1 = cy0 + w->phys_cursor_height;
21851 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
21852 return;
21853
21854 w->phys_cursor_on_p = 0;
21855 }
21856
21857 #endif /* HAVE_WINDOW_SYSTEM */
21858
21859 \f
21860 /************************************************************************
21861 Mouse Face
21862 ************************************************************************/
21863
21864 #ifdef HAVE_WINDOW_SYSTEM
21865
21866 /* EXPORT for RIF:
21867 Fix the display of area AREA of overlapping row ROW in window W
21868 with respect to the overlapping part OVERLAPS. */
21869
21870 void
21871 x_fix_overlapping_area (w, row, area, overlaps)
21872 struct window *w;
21873 struct glyph_row *row;
21874 enum glyph_row_area area;
21875 int overlaps;
21876 {
21877 int i, x;
21878
21879 BLOCK_INPUT;
21880
21881 x = 0;
21882 for (i = 0; i < row->used[area];)
21883 {
21884 if (row->glyphs[area][i].overlaps_vertically_p)
21885 {
21886 int start = i, start_x = x;
21887
21888 do
21889 {
21890 x += row->glyphs[area][i].pixel_width;
21891 ++i;
21892 }
21893 while (i < row->used[area]
21894 && row->glyphs[area][i].overlaps_vertically_p);
21895
21896 draw_glyphs (w, start_x, row, area,
21897 start, i,
21898 DRAW_NORMAL_TEXT, overlaps);
21899 }
21900 else
21901 {
21902 x += row->glyphs[area][i].pixel_width;
21903 ++i;
21904 }
21905 }
21906
21907 UNBLOCK_INPUT;
21908 }
21909
21910
21911 /* EXPORT:
21912 Draw the cursor glyph of window W in glyph row ROW. See the
21913 comment of draw_glyphs for the meaning of HL. */
21914
21915 void
21916 draw_phys_cursor_glyph (w, row, hl)
21917 struct window *w;
21918 struct glyph_row *row;
21919 enum draw_glyphs_face hl;
21920 {
21921 /* If cursor hpos is out of bounds, don't draw garbage. This can
21922 happen in mini-buffer windows when switching between echo area
21923 glyphs and mini-buffer. */
21924 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
21925 {
21926 int on_p = w->phys_cursor_on_p;
21927 int x1;
21928 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
21929 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
21930 hl, 0);
21931 w->phys_cursor_on_p = on_p;
21932
21933 if (hl == DRAW_CURSOR)
21934 w->phys_cursor_width = x1 - w->phys_cursor.x;
21935 /* When we erase the cursor, and ROW is overlapped by other
21936 rows, make sure that these overlapping parts of other rows
21937 are redrawn. */
21938 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
21939 {
21940 w->phys_cursor_width = x1 - w->phys_cursor.x;
21941
21942 if (row > w->current_matrix->rows
21943 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
21944 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
21945 OVERLAPS_ERASED_CURSOR);
21946
21947 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
21948 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
21949 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
21950 OVERLAPS_ERASED_CURSOR);
21951 }
21952 }
21953 }
21954
21955
21956 /* EXPORT:
21957 Erase the image of a cursor of window W from the screen. */
21958
21959 void
21960 erase_phys_cursor (w)
21961 struct window *w;
21962 {
21963 struct frame *f = XFRAME (w->frame);
21964 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21965 int hpos = w->phys_cursor.hpos;
21966 int vpos = w->phys_cursor.vpos;
21967 int mouse_face_here_p = 0;
21968 struct glyph_matrix *active_glyphs = w->current_matrix;
21969 struct glyph_row *cursor_row;
21970 struct glyph *cursor_glyph;
21971 enum draw_glyphs_face hl;
21972
21973 /* No cursor displayed or row invalidated => nothing to do on the
21974 screen. */
21975 if (w->phys_cursor_type == NO_CURSOR)
21976 goto mark_cursor_off;
21977
21978 /* VPOS >= active_glyphs->nrows means that window has been resized.
21979 Don't bother to erase the cursor. */
21980 if (vpos >= active_glyphs->nrows)
21981 goto mark_cursor_off;
21982
21983 /* If row containing cursor is marked invalid, there is nothing we
21984 can do. */
21985 cursor_row = MATRIX_ROW (active_glyphs, vpos);
21986 if (!cursor_row->enabled_p)
21987 goto mark_cursor_off;
21988
21989 /* If line spacing is > 0, old cursor may only be partially visible in
21990 window after split-window. So adjust visible height. */
21991 cursor_row->visible_height = min (cursor_row->visible_height,
21992 window_text_bottom_y (w) - cursor_row->y);
21993
21994 /* If row is completely invisible, don't attempt to delete a cursor which
21995 isn't there. This can happen if cursor is at top of a window, and
21996 we switch to a buffer with a header line in that window. */
21997 if (cursor_row->visible_height <= 0)
21998 goto mark_cursor_off;
21999
22000 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
22001 if (cursor_row->cursor_in_fringe_p)
22002 {
22003 cursor_row->cursor_in_fringe_p = 0;
22004 draw_fringe_bitmap (w, cursor_row, 0);
22005 goto mark_cursor_off;
22006 }
22007
22008 /* This can happen when the new row is shorter than the old one.
22009 In this case, either draw_glyphs or clear_end_of_line
22010 should have cleared the cursor. Note that we wouldn't be
22011 able to erase the cursor in this case because we don't have a
22012 cursor glyph at hand. */
22013 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
22014 goto mark_cursor_off;
22015
22016 /* If the cursor is in the mouse face area, redisplay that when
22017 we clear the cursor. */
22018 if (! NILP (dpyinfo->mouse_face_window)
22019 && w == XWINDOW (dpyinfo->mouse_face_window)
22020 && (vpos > dpyinfo->mouse_face_beg_row
22021 || (vpos == dpyinfo->mouse_face_beg_row
22022 && hpos >= dpyinfo->mouse_face_beg_col))
22023 && (vpos < dpyinfo->mouse_face_end_row
22024 || (vpos == dpyinfo->mouse_face_end_row
22025 && hpos < dpyinfo->mouse_face_end_col))
22026 /* Don't redraw the cursor's spot in mouse face if it is at the
22027 end of a line (on a newline). The cursor appears there, but
22028 mouse highlighting does not. */
22029 && cursor_row->used[TEXT_AREA] > hpos)
22030 mouse_face_here_p = 1;
22031
22032 /* Maybe clear the display under the cursor. */
22033 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
22034 {
22035 int x, y, left_x;
22036 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
22037 int width;
22038
22039 cursor_glyph = get_phys_cursor_glyph (w);
22040 if (cursor_glyph == NULL)
22041 goto mark_cursor_off;
22042
22043 width = cursor_glyph->pixel_width;
22044 left_x = window_box_left_offset (w, TEXT_AREA);
22045 x = w->phys_cursor.x;
22046 if (x < left_x)
22047 width -= left_x - x;
22048 width = min (width, window_box_width (w, TEXT_AREA) - x);
22049 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
22050 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
22051
22052 if (width > 0)
22053 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
22054 }
22055
22056 /* Erase the cursor by redrawing the character underneath it. */
22057 if (mouse_face_here_p)
22058 hl = DRAW_MOUSE_FACE;
22059 else
22060 hl = DRAW_NORMAL_TEXT;
22061 draw_phys_cursor_glyph (w, cursor_row, hl);
22062
22063 mark_cursor_off:
22064 w->phys_cursor_on_p = 0;
22065 w->phys_cursor_type = NO_CURSOR;
22066 }
22067
22068
22069 /* EXPORT:
22070 Display or clear cursor of window W. If ON is zero, clear the
22071 cursor. If it is non-zero, display the cursor. If ON is nonzero,
22072 where to put the cursor is specified by HPOS, VPOS, X and Y. */
22073
22074 void
22075 display_and_set_cursor (w, on, hpos, vpos, x, y)
22076 struct window *w;
22077 int on, hpos, vpos, x, y;
22078 {
22079 struct frame *f = XFRAME (w->frame);
22080 int new_cursor_type;
22081 int new_cursor_width;
22082 int active_cursor;
22083 struct glyph_row *glyph_row;
22084 struct glyph *glyph;
22085
22086 /* This is pointless on invisible frames, and dangerous on garbaged
22087 windows and frames; in the latter case, the frame or window may
22088 be in the midst of changing its size, and x and y may be off the
22089 window. */
22090 if (! FRAME_VISIBLE_P (f)
22091 || FRAME_GARBAGED_P (f)
22092 || vpos >= w->current_matrix->nrows
22093 || hpos >= w->current_matrix->matrix_w)
22094 return;
22095
22096 /* If cursor is off and we want it off, return quickly. */
22097 if (!on && !w->phys_cursor_on_p)
22098 return;
22099
22100 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
22101 /* If cursor row is not enabled, we don't really know where to
22102 display the cursor. */
22103 if (!glyph_row->enabled_p)
22104 {
22105 w->phys_cursor_on_p = 0;
22106 return;
22107 }
22108
22109 glyph = NULL;
22110 if (!glyph_row->exact_window_width_line_p
22111 || hpos < glyph_row->used[TEXT_AREA])
22112 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
22113
22114 xassert (interrupt_input_blocked);
22115
22116 /* Set new_cursor_type to the cursor we want to be displayed. */
22117 new_cursor_type = get_window_cursor_type (w, glyph,
22118 &new_cursor_width, &active_cursor);
22119
22120 /* If cursor is currently being shown and we don't want it to be or
22121 it is in the wrong place, or the cursor type is not what we want,
22122 erase it. */
22123 if (w->phys_cursor_on_p
22124 && (!on
22125 || w->phys_cursor.x != x
22126 || w->phys_cursor.y != y
22127 || new_cursor_type != w->phys_cursor_type
22128 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
22129 && new_cursor_width != w->phys_cursor_width)))
22130 erase_phys_cursor (w);
22131
22132 /* Don't check phys_cursor_on_p here because that flag is only set
22133 to zero in some cases where we know that the cursor has been
22134 completely erased, to avoid the extra work of erasing the cursor
22135 twice. In other words, phys_cursor_on_p can be 1 and the cursor
22136 still not be visible, or it has only been partly erased. */
22137 if (on)
22138 {
22139 w->phys_cursor_ascent = glyph_row->ascent;
22140 w->phys_cursor_height = glyph_row->height;
22141
22142 /* Set phys_cursor_.* before x_draw_.* is called because some
22143 of them may need the information. */
22144 w->phys_cursor.x = x;
22145 w->phys_cursor.y = glyph_row->y;
22146 w->phys_cursor.hpos = hpos;
22147 w->phys_cursor.vpos = vpos;
22148 }
22149
22150 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
22151 new_cursor_type, new_cursor_width,
22152 on, active_cursor);
22153 }
22154
22155
22156 /* Switch the display of W's cursor on or off, according to the value
22157 of ON. */
22158
22159 static void
22160 update_window_cursor (w, on)
22161 struct window *w;
22162 int on;
22163 {
22164 /* Don't update cursor in windows whose frame is in the process
22165 of being deleted. */
22166 if (w->current_matrix)
22167 {
22168 BLOCK_INPUT;
22169 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
22170 w->phys_cursor.x, w->phys_cursor.y);
22171 UNBLOCK_INPUT;
22172 }
22173 }
22174
22175
22176 /* Call update_window_cursor with parameter ON_P on all leaf windows
22177 in the window tree rooted at W. */
22178
22179 static void
22180 update_cursor_in_window_tree (w, on_p)
22181 struct window *w;
22182 int on_p;
22183 {
22184 while (w)
22185 {
22186 if (!NILP (w->hchild))
22187 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
22188 else if (!NILP (w->vchild))
22189 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
22190 else
22191 update_window_cursor (w, on_p);
22192
22193 w = NILP (w->next) ? 0 : XWINDOW (w->next);
22194 }
22195 }
22196
22197
22198 /* EXPORT:
22199 Display the cursor on window W, or clear it, according to ON_P.
22200 Don't change the cursor's position. */
22201
22202 void
22203 x_update_cursor (f, on_p)
22204 struct frame *f;
22205 int on_p;
22206 {
22207 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
22208 }
22209
22210
22211 /* EXPORT:
22212 Clear the cursor of window W to background color, and mark the
22213 cursor as not shown. This is used when the text where the cursor
22214 is is about to be rewritten. */
22215
22216 void
22217 x_clear_cursor (w)
22218 struct window *w;
22219 {
22220 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
22221 update_window_cursor (w, 0);
22222 }
22223
22224
22225 /* EXPORT:
22226 Display the active region described by mouse_face_* according to DRAW. */
22227
22228 void
22229 show_mouse_face (dpyinfo, draw)
22230 Display_Info *dpyinfo;
22231 enum draw_glyphs_face draw;
22232 {
22233 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
22234 struct frame *f = XFRAME (WINDOW_FRAME (w));
22235
22236 if (/* If window is in the process of being destroyed, don't bother
22237 to do anything. */
22238 w->current_matrix != NULL
22239 /* Don't update mouse highlight if hidden */
22240 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
22241 /* Recognize when we are called to operate on rows that don't exist
22242 anymore. This can happen when a window is split. */
22243 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
22244 {
22245 int phys_cursor_on_p = w->phys_cursor_on_p;
22246 struct glyph_row *row, *first, *last;
22247
22248 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
22249 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
22250
22251 for (row = first; row <= last && row->enabled_p; ++row)
22252 {
22253 int start_hpos, end_hpos, start_x;
22254
22255 /* For all but the first row, the highlight starts at column 0. */
22256 if (row == first)
22257 {
22258 start_hpos = dpyinfo->mouse_face_beg_col;
22259 start_x = dpyinfo->mouse_face_beg_x;
22260 }
22261 else
22262 {
22263 start_hpos = 0;
22264 start_x = 0;
22265 }
22266
22267 if (row == last)
22268 end_hpos = dpyinfo->mouse_face_end_col;
22269 else
22270 {
22271 end_hpos = row->used[TEXT_AREA];
22272 if (draw == DRAW_NORMAL_TEXT)
22273 row->fill_line_p = 1; /* Clear to end of line */
22274 }
22275
22276 if (end_hpos > start_hpos)
22277 {
22278 draw_glyphs (w, start_x, row, TEXT_AREA,
22279 start_hpos, end_hpos,
22280 draw, 0);
22281
22282 row->mouse_face_p
22283 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
22284 }
22285 }
22286
22287 /* When we've written over the cursor, arrange for it to
22288 be displayed again. */
22289 if (phys_cursor_on_p && !w->phys_cursor_on_p)
22290 {
22291 BLOCK_INPUT;
22292 display_and_set_cursor (w, 1,
22293 w->phys_cursor.hpos, w->phys_cursor.vpos,
22294 w->phys_cursor.x, w->phys_cursor.y);
22295 UNBLOCK_INPUT;
22296 }
22297 }
22298
22299 /* Change the mouse cursor. */
22300 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
22301 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
22302 else if (draw == DRAW_MOUSE_FACE)
22303 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
22304 else
22305 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
22306 }
22307
22308 /* EXPORT:
22309 Clear out the mouse-highlighted active region.
22310 Redraw it un-highlighted first. Value is non-zero if mouse
22311 face was actually drawn unhighlighted. */
22312
22313 int
22314 clear_mouse_face (dpyinfo)
22315 Display_Info *dpyinfo;
22316 {
22317 int cleared = 0;
22318
22319 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
22320 {
22321 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
22322 cleared = 1;
22323 }
22324
22325 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
22326 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
22327 dpyinfo->mouse_face_window = Qnil;
22328 dpyinfo->mouse_face_overlay = Qnil;
22329 return cleared;
22330 }
22331
22332
22333 /* EXPORT:
22334 Non-zero if physical cursor of window W is within mouse face. */
22335
22336 int
22337 cursor_in_mouse_face_p (w)
22338 struct window *w;
22339 {
22340 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
22341 int in_mouse_face = 0;
22342
22343 if (WINDOWP (dpyinfo->mouse_face_window)
22344 && XWINDOW (dpyinfo->mouse_face_window) == w)
22345 {
22346 int hpos = w->phys_cursor.hpos;
22347 int vpos = w->phys_cursor.vpos;
22348
22349 if (vpos >= dpyinfo->mouse_face_beg_row
22350 && vpos <= dpyinfo->mouse_face_end_row
22351 && (vpos > dpyinfo->mouse_face_beg_row
22352 || hpos >= dpyinfo->mouse_face_beg_col)
22353 && (vpos < dpyinfo->mouse_face_end_row
22354 || hpos < dpyinfo->mouse_face_end_col
22355 || dpyinfo->mouse_face_past_end))
22356 in_mouse_face = 1;
22357 }
22358
22359 return in_mouse_face;
22360 }
22361
22362
22363
22364 \f
22365 /* Find the glyph matrix position of buffer position CHARPOS in window
22366 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
22367 current glyphs must be up to date. If CHARPOS is above window
22368 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
22369 of last line in W. In the row containing CHARPOS, stop before glyphs
22370 having STOP as object. */
22371
22372 #if 1 /* This is a version of fast_find_position that's more correct
22373 in the presence of hscrolling, for example. I didn't install
22374 it right away because the problem fixed is minor, it failed
22375 in 20.x as well, and I think it's too risky to install
22376 so near the release of 21.1. 2001-09-25 gerd. */
22377
22378 static int
22379 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
22380 struct window *w;
22381 EMACS_INT charpos;
22382 int *hpos, *vpos, *x, *y;
22383 Lisp_Object stop;
22384 {
22385 struct glyph_row *row, *first;
22386 struct glyph *glyph, *end;
22387 int past_end = 0;
22388
22389 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22390 if (charpos < MATRIX_ROW_START_CHARPOS (first))
22391 {
22392 *x = first->x;
22393 *y = first->y;
22394 *hpos = 0;
22395 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
22396 return 1;
22397 }
22398
22399 row = row_containing_pos (w, charpos, first, NULL, 0);
22400 if (row == NULL)
22401 {
22402 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22403 past_end = 1;
22404 }
22405
22406 /* If whole rows or last part of a row came from a display overlay,
22407 row_containing_pos will skip over such rows because their end pos
22408 equals the start pos of the overlay or interval.
22409
22410 Move back if we have a STOP object and previous row's
22411 end glyph came from STOP. */
22412 if (!NILP (stop))
22413 {
22414 struct glyph_row *prev;
22415 while ((prev = row - 1, prev >= first)
22416 && MATRIX_ROW_END_CHARPOS (prev) == charpos
22417 && prev->used[TEXT_AREA] > 0)
22418 {
22419 struct glyph *beg = prev->glyphs[TEXT_AREA];
22420 glyph = beg + prev->used[TEXT_AREA];
22421 while (--glyph >= beg
22422 && INTEGERP (glyph->object));
22423 if (glyph < beg
22424 || !EQ (stop, glyph->object))
22425 break;
22426 row = prev;
22427 }
22428 }
22429
22430 *x = row->x;
22431 *y = row->y;
22432 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22433
22434 glyph = row->glyphs[TEXT_AREA];
22435 end = glyph + row->used[TEXT_AREA];
22436
22437 /* Skip over glyphs not having an object at the start of the row.
22438 These are special glyphs like truncation marks on terminal
22439 frames. */
22440 if (row->displays_text_p)
22441 while (glyph < end
22442 && INTEGERP (glyph->object)
22443 && !EQ (stop, glyph->object)
22444 && glyph->charpos < 0)
22445 {
22446 *x += glyph->pixel_width;
22447 ++glyph;
22448 }
22449
22450 while (glyph < end
22451 && !INTEGERP (glyph->object)
22452 && !EQ (stop, glyph->object)
22453 && (!BUFFERP (glyph->object)
22454 || glyph->charpos < charpos))
22455 {
22456 *x += glyph->pixel_width;
22457 ++glyph;
22458 }
22459
22460 *hpos = glyph - row->glyphs[TEXT_AREA];
22461 return !past_end;
22462 }
22463
22464 #else /* not 1 */
22465
22466 static int
22467 fast_find_position (w, pos, hpos, vpos, x, y, stop)
22468 struct window *w;
22469 EMACS_INT pos;
22470 int *hpos, *vpos, *x, *y;
22471 Lisp_Object stop;
22472 {
22473 int i;
22474 int lastcol;
22475 int maybe_next_line_p = 0;
22476 int line_start_position;
22477 int yb = window_text_bottom_y (w);
22478 struct glyph_row *row, *best_row;
22479 int row_vpos, best_row_vpos;
22480 int current_x;
22481
22482 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22483 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22484
22485 while (row->y < yb)
22486 {
22487 if (row->used[TEXT_AREA])
22488 line_start_position = row->glyphs[TEXT_AREA]->charpos;
22489 else
22490 line_start_position = 0;
22491
22492 if (line_start_position > pos)
22493 break;
22494 /* If the position sought is the end of the buffer,
22495 don't include the blank lines at the bottom of the window. */
22496 else if (line_start_position == pos
22497 && pos == BUF_ZV (XBUFFER (w->buffer)))
22498 {
22499 maybe_next_line_p = 1;
22500 break;
22501 }
22502 else if (line_start_position > 0)
22503 {
22504 best_row = row;
22505 best_row_vpos = row_vpos;
22506 }
22507
22508 if (row->y + row->height >= yb)
22509 break;
22510
22511 ++row;
22512 ++row_vpos;
22513 }
22514
22515 /* Find the right column within BEST_ROW. */
22516 lastcol = 0;
22517 current_x = best_row->x;
22518 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
22519 {
22520 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
22521 int charpos = glyph->charpos;
22522
22523 if (BUFFERP (glyph->object))
22524 {
22525 if (charpos == pos)
22526 {
22527 *hpos = i;
22528 *vpos = best_row_vpos;
22529 *x = current_x;
22530 *y = best_row->y;
22531 return 1;
22532 }
22533 else if (charpos > pos)
22534 break;
22535 }
22536 else if (EQ (glyph->object, stop))
22537 break;
22538
22539 if (charpos > 0)
22540 lastcol = i;
22541 current_x += glyph->pixel_width;
22542 }
22543
22544 /* If we're looking for the end of the buffer,
22545 and we didn't find it in the line we scanned,
22546 use the start of the following line. */
22547 if (maybe_next_line_p)
22548 {
22549 ++best_row;
22550 ++best_row_vpos;
22551 lastcol = 0;
22552 current_x = best_row->x;
22553 }
22554
22555 *vpos = best_row_vpos;
22556 *hpos = lastcol + 1;
22557 *x = current_x;
22558 *y = best_row->y;
22559 return 0;
22560 }
22561
22562 #endif /* not 1 */
22563
22564
22565 /* Find the position of the glyph for position POS in OBJECT in
22566 window W's current matrix, and return in *X, *Y the pixel
22567 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
22568
22569 RIGHT_P non-zero means return the position of the right edge of the
22570 glyph, RIGHT_P zero means return the left edge position.
22571
22572 If no glyph for POS exists in the matrix, return the position of
22573 the glyph with the next smaller position that is in the matrix, if
22574 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
22575 exists in the matrix, return the position of the glyph with the
22576 next larger position in OBJECT.
22577
22578 Value is non-zero if a glyph was found. */
22579
22580 static int
22581 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
22582 struct window *w;
22583 EMACS_INT pos;
22584 Lisp_Object object;
22585 int *hpos, *vpos, *x, *y;
22586 int right_p;
22587 {
22588 int yb = window_text_bottom_y (w);
22589 struct glyph_row *r;
22590 struct glyph *best_glyph = NULL;
22591 struct glyph_row *best_row = NULL;
22592 int best_x = 0;
22593
22594 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22595 r->enabled_p && r->y < yb;
22596 ++r)
22597 {
22598 struct glyph *g = r->glyphs[TEXT_AREA];
22599 struct glyph *e = g + r->used[TEXT_AREA];
22600 int gx;
22601
22602 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
22603 if (EQ (g->object, object))
22604 {
22605 if (g->charpos == pos)
22606 {
22607 best_glyph = g;
22608 best_x = gx;
22609 best_row = r;
22610 goto found;
22611 }
22612 else if (best_glyph == NULL
22613 || ((abs (g->charpos - pos)
22614 < abs (best_glyph->charpos - pos))
22615 && (right_p
22616 ? g->charpos < pos
22617 : g->charpos > pos)))
22618 {
22619 best_glyph = g;
22620 best_x = gx;
22621 best_row = r;
22622 }
22623 }
22624 }
22625
22626 found:
22627
22628 if (best_glyph)
22629 {
22630 *x = best_x;
22631 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
22632
22633 if (right_p)
22634 {
22635 *x += best_glyph->pixel_width;
22636 ++*hpos;
22637 }
22638
22639 *y = best_row->y;
22640 *vpos = best_row - w->current_matrix->rows;
22641 }
22642
22643 return best_glyph != NULL;
22644 }
22645
22646
22647 /* See if position X, Y is within a hot-spot of an image. */
22648
22649 static int
22650 on_hot_spot_p (hot_spot, x, y)
22651 Lisp_Object hot_spot;
22652 int x, y;
22653 {
22654 if (!CONSP (hot_spot))
22655 return 0;
22656
22657 if (EQ (XCAR (hot_spot), Qrect))
22658 {
22659 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
22660 Lisp_Object rect = XCDR (hot_spot);
22661 Lisp_Object tem;
22662 if (!CONSP (rect))
22663 return 0;
22664 if (!CONSP (XCAR (rect)))
22665 return 0;
22666 if (!CONSP (XCDR (rect)))
22667 return 0;
22668 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
22669 return 0;
22670 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
22671 return 0;
22672 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
22673 return 0;
22674 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
22675 return 0;
22676 return 1;
22677 }
22678 else if (EQ (XCAR (hot_spot), Qcircle))
22679 {
22680 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
22681 Lisp_Object circ = XCDR (hot_spot);
22682 Lisp_Object lr, lx0, ly0;
22683 if (CONSP (circ)
22684 && CONSP (XCAR (circ))
22685 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
22686 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
22687 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
22688 {
22689 double r = XFLOATINT (lr);
22690 double dx = XINT (lx0) - x;
22691 double dy = XINT (ly0) - y;
22692 return (dx * dx + dy * dy <= r * r);
22693 }
22694 }
22695 else if (EQ (XCAR (hot_spot), Qpoly))
22696 {
22697 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
22698 if (VECTORP (XCDR (hot_spot)))
22699 {
22700 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
22701 Lisp_Object *poly = v->contents;
22702 int n = v->size;
22703 int i;
22704 int inside = 0;
22705 Lisp_Object lx, ly;
22706 int x0, y0;
22707
22708 /* Need an even number of coordinates, and at least 3 edges. */
22709 if (n < 6 || n & 1)
22710 return 0;
22711
22712 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
22713 If count is odd, we are inside polygon. Pixels on edges
22714 may or may not be included depending on actual geometry of the
22715 polygon. */
22716 if ((lx = poly[n-2], !INTEGERP (lx))
22717 || (ly = poly[n-1], !INTEGERP (lx)))
22718 return 0;
22719 x0 = XINT (lx), y0 = XINT (ly);
22720 for (i = 0; i < n; i += 2)
22721 {
22722 int x1 = x0, y1 = y0;
22723 if ((lx = poly[i], !INTEGERP (lx))
22724 || (ly = poly[i+1], !INTEGERP (ly)))
22725 return 0;
22726 x0 = XINT (lx), y0 = XINT (ly);
22727
22728 /* Does this segment cross the X line? */
22729 if (x0 >= x)
22730 {
22731 if (x1 >= x)
22732 continue;
22733 }
22734 else if (x1 < x)
22735 continue;
22736 if (y > y0 && y > y1)
22737 continue;
22738 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
22739 inside = !inside;
22740 }
22741 return inside;
22742 }
22743 }
22744 return 0;
22745 }
22746
22747 Lisp_Object
22748 find_hot_spot (map, x, y)
22749 Lisp_Object map;
22750 int x, y;
22751 {
22752 while (CONSP (map))
22753 {
22754 if (CONSP (XCAR (map))
22755 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
22756 return XCAR (map);
22757 map = XCDR (map);
22758 }
22759
22760 return Qnil;
22761 }
22762
22763 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
22764 3, 3, 0,
22765 doc: /* Lookup in image map MAP coordinates X and Y.
22766 An image map is an alist where each element has the format (AREA ID PLIST).
22767 An AREA is specified as either a rectangle, a circle, or a polygon:
22768 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
22769 pixel coordinates of the upper left and bottom right corners.
22770 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
22771 and the radius of the circle; r may be a float or integer.
22772 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
22773 vector describes one corner in the polygon.
22774 Returns the alist element for the first matching AREA in MAP. */)
22775 (map, x, y)
22776 Lisp_Object map;
22777 Lisp_Object x, y;
22778 {
22779 if (NILP (map))
22780 return Qnil;
22781
22782 CHECK_NUMBER (x);
22783 CHECK_NUMBER (y);
22784
22785 return find_hot_spot (map, XINT (x), XINT (y));
22786 }
22787
22788
22789 /* Display frame CURSOR, optionally using shape defined by POINTER. */
22790 static void
22791 define_frame_cursor1 (f, cursor, pointer)
22792 struct frame *f;
22793 Cursor cursor;
22794 Lisp_Object pointer;
22795 {
22796 /* Do not change cursor shape while dragging mouse. */
22797 if (!NILP (do_mouse_tracking))
22798 return;
22799
22800 if (!NILP (pointer))
22801 {
22802 if (EQ (pointer, Qarrow))
22803 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22804 else if (EQ (pointer, Qhand))
22805 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
22806 else if (EQ (pointer, Qtext))
22807 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22808 else if (EQ (pointer, intern ("hdrag")))
22809 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22810 #ifdef HAVE_X_WINDOWS
22811 else if (EQ (pointer, intern ("vdrag")))
22812 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
22813 #endif
22814 else if (EQ (pointer, intern ("hourglass")))
22815 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
22816 else if (EQ (pointer, Qmodeline))
22817 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
22818 else
22819 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22820 }
22821
22822 if (cursor != No_Cursor)
22823 FRAME_RIF (f)->define_frame_cursor (f, cursor);
22824 }
22825
22826 /* Take proper action when mouse has moved to the mode or header line
22827 or marginal area AREA of window W, x-position X and y-position Y.
22828 X is relative to the start of the text display area of W, so the
22829 width of bitmap areas and scroll bars must be subtracted to get a
22830 position relative to the start of the mode line. */
22831
22832 static void
22833 note_mode_line_or_margin_highlight (window, x, y, area)
22834 Lisp_Object window;
22835 int x, y;
22836 enum window_part area;
22837 {
22838 struct window *w = XWINDOW (window);
22839 struct frame *f = XFRAME (w->frame);
22840 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22841 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22842 Lisp_Object pointer = Qnil;
22843 int charpos, dx, dy, width, height;
22844 Lisp_Object string, object = Qnil;
22845 Lisp_Object pos, help;
22846
22847 Lisp_Object mouse_face;
22848 int original_x_pixel = x;
22849 struct glyph * glyph = NULL, * row_start_glyph = NULL;
22850 struct glyph_row *row;
22851
22852 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
22853 {
22854 int x0;
22855 struct glyph *end;
22856
22857 string = mode_line_string (w, area, &x, &y, &charpos,
22858 &object, &dx, &dy, &width, &height);
22859
22860 row = (area == ON_MODE_LINE
22861 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
22862 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
22863
22864 /* Find glyph */
22865 if (row->mode_line_p && row->enabled_p)
22866 {
22867 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
22868 end = glyph + row->used[TEXT_AREA];
22869
22870 for (x0 = original_x_pixel;
22871 glyph < end && x0 >= glyph->pixel_width;
22872 ++glyph)
22873 x0 -= glyph->pixel_width;
22874
22875 if (glyph >= end)
22876 glyph = NULL;
22877 }
22878 }
22879 else
22880 {
22881 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
22882 string = marginal_area_string (w, area, &x, &y, &charpos,
22883 &object, &dx, &dy, &width, &height);
22884 }
22885
22886 help = Qnil;
22887
22888 if (IMAGEP (object))
22889 {
22890 Lisp_Object image_map, hotspot;
22891 if ((image_map = Fplist_get (XCDR (object), QCmap),
22892 !NILP (image_map))
22893 && (hotspot = find_hot_spot (image_map, dx, dy),
22894 CONSP (hotspot))
22895 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22896 {
22897 Lisp_Object area_id, plist;
22898
22899 area_id = XCAR (hotspot);
22900 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22901 If so, we could look for mouse-enter, mouse-leave
22902 properties in PLIST (and do something...). */
22903 hotspot = XCDR (hotspot);
22904 if (CONSP (hotspot)
22905 && (plist = XCAR (hotspot), CONSP (plist)))
22906 {
22907 pointer = Fplist_get (plist, Qpointer);
22908 if (NILP (pointer))
22909 pointer = Qhand;
22910 help = Fplist_get (plist, Qhelp_echo);
22911 if (!NILP (help))
22912 {
22913 help_echo_string = help;
22914 /* Is this correct? ++kfs */
22915 XSETWINDOW (help_echo_window, w);
22916 help_echo_object = w->buffer;
22917 help_echo_pos = charpos;
22918 }
22919 }
22920 }
22921 if (NILP (pointer))
22922 pointer = Fplist_get (XCDR (object), QCpointer);
22923 }
22924
22925 if (STRINGP (string))
22926 {
22927 pos = make_number (charpos);
22928 /* If we're on a string with `help-echo' text property, arrange
22929 for the help to be displayed. This is done by setting the
22930 global variable help_echo_string to the help string. */
22931 if (NILP (help))
22932 {
22933 help = Fget_text_property (pos, Qhelp_echo, string);
22934 if (!NILP (help))
22935 {
22936 help_echo_string = help;
22937 XSETWINDOW (help_echo_window, w);
22938 help_echo_object = string;
22939 help_echo_pos = charpos;
22940 }
22941 }
22942
22943 if (NILP (pointer))
22944 pointer = Fget_text_property (pos, Qpointer, string);
22945
22946 /* Change the mouse pointer according to what is under X/Y. */
22947 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
22948 {
22949 Lisp_Object map;
22950 map = Fget_text_property (pos, Qlocal_map, string);
22951 if (!KEYMAPP (map))
22952 map = Fget_text_property (pos, Qkeymap, string);
22953 if (!KEYMAPP (map))
22954 cursor = dpyinfo->vertical_scroll_bar_cursor;
22955 }
22956
22957 /* Change the mouse face according to what is under X/Y. */
22958 mouse_face = Fget_text_property (pos, Qmouse_face, string);
22959 if (!NILP (mouse_face)
22960 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22961 && glyph)
22962 {
22963 Lisp_Object b, e;
22964
22965 struct glyph * tmp_glyph;
22966
22967 int gpos;
22968 int gseq_length;
22969 int total_pixel_width;
22970 int ignore;
22971
22972 int vpos, hpos;
22973
22974 b = Fprevious_single_property_change (make_number (charpos + 1),
22975 Qmouse_face, string, Qnil);
22976 if (NILP (b))
22977 b = make_number (0);
22978
22979 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
22980 if (NILP (e))
22981 e = make_number (SCHARS (string));
22982
22983 /* Calculate the position(glyph position: GPOS) of GLYPH in
22984 displayed string. GPOS is different from CHARPOS.
22985
22986 CHARPOS is the position of glyph in internal string
22987 object. A mode line string format has structures which
22988 is converted to a flatten by emacs lisp interpreter.
22989 The internal string is an element of the structures.
22990 The displayed string is the flatten string. */
22991 gpos = 0;
22992 if (glyph > row_start_glyph)
22993 {
22994 tmp_glyph = glyph - 1;
22995 while (tmp_glyph >= row_start_glyph
22996 && tmp_glyph->charpos >= XINT (b)
22997 && EQ (tmp_glyph->object, glyph->object))
22998 {
22999 tmp_glyph--;
23000 gpos++;
23001 }
23002 }
23003
23004 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
23005 displayed string holding GLYPH.
23006
23007 GSEQ_LENGTH is different from SCHARS (STRING).
23008 SCHARS (STRING) returns the length of the internal string. */
23009 for (tmp_glyph = glyph, gseq_length = gpos;
23010 tmp_glyph->charpos < XINT (e);
23011 tmp_glyph++, gseq_length++)
23012 {
23013 if (!EQ (tmp_glyph->object, glyph->object))
23014 break;
23015 }
23016
23017 total_pixel_width = 0;
23018 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
23019 total_pixel_width += tmp_glyph->pixel_width;
23020
23021 /* Pre calculation of re-rendering position */
23022 vpos = (x - gpos);
23023 hpos = (area == ON_MODE_LINE
23024 ? (w->current_matrix)->nrows - 1
23025 : 0);
23026
23027 /* If the re-rendering position is included in the last
23028 re-rendering area, we should do nothing. */
23029 if ( EQ (window, dpyinfo->mouse_face_window)
23030 && dpyinfo->mouse_face_beg_col <= vpos
23031 && vpos < dpyinfo->mouse_face_end_col
23032 && dpyinfo->mouse_face_beg_row == hpos )
23033 return;
23034
23035 if (clear_mouse_face (dpyinfo))
23036 cursor = No_Cursor;
23037
23038 dpyinfo->mouse_face_beg_col = vpos;
23039 dpyinfo->mouse_face_beg_row = hpos;
23040
23041 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
23042 dpyinfo->mouse_face_beg_y = 0;
23043
23044 dpyinfo->mouse_face_end_col = vpos + gseq_length;
23045 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
23046
23047 dpyinfo->mouse_face_end_x = 0;
23048 dpyinfo->mouse_face_end_y = 0;
23049
23050 dpyinfo->mouse_face_past_end = 0;
23051 dpyinfo->mouse_face_window = window;
23052
23053 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
23054 charpos,
23055 0, 0, 0, &ignore,
23056 glyph->face_id, 1);
23057 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23058
23059 if (NILP (pointer))
23060 pointer = Qhand;
23061 }
23062 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
23063 clear_mouse_face (dpyinfo);
23064 }
23065 define_frame_cursor1 (f, cursor, pointer);
23066 }
23067
23068
23069 /* EXPORT:
23070 Take proper action when the mouse has moved to position X, Y on
23071 frame F as regards highlighting characters that have mouse-face
23072 properties. Also de-highlighting chars where the mouse was before.
23073 X and Y can be negative or out of range. */
23074
23075 void
23076 note_mouse_highlight (f, x, y)
23077 struct frame *f;
23078 int x, y;
23079 {
23080 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23081 enum window_part part;
23082 Lisp_Object window;
23083 struct window *w;
23084 Cursor cursor = No_Cursor;
23085 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
23086 struct buffer *b;
23087
23088 /* When a menu is active, don't highlight because this looks odd. */
23089 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
23090 if (popup_activated ())
23091 return;
23092 #endif
23093
23094 if (NILP (Vmouse_highlight)
23095 || !f->glyphs_initialized_p)
23096 return;
23097
23098 dpyinfo->mouse_face_mouse_x = x;
23099 dpyinfo->mouse_face_mouse_y = y;
23100 dpyinfo->mouse_face_mouse_frame = f;
23101
23102 if (dpyinfo->mouse_face_defer)
23103 return;
23104
23105 if (gc_in_progress)
23106 {
23107 dpyinfo->mouse_face_deferred_gc = 1;
23108 return;
23109 }
23110
23111 /* Which window is that in? */
23112 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
23113
23114 /* If we were displaying active text in another window, clear that.
23115 Also clear if we move out of text area in same window. */
23116 if (! EQ (window, dpyinfo->mouse_face_window)
23117 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
23118 && !NILP (dpyinfo->mouse_face_window)))
23119 clear_mouse_face (dpyinfo);
23120
23121 /* Not on a window -> return. */
23122 if (!WINDOWP (window))
23123 return;
23124
23125 /* Reset help_echo_string. It will get recomputed below. */
23126 help_echo_string = Qnil;
23127
23128 /* Convert to window-relative pixel coordinates. */
23129 w = XWINDOW (window);
23130 frame_to_window_pixel_xy (w, &x, &y);
23131
23132 /* Handle tool-bar window differently since it doesn't display a
23133 buffer. */
23134 if (EQ (window, f->tool_bar_window))
23135 {
23136 note_tool_bar_highlight (f, x, y);
23137 return;
23138 }
23139
23140 /* Mouse is on the mode, header line or margin? */
23141 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
23142 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
23143 {
23144 note_mode_line_or_margin_highlight (window, x, y, part);
23145 return;
23146 }
23147
23148 if (part == ON_VERTICAL_BORDER)
23149 {
23150 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
23151 help_echo_string = build_string ("drag-mouse-1: resize");
23152 }
23153 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
23154 || part == ON_SCROLL_BAR)
23155 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23156 else
23157 cursor = FRAME_X_OUTPUT (f)->text_cursor;
23158
23159 /* Are we in a window whose display is up to date?
23160 And verify the buffer's text has not changed. */
23161 b = XBUFFER (w->buffer);
23162 if (part == ON_TEXT
23163 && EQ (w->window_end_valid, w->buffer)
23164 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
23165 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
23166 {
23167 int hpos, vpos, pos, i, dx, dy, area;
23168 struct glyph *glyph;
23169 Lisp_Object object;
23170 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
23171 Lisp_Object *overlay_vec = NULL;
23172 int noverlays;
23173 struct buffer *obuf;
23174 int obegv, ozv, same_region;
23175
23176 /* Find the glyph under X/Y. */
23177 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
23178
23179 /* Look for :pointer property on image. */
23180 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23181 {
23182 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23183 if (img != NULL && IMAGEP (img->spec))
23184 {
23185 Lisp_Object image_map, hotspot;
23186 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
23187 !NILP (image_map))
23188 && (hotspot = find_hot_spot (image_map,
23189 glyph->slice.x + dx,
23190 glyph->slice.y + dy),
23191 CONSP (hotspot))
23192 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
23193 {
23194 Lisp_Object area_id, plist;
23195
23196 area_id = XCAR (hotspot);
23197 /* Could check AREA_ID to see if we enter/leave this hot-spot.
23198 If so, we could look for mouse-enter, mouse-leave
23199 properties in PLIST (and do something...). */
23200 hotspot = XCDR (hotspot);
23201 if (CONSP (hotspot)
23202 && (plist = XCAR (hotspot), CONSP (plist)))
23203 {
23204 pointer = Fplist_get (plist, Qpointer);
23205 if (NILP (pointer))
23206 pointer = Qhand;
23207 help_echo_string = Fplist_get (plist, Qhelp_echo);
23208 if (!NILP (help_echo_string))
23209 {
23210 help_echo_window = window;
23211 help_echo_object = glyph->object;
23212 help_echo_pos = glyph->charpos;
23213 }
23214 }
23215 }
23216 if (NILP (pointer))
23217 pointer = Fplist_get (XCDR (img->spec), QCpointer);
23218 }
23219 }
23220
23221 /* Clear mouse face if X/Y not over text. */
23222 if (glyph == NULL
23223 || area != TEXT_AREA
23224 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
23225 {
23226 if (clear_mouse_face (dpyinfo))
23227 cursor = No_Cursor;
23228 if (NILP (pointer))
23229 {
23230 if (area != TEXT_AREA)
23231 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23232 else
23233 pointer = Vvoid_text_area_pointer;
23234 }
23235 goto set_cursor;
23236 }
23237
23238 pos = glyph->charpos;
23239 object = glyph->object;
23240 if (!STRINGP (object) && !BUFFERP (object))
23241 goto set_cursor;
23242
23243 /* If we get an out-of-range value, return now; avoid an error. */
23244 if (BUFFERP (object) && pos > BUF_Z (b))
23245 goto set_cursor;
23246
23247 /* Make the window's buffer temporarily current for
23248 overlays_at and compute_char_face. */
23249 obuf = current_buffer;
23250 current_buffer = b;
23251 obegv = BEGV;
23252 ozv = ZV;
23253 BEGV = BEG;
23254 ZV = Z;
23255
23256 /* Is this char mouse-active or does it have help-echo? */
23257 position = make_number (pos);
23258
23259 if (BUFFERP (object))
23260 {
23261 /* Put all the overlays we want in a vector in overlay_vec. */
23262 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
23263 /* Sort overlays into increasing priority order. */
23264 noverlays = sort_overlays (overlay_vec, noverlays, w);
23265 }
23266 else
23267 noverlays = 0;
23268
23269 same_region = (EQ (window, dpyinfo->mouse_face_window)
23270 && vpos >= dpyinfo->mouse_face_beg_row
23271 && vpos <= dpyinfo->mouse_face_end_row
23272 && (vpos > dpyinfo->mouse_face_beg_row
23273 || hpos >= dpyinfo->mouse_face_beg_col)
23274 && (vpos < dpyinfo->mouse_face_end_row
23275 || hpos < dpyinfo->mouse_face_end_col
23276 || dpyinfo->mouse_face_past_end));
23277
23278 if (same_region)
23279 cursor = No_Cursor;
23280
23281 /* Check mouse-face highlighting. */
23282 if (! same_region
23283 /* If there exists an overlay with mouse-face overlapping
23284 the one we are currently highlighting, we have to
23285 check if we enter the overlapping overlay, and then
23286 highlight only that. */
23287 || (OVERLAYP (dpyinfo->mouse_face_overlay)
23288 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
23289 {
23290 /* Find the highest priority overlay that has a mouse-face
23291 property. */
23292 overlay = Qnil;
23293 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
23294 {
23295 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
23296 if (!NILP (mouse_face))
23297 overlay = overlay_vec[i];
23298 }
23299
23300 /* If we're actually highlighting the same overlay as
23301 before, there's no need to do that again. */
23302 if (!NILP (overlay)
23303 && EQ (overlay, dpyinfo->mouse_face_overlay))
23304 goto check_help_echo;
23305
23306 dpyinfo->mouse_face_overlay = overlay;
23307
23308 /* Clear the display of the old active region, if any. */
23309 if (clear_mouse_face (dpyinfo))
23310 cursor = No_Cursor;
23311
23312 /* If no overlay applies, get a text property. */
23313 if (NILP (overlay))
23314 mouse_face = Fget_text_property (position, Qmouse_face, object);
23315
23316 /* Handle the overlay case. */
23317 if (!NILP (overlay))
23318 {
23319 /* Find the range of text around this char that
23320 should be active. */
23321 Lisp_Object before, after;
23322 int ignore;
23323
23324 before = Foverlay_start (overlay);
23325 after = Foverlay_end (overlay);
23326 /* Record this as the current active region. */
23327 fast_find_position (w, XFASTINT (before),
23328 &dpyinfo->mouse_face_beg_col,
23329 &dpyinfo->mouse_face_beg_row,
23330 &dpyinfo->mouse_face_beg_x,
23331 &dpyinfo->mouse_face_beg_y, Qnil);
23332
23333 dpyinfo->mouse_face_past_end
23334 = !fast_find_position (w, XFASTINT (after),
23335 &dpyinfo->mouse_face_end_col,
23336 &dpyinfo->mouse_face_end_row,
23337 &dpyinfo->mouse_face_end_x,
23338 &dpyinfo->mouse_face_end_y, Qnil);
23339 dpyinfo->mouse_face_window = window;
23340
23341 dpyinfo->mouse_face_face_id
23342 = face_at_buffer_position (w, pos, 0, 0,
23343 &ignore, pos + 1,
23344 !dpyinfo->mouse_face_hidden);
23345
23346 /* Display it as active. */
23347 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23348 cursor = No_Cursor;
23349 }
23350 /* Handle the text property case. */
23351 else if (!NILP (mouse_face) && BUFFERP (object))
23352 {
23353 /* Find the range of text around this char that
23354 should be active. */
23355 Lisp_Object before, after, beginning, end;
23356 int ignore;
23357
23358 beginning = Fmarker_position (w->start);
23359 end = make_number (BUF_Z (XBUFFER (object))
23360 - XFASTINT (w->window_end_pos));
23361 before
23362 = Fprevious_single_property_change (make_number (pos + 1),
23363 Qmouse_face,
23364 object, beginning);
23365 after
23366 = Fnext_single_property_change (position, Qmouse_face,
23367 object, end);
23368
23369 /* Record this as the current active region. */
23370 fast_find_position (w, XFASTINT (before),
23371 &dpyinfo->mouse_face_beg_col,
23372 &dpyinfo->mouse_face_beg_row,
23373 &dpyinfo->mouse_face_beg_x,
23374 &dpyinfo->mouse_face_beg_y, Qnil);
23375 dpyinfo->mouse_face_past_end
23376 = !fast_find_position (w, XFASTINT (after),
23377 &dpyinfo->mouse_face_end_col,
23378 &dpyinfo->mouse_face_end_row,
23379 &dpyinfo->mouse_face_end_x,
23380 &dpyinfo->mouse_face_end_y, Qnil);
23381 dpyinfo->mouse_face_window = window;
23382
23383 if (BUFFERP (object))
23384 dpyinfo->mouse_face_face_id
23385 = face_at_buffer_position (w, pos, 0, 0,
23386 &ignore, pos + 1,
23387 !dpyinfo->mouse_face_hidden);
23388
23389 /* Display it as active. */
23390 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23391 cursor = No_Cursor;
23392 }
23393 else if (!NILP (mouse_face) && STRINGP (object))
23394 {
23395 Lisp_Object b, e;
23396 int ignore;
23397
23398 b = Fprevious_single_property_change (make_number (pos + 1),
23399 Qmouse_face,
23400 object, Qnil);
23401 e = Fnext_single_property_change (position, Qmouse_face,
23402 object, Qnil);
23403 if (NILP (b))
23404 b = make_number (0);
23405 if (NILP (e))
23406 e = make_number (SCHARS (object) - 1);
23407
23408 fast_find_string_pos (w, XINT (b), object,
23409 &dpyinfo->mouse_face_beg_col,
23410 &dpyinfo->mouse_face_beg_row,
23411 &dpyinfo->mouse_face_beg_x,
23412 &dpyinfo->mouse_face_beg_y, 0);
23413 fast_find_string_pos (w, XINT (e), object,
23414 &dpyinfo->mouse_face_end_col,
23415 &dpyinfo->mouse_face_end_row,
23416 &dpyinfo->mouse_face_end_x,
23417 &dpyinfo->mouse_face_end_y, 1);
23418 dpyinfo->mouse_face_past_end = 0;
23419 dpyinfo->mouse_face_window = window;
23420 dpyinfo->mouse_face_face_id
23421 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
23422 glyph->face_id, 1);
23423 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23424 cursor = No_Cursor;
23425 }
23426 else if (STRINGP (object) && NILP (mouse_face))
23427 {
23428 /* A string which doesn't have mouse-face, but
23429 the text ``under'' it might have. */
23430 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
23431 int start = MATRIX_ROW_START_CHARPOS (r);
23432
23433 pos = string_buffer_position (w, object, start);
23434 if (pos > 0)
23435 mouse_face = get_char_property_and_overlay (make_number (pos),
23436 Qmouse_face,
23437 w->buffer,
23438 &overlay);
23439 if (!NILP (mouse_face) && !NILP (overlay))
23440 {
23441 Lisp_Object before = Foverlay_start (overlay);
23442 Lisp_Object after = Foverlay_end (overlay);
23443 int ignore;
23444
23445 /* Note that we might not be able to find position
23446 BEFORE in the glyph matrix if the overlay is
23447 entirely covered by a `display' property. In
23448 this case, we overshoot. So let's stop in
23449 the glyph matrix before glyphs for OBJECT. */
23450 fast_find_position (w, XFASTINT (before),
23451 &dpyinfo->mouse_face_beg_col,
23452 &dpyinfo->mouse_face_beg_row,
23453 &dpyinfo->mouse_face_beg_x,
23454 &dpyinfo->mouse_face_beg_y,
23455 object);
23456
23457 dpyinfo->mouse_face_past_end
23458 = !fast_find_position (w, XFASTINT (after),
23459 &dpyinfo->mouse_face_end_col,
23460 &dpyinfo->mouse_face_end_row,
23461 &dpyinfo->mouse_face_end_x,
23462 &dpyinfo->mouse_face_end_y,
23463 Qnil);
23464 dpyinfo->mouse_face_window = window;
23465 dpyinfo->mouse_face_face_id
23466 = face_at_buffer_position (w, pos, 0, 0,
23467 &ignore, pos + 1,
23468 !dpyinfo->mouse_face_hidden);
23469
23470 /* Display it as active. */
23471 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23472 cursor = No_Cursor;
23473 }
23474 }
23475 }
23476
23477 check_help_echo:
23478
23479 /* Look for a `help-echo' property. */
23480 if (NILP (help_echo_string)) {
23481 Lisp_Object help, overlay;
23482
23483 /* Check overlays first. */
23484 help = overlay = Qnil;
23485 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
23486 {
23487 overlay = overlay_vec[i];
23488 help = Foverlay_get (overlay, Qhelp_echo);
23489 }
23490
23491 if (!NILP (help))
23492 {
23493 help_echo_string = help;
23494 help_echo_window = window;
23495 help_echo_object = overlay;
23496 help_echo_pos = pos;
23497 }
23498 else
23499 {
23500 Lisp_Object object = glyph->object;
23501 int charpos = glyph->charpos;
23502
23503 /* Try text properties. */
23504 if (STRINGP (object)
23505 && charpos >= 0
23506 && charpos < SCHARS (object))
23507 {
23508 help = Fget_text_property (make_number (charpos),
23509 Qhelp_echo, object);
23510 if (NILP (help))
23511 {
23512 /* If the string itself doesn't specify a help-echo,
23513 see if the buffer text ``under'' it does. */
23514 struct glyph_row *r
23515 = MATRIX_ROW (w->current_matrix, vpos);
23516 int start = MATRIX_ROW_START_CHARPOS (r);
23517 int pos = string_buffer_position (w, object, start);
23518 if (pos > 0)
23519 {
23520 help = Fget_char_property (make_number (pos),
23521 Qhelp_echo, w->buffer);
23522 if (!NILP (help))
23523 {
23524 charpos = pos;
23525 object = w->buffer;
23526 }
23527 }
23528 }
23529 }
23530 else if (BUFFERP (object)
23531 && charpos >= BEGV
23532 && charpos < ZV)
23533 help = Fget_text_property (make_number (charpos), Qhelp_echo,
23534 object);
23535
23536 if (!NILP (help))
23537 {
23538 help_echo_string = help;
23539 help_echo_window = window;
23540 help_echo_object = object;
23541 help_echo_pos = charpos;
23542 }
23543 }
23544 }
23545
23546 /* Look for a `pointer' property. */
23547 if (NILP (pointer))
23548 {
23549 /* Check overlays first. */
23550 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
23551 pointer = Foverlay_get (overlay_vec[i], Qpointer);
23552
23553 if (NILP (pointer))
23554 {
23555 Lisp_Object object = glyph->object;
23556 int charpos = glyph->charpos;
23557
23558 /* Try text properties. */
23559 if (STRINGP (object)
23560 && charpos >= 0
23561 && charpos < SCHARS (object))
23562 {
23563 pointer = Fget_text_property (make_number (charpos),
23564 Qpointer, object);
23565 if (NILP (pointer))
23566 {
23567 /* If the string itself doesn't specify a pointer,
23568 see if the buffer text ``under'' it does. */
23569 struct glyph_row *r
23570 = MATRIX_ROW (w->current_matrix, vpos);
23571 int start = MATRIX_ROW_START_CHARPOS (r);
23572 int pos = string_buffer_position (w, object, start);
23573 if (pos > 0)
23574 pointer = Fget_char_property (make_number (pos),
23575 Qpointer, w->buffer);
23576 }
23577 }
23578 else if (BUFFERP (object)
23579 && charpos >= BEGV
23580 && charpos < ZV)
23581 pointer = Fget_text_property (make_number (charpos),
23582 Qpointer, object);
23583 }
23584 }
23585
23586 BEGV = obegv;
23587 ZV = ozv;
23588 current_buffer = obuf;
23589 }
23590
23591 set_cursor:
23592
23593 define_frame_cursor1 (f, cursor, pointer);
23594 }
23595
23596
23597 /* EXPORT for RIF:
23598 Clear any mouse-face on window W. This function is part of the
23599 redisplay interface, and is called from try_window_id and similar
23600 functions to ensure the mouse-highlight is off. */
23601
23602 void
23603 x_clear_window_mouse_face (w)
23604 struct window *w;
23605 {
23606 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23607 Lisp_Object window;
23608
23609 BLOCK_INPUT;
23610 XSETWINDOW (window, w);
23611 if (EQ (window, dpyinfo->mouse_face_window))
23612 clear_mouse_face (dpyinfo);
23613 UNBLOCK_INPUT;
23614 }
23615
23616
23617 /* EXPORT:
23618 Just discard the mouse face information for frame F, if any.
23619 This is used when the size of F is changed. */
23620
23621 void
23622 cancel_mouse_face (f)
23623 struct frame *f;
23624 {
23625 Lisp_Object window;
23626 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23627
23628 window = dpyinfo->mouse_face_window;
23629 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
23630 {
23631 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
23632 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
23633 dpyinfo->mouse_face_window = Qnil;
23634 }
23635 }
23636
23637
23638 #endif /* HAVE_WINDOW_SYSTEM */
23639
23640 \f
23641 /***********************************************************************
23642 Exposure Events
23643 ***********************************************************************/
23644
23645 #ifdef HAVE_WINDOW_SYSTEM
23646
23647 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
23648 which intersects rectangle R. R is in window-relative coordinates. */
23649
23650 static void
23651 expose_area (w, row, r, area)
23652 struct window *w;
23653 struct glyph_row *row;
23654 XRectangle *r;
23655 enum glyph_row_area area;
23656 {
23657 struct glyph *first = row->glyphs[area];
23658 struct glyph *end = row->glyphs[area] + row->used[area];
23659 struct glyph *last;
23660 int first_x, start_x, x;
23661
23662 if (area == TEXT_AREA && row->fill_line_p)
23663 /* If row extends face to end of line write the whole line. */
23664 draw_glyphs (w, 0, row, area,
23665 0, row->used[area],
23666 DRAW_NORMAL_TEXT, 0);
23667 else
23668 {
23669 /* Set START_X to the window-relative start position for drawing glyphs of
23670 AREA. The first glyph of the text area can be partially visible.
23671 The first glyphs of other areas cannot. */
23672 start_x = window_box_left_offset (w, area);
23673 x = start_x;
23674 if (area == TEXT_AREA)
23675 x += row->x;
23676
23677 /* Find the first glyph that must be redrawn. */
23678 while (first < end
23679 && x + first->pixel_width < r->x)
23680 {
23681 x += first->pixel_width;
23682 ++first;
23683 }
23684
23685 /* Find the last one. */
23686 last = first;
23687 first_x = x;
23688 while (last < end
23689 && x < r->x + r->width)
23690 {
23691 x += last->pixel_width;
23692 ++last;
23693 }
23694
23695 /* Repaint. */
23696 if (last > first)
23697 draw_glyphs (w, first_x - start_x, row, area,
23698 first - row->glyphs[area], last - row->glyphs[area],
23699 DRAW_NORMAL_TEXT, 0);
23700 }
23701 }
23702
23703
23704 /* Redraw the parts of the glyph row ROW on window W intersecting
23705 rectangle R. R is in window-relative coordinates. Value is
23706 non-zero if mouse-face was overwritten. */
23707
23708 static int
23709 expose_line (w, row, r)
23710 struct window *w;
23711 struct glyph_row *row;
23712 XRectangle *r;
23713 {
23714 xassert (row->enabled_p);
23715
23716 if (row->mode_line_p || w->pseudo_window_p)
23717 draw_glyphs (w, 0, row, TEXT_AREA,
23718 0, row->used[TEXT_AREA],
23719 DRAW_NORMAL_TEXT, 0);
23720 else
23721 {
23722 if (row->used[LEFT_MARGIN_AREA])
23723 expose_area (w, row, r, LEFT_MARGIN_AREA);
23724 if (row->used[TEXT_AREA])
23725 expose_area (w, row, r, TEXT_AREA);
23726 if (row->used[RIGHT_MARGIN_AREA])
23727 expose_area (w, row, r, RIGHT_MARGIN_AREA);
23728 draw_row_fringe_bitmaps (w, row);
23729 }
23730
23731 return row->mouse_face_p;
23732 }
23733
23734
23735 /* Redraw those parts of glyphs rows during expose event handling that
23736 overlap other rows. Redrawing of an exposed line writes over parts
23737 of lines overlapping that exposed line; this function fixes that.
23738
23739 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
23740 row in W's current matrix that is exposed and overlaps other rows.
23741 LAST_OVERLAPPING_ROW is the last such row. */
23742
23743 static void
23744 expose_overlaps (w, first_overlapping_row, last_overlapping_row, r)
23745 struct window *w;
23746 struct glyph_row *first_overlapping_row;
23747 struct glyph_row *last_overlapping_row;
23748 XRectangle *r;
23749 {
23750 struct glyph_row *row;
23751
23752 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
23753 if (row->overlapping_p)
23754 {
23755 xassert (row->enabled_p && !row->mode_line_p);
23756
23757 row->clip = r;
23758 if (row->used[LEFT_MARGIN_AREA])
23759 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
23760
23761 if (row->used[TEXT_AREA])
23762 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
23763
23764 if (row->used[RIGHT_MARGIN_AREA])
23765 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
23766 row->clip = NULL;
23767 }
23768 }
23769
23770
23771 /* Return non-zero if W's cursor intersects rectangle R. */
23772
23773 static int
23774 phys_cursor_in_rect_p (w, r)
23775 struct window *w;
23776 XRectangle *r;
23777 {
23778 XRectangle cr, result;
23779 struct glyph *cursor_glyph;
23780
23781 cursor_glyph = get_phys_cursor_glyph (w);
23782 if (cursor_glyph)
23783 {
23784 /* r is relative to W's box, but w->phys_cursor.x is relative
23785 to left edge of W's TEXT area. Adjust it. */
23786 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
23787 cr.y = w->phys_cursor.y;
23788 cr.width = cursor_glyph->pixel_width;
23789 cr.height = w->phys_cursor_height;
23790 /* ++KFS: W32 version used W32-specific IntersectRect here, but
23791 I assume the effect is the same -- and this is portable. */
23792 return x_intersect_rectangles (&cr, r, &result);
23793 }
23794 /* If we don't understand the format, pretend we're not in the hot-spot. */
23795 return 0;
23796 }
23797
23798
23799 /* EXPORT:
23800 Draw a vertical window border to the right of window W if W doesn't
23801 have vertical scroll bars. */
23802
23803 void
23804 x_draw_vertical_border (w)
23805 struct window *w;
23806 {
23807 struct frame *f = XFRAME (WINDOW_FRAME (w));
23808
23809 /* We could do better, if we knew what type of scroll-bar the adjacent
23810 windows (on either side) have... But we don't :-(
23811 However, I think this works ok. ++KFS 2003-04-25 */
23812
23813 /* Redraw borders between horizontally adjacent windows. Don't
23814 do it for frames with vertical scroll bars because either the
23815 right scroll bar of a window, or the left scroll bar of its
23816 neighbor will suffice as a border. */
23817 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
23818 return;
23819
23820 if (!WINDOW_RIGHTMOST_P (w)
23821 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
23822 {
23823 int x0, x1, y0, y1;
23824
23825 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23826 y1 -= 1;
23827
23828 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23829 x1 -= 1;
23830
23831 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
23832 }
23833 else if (!WINDOW_LEFTMOST_P (w)
23834 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
23835 {
23836 int x0, x1, y0, y1;
23837
23838 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23839 y1 -= 1;
23840
23841 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23842 x0 -= 1;
23843
23844 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
23845 }
23846 }
23847
23848
23849 /* Redraw the part of window W intersection rectangle FR. Pixel
23850 coordinates in FR are frame-relative. Call this function with
23851 input blocked. Value is non-zero if the exposure overwrites
23852 mouse-face. */
23853
23854 static int
23855 expose_window (w, fr)
23856 struct window *w;
23857 XRectangle *fr;
23858 {
23859 struct frame *f = XFRAME (w->frame);
23860 XRectangle wr, r;
23861 int mouse_face_overwritten_p = 0;
23862
23863 /* If window is not yet fully initialized, do nothing. This can
23864 happen when toolkit scroll bars are used and a window is split.
23865 Reconfiguring the scroll bar will generate an expose for a newly
23866 created window. */
23867 if (w->current_matrix == NULL)
23868 return 0;
23869
23870 /* When we're currently updating the window, display and current
23871 matrix usually don't agree. Arrange for a thorough display
23872 later. */
23873 if (w == updated_window)
23874 {
23875 SET_FRAME_GARBAGED (f);
23876 return 0;
23877 }
23878
23879 /* Frame-relative pixel rectangle of W. */
23880 wr.x = WINDOW_LEFT_EDGE_X (w);
23881 wr.y = WINDOW_TOP_EDGE_Y (w);
23882 wr.width = WINDOW_TOTAL_WIDTH (w);
23883 wr.height = WINDOW_TOTAL_HEIGHT (w);
23884
23885 if (x_intersect_rectangles (fr, &wr, &r))
23886 {
23887 int yb = window_text_bottom_y (w);
23888 struct glyph_row *row;
23889 int cursor_cleared_p;
23890 struct glyph_row *first_overlapping_row, *last_overlapping_row;
23891
23892 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
23893 r.x, r.y, r.width, r.height));
23894
23895 /* Convert to window coordinates. */
23896 r.x -= WINDOW_LEFT_EDGE_X (w);
23897 r.y -= WINDOW_TOP_EDGE_Y (w);
23898
23899 /* Turn off the cursor. */
23900 if (!w->pseudo_window_p
23901 && phys_cursor_in_rect_p (w, &r))
23902 {
23903 x_clear_cursor (w);
23904 cursor_cleared_p = 1;
23905 }
23906 else
23907 cursor_cleared_p = 0;
23908
23909 /* Update lines intersecting rectangle R. */
23910 first_overlapping_row = last_overlapping_row = NULL;
23911 for (row = w->current_matrix->rows;
23912 row->enabled_p;
23913 ++row)
23914 {
23915 int y0 = row->y;
23916 int y1 = MATRIX_ROW_BOTTOM_Y (row);
23917
23918 if ((y0 >= r.y && y0 < r.y + r.height)
23919 || (y1 > r.y && y1 < r.y + r.height)
23920 || (r.y >= y0 && r.y < y1)
23921 || (r.y + r.height > y0 && r.y + r.height < y1))
23922 {
23923 /* A header line may be overlapping, but there is no need
23924 to fix overlapping areas for them. KFS 2005-02-12 */
23925 if (row->overlapping_p && !row->mode_line_p)
23926 {
23927 if (first_overlapping_row == NULL)
23928 first_overlapping_row = row;
23929 last_overlapping_row = row;
23930 }
23931
23932 row->clip = fr;
23933 if (expose_line (w, row, &r))
23934 mouse_face_overwritten_p = 1;
23935 row->clip = NULL;
23936 }
23937 else if (row->overlapping_p)
23938 {
23939 /* We must redraw a row overlapping the exposed area. */
23940 if (y0 < r.y
23941 ? y0 + row->phys_height > r.y
23942 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
23943 {
23944 if (first_overlapping_row == NULL)
23945 first_overlapping_row = row;
23946 last_overlapping_row = row;
23947 }
23948 }
23949
23950 if (y1 >= yb)
23951 break;
23952 }
23953
23954 /* Display the mode line if there is one. */
23955 if (WINDOW_WANTS_MODELINE_P (w)
23956 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
23957 row->enabled_p)
23958 && row->y < r.y + r.height)
23959 {
23960 if (expose_line (w, row, &r))
23961 mouse_face_overwritten_p = 1;
23962 }
23963
23964 if (!w->pseudo_window_p)
23965 {
23966 /* Fix the display of overlapping rows. */
23967 if (first_overlapping_row)
23968 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
23969 fr);
23970
23971 /* Draw border between windows. */
23972 x_draw_vertical_border (w);
23973
23974 /* Turn the cursor on again. */
23975 if (cursor_cleared_p)
23976 update_window_cursor (w, 1);
23977 }
23978 }
23979
23980 return mouse_face_overwritten_p;
23981 }
23982
23983
23984
23985 /* Redraw (parts) of all windows in the window tree rooted at W that
23986 intersect R. R contains frame pixel coordinates. Value is
23987 non-zero if the exposure overwrites mouse-face. */
23988
23989 static int
23990 expose_window_tree (w, r)
23991 struct window *w;
23992 XRectangle *r;
23993 {
23994 struct frame *f = XFRAME (w->frame);
23995 int mouse_face_overwritten_p = 0;
23996
23997 while (w && !FRAME_GARBAGED_P (f))
23998 {
23999 if (!NILP (w->hchild))
24000 mouse_face_overwritten_p
24001 |= expose_window_tree (XWINDOW (w->hchild), r);
24002 else if (!NILP (w->vchild))
24003 mouse_face_overwritten_p
24004 |= expose_window_tree (XWINDOW (w->vchild), r);
24005 else
24006 mouse_face_overwritten_p |= expose_window (w, r);
24007
24008 w = NILP (w->next) ? NULL : XWINDOW (w->next);
24009 }
24010
24011 return mouse_face_overwritten_p;
24012 }
24013
24014
24015 /* EXPORT:
24016 Redisplay an exposed area of frame F. X and Y are the upper-left
24017 corner of the exposed rectangle. W and H are width and height of
24018 the exposed area. All are pixel values. W or H zero means redraw
24019 the entire frame. */
24020
24021 void
24022 expose_frame (f, x, y, w, h)
24023 struct frame *f;
24024 int x, y, w, h;
24025 {
24026 XRectangle r;
24027 int mouse_face_overwritten_p = 0;
24028
24029 TRACE ((stderr, "expose_frame "));
24030
24031 /* No need to redraw if frame will be redrawn soon. */
24032 if (FRAME_GARBAGED_P (f))
24033 {
24034 TRACE ((stderr, " garbaged\n"));
24035 return;
24036 }
24037
24038 /* If basic faces haven't been realized yet, there is no point in
24039 trying to redraw anything. This can happen when we get an expose
24040 event while Emacs is starting, e.g. by moving another window. */
24041 if (FRAME_FACE_CACHE (f) == NULL
24042 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
24043 {
24044 TRACE ((stderr, " no faces\n"));
24045 return;
24046 }
24047
24048 if (w == 0 || h == 0)
24049 {
24050 r.x = r.y = 0;
24051 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
24052 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
24053 }
24054 else
24055 {
24056 r.x = x;
24057 r.y = y;
24058 r.width = w;
24059 r.height = h;
24060 }
24061
24062 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
24063 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
24064
24065 if (WINDOWP (f->tool_bar_window))
24066 mouse_face_overwritten_p
24067 |= expose_window (XWINDOW (f->tool_bar_window), &r);
24068
24069 #ifdef HAVE_X_WINDOWS
24070 #ifndef MSDOS
24071 #ifndef USE_X_TOOLKIT
24072 if (WINDOWP (f->menu_bar_window))
24073 mouse_face_overwritten_p
24074 |= expose_window (XWINDOW (f->menu_bar_window), &r);
24075 #endif /* not USE_X_TOOLKIT */
24076 #endif
24077 #endif
24078
24079 /* Some window managers support a focus-follows-mouse style with
24080 delayed raising of frames. Imagine a partially obscured frame,
24081 and moving the mouse into partially obscured mouse-face on that
24082 frame. The visible part of the mouse-face will be highlighted,
24083 then the WM raises the obscured frame. With at least one WM, KDE
24084 2.1, Emacs is not getting any event for the raising of the frame
24085 (even tried with SubstructureRedirectMask), only Expose events.
24086 These expose events will draw text normally, i.e. not
24087 highlighted. Which means we must redo the highlight here.
24088 Subsume it under ``we love X''. --gerd 2001-08-15 */
24089 /* Included in Windows version because Windows most likely does not
24090 do the right thing if any third party tool offers
24091 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
24092 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
24093 {
24094 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24095 if (f == dpyinfo->mouse_face_mouse_frame)
24096 {
24097 int x = dpyinfo->mouse_face_mouse_x;
24098 int y = dpyinfo->mouse_face_mouse_y;
24099 clear_mouse_face (dpyinfo);
24100 note_mouse_highlight (f, x, y);
24101 }
24102 }
24103 }
24104
24105
24106 /* EXPORT:
24107 Determine the intersection of two rectangles R1 and R2. Return
24108 the intersection in *RESULT. Value is non-zero if RESULT is not
24109 empty. */
24110
24111 int
24112 x_intersect_rectangles (r1, r2, result)
24113 XRectangle *r1, *r2, *result;
24114 {
24115 XRectangle *left, *right;
24116 XRectangle *upper, *lower;
24117 int intersection_p = 0;
24118
24119 /* Rearrange so that R1 is the left-most rectangle. */
24120 if (r1->x < r2->x)
24121 left = r1, right = r2;
24122 else
24123 left = r2, right = r1;
24124
24125 /* X0 of the intersection is right.x0, if this is inside R1,
24126 otherwise there is no intersection. */
24127 if (right->x <= left->x + left->width)
24128 {
24129 result->x = right->x;
24130
24131 /* The right end of the intersection is the minimum of the
24132 the right ends of left and right. */
24133 result->width = (min (left->x + left->width, right->x + right->width)
24134 - result->x);
24135
24136 /* Same game for Y. */
24137 if (r1->y < r2->y)
24138 upper = r1, lower = r2;
24139 else
24140 upper = r2, lower = r1;
24141
24142 /* The upper end of the intersection is lower.y0, if this is inside
24143 of upper. Otherwise, there is no intersection. */
24144 if (lower->y <= upper->y + upper->height)
24145 {
24146 result->y = lower->y;
24147
24148 /* The lower end of the intersection is the minimum of the lower
24149 ends of upper and lower. */
24150 result->height = (min (lower->y + lower->height,
24151 upper->y + upper->height)
24152 - result->y);
24153 intersection_p = 1;
24154 }
24155 }
24156
24157 return intersection_p;
24158 }
24159
24160 #endif /* HAVE_WINDOW_SYSTEM */
24161
24162 \f
24163 /***********************************************************************
24164 Initialization
24165 ***********************************************************************/
24166
24167 void
24168 syms_of_xdisp ()
24169 {
24170 Vwith_echo_area_save_vector = Qnil;
24171 staticpro (&Vwith_echo_area_save_vector);
24172
24173 Vmessage_stack = Qnil;
24174 staticpro (&Vmessage_stack);
24175
24176 Qinhibit_redisplay = intern ("inhibit-redisplay");
24177 staticpro (&Qinhibit_redisplay);
24178
24179 message_dolog_marker1 = Fmake_marker ();
24180 staticpro (&message_dolog_marker1);
24181 message_dolog_marker2 = Fmake_marker ();
24182 staticpro (&message_dolog_marker2);
24183 message_dolog_marker3 = Fmake_marker ();
24184 staticpro (&message_dolog_marker3);
24185
24186 #if GLYPH_DEBUG
24187 defsubr (&Sdump_frame_glyph_matrix);
24188 defsubr (&Sdump_glyph_matrix);
24189 defsubr (&Sdump_glyph_row);
24190 defsubr (&Sdump_tool_bar_row);
24191 defsubr (&Strace_redisplay);
24192 defsubr (&Strace_to_stderr);
24193 #endif
24194 #ifdef HAVE_WINDOW_SYSTEM
24195 defsubr (&Stool_bar_lines_needed);
24196 defsubr (&Slookup_image_map);
24197 #endif
24198 defsubr (&Sformat_mode_line);
24199 defsubr (&Sinvisible_p);
24200
24201 staticpro (&Qmenu_bar_update_hook);
24202 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
24203
24204 staticpro (&Qoverriding_terminal_local_map);
24205 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
24206
24207 staticpro (&Qoverriding_local_map);
24208 Qoverriding_local_map = intern ("overriding-local-map");
24209
24210 staticpro (&Qwindow_scroll_functions);
24211 Qwindow_scroll_functions = intern ("window-scroll-functions");
24212
24213 staticpro (&Qredisplay_end_trigger_functions);
24214 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
24215
24216 staticpro (&Qinhibit_point_motion_hooks);
24217 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
24218
24219 QCdata = intern (":data");
24220 staticpro (&QCdata);
24221 Qdisplay = intern ("display");
24222 staticpro (&Qdisplay);
24223 Qspace_width = intern ("space-width");
24224 staticpro (&Qspace_width);
24225 Qraise = intern ("raise");
24226 staticpro (&Qraise);
24227 Qslice = intern ("slice");
24228 staticpro (&Qslice);
24229 Qspace = intern ("space");
24230 staticpro (&Qspace);
24231 Qmargin = intern ("margin");
24232 staticpro (&Qmargin);
24233 Qpointer = intern ("pointer");
24234 staticpro (&Qpointer);
24235 Qleft_margin = intern ("left-margin");
24236 staticpro (&Qleft_margin);
24237 Qright_margin = intern ("right-margin");
24238 staticpro (&Qright_margin);
24239 Qcenter = intern ("center");
24240 staticpro (&Qcenter);
24241 Qline_height = intern ("line-height");
24242 staticpro (&Qline_height);
24243 QCalign_to = intern (":align-to");
24244 staticpro (&QCalign_to);
24245 QCrelative_width = intern (":relative-width");
24246 staticpro (&QCrelative_width);
24247 QCrelative_height = intern (":relative-height");
24248 staticpro (&QCrelative_height);
24249 QCeval = intern (":eval");
24250 staticpro (&QCeval);
24251 QCpropertize = intern (":propertize");
24252 staticpro (&QCpropertize);
24253 QCfile = intern (":file");
24254 staticpro (&QCfile);
24255 Qfontified = intern ("fontified");
24256 staticpro (&Qfontified);
24257 Qfontification_functions = intern ("fontification-functions");
24258 staticpro (&Qfontification_functions);
24259 Qtrailing_whitespace = intern ("trailing-whitespace");
24260 staticpro (&Qtrailing_whitespace);
24261 Qescape_glyph = intern ("escape-glyph");
24262 staticpro (&Qescape_glyph);
24263 Qnobreak_space = intern ("nobreak-space");
24264 staticpro (&Qnobreak_space);
24265 Qimage = intern ("image");
24266 staticpro (&Qimage);
24267 QCmap = intern (":map");
24268 staticpro (&QCmap);
24269 QCpointer = intern (":pointer");
24270 staticpro (&QCpointer);
24271 Qrect = intern ("rect");
24272 staticpro (&Qrect);
24273 Qcircle = intern ("circle");
24274 staticpro (&Qcircle);
24275 Qpoly = intern ("poly");
24276 staticpro (&Qpoly);
24277 Qmessage_truncate_lines = intern ("message-truncate-lines");
24278 staticpro (&Qmessage_truncate_lines);
24279 Qgrow_only = intern ("grow-only");
24280 staticpro (&Qgrow_only);
24281 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
24282 staticpro (&Qinhibit_menubar_update);
24283 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
24284 staticpro (&Qinhibit_eval_during_redisplay);
24285 Qposition = intern ("position");
24286 staticpro (&Qposition);
24287 Qbuffer_position = intern ("buffer-position");
24288 staticpro (&Qbuffer_position);
24289 Qobject = intern ("object");
24290 staticpro (&Qobject);
24291 Qbar = intern ("bar");
24292 staticpro (&Qbar);
24293 Qhbar = intern ("hbar");
24294 staticpro (&Qhbar);
24295 Qbox = intern ("box");
24296 staticpro (&Qbox);
24297 Qhollow = intern ("hollow");
24298 staticpro (&Qhollow);
24299 Qhand = intern ("hand");
24300 staticpro (&Qhand);
24301 Qarrow = intern ("arrow");
24302 staticpro (&Qarrow);
24303 Qtext = intern ("text");
24304 staticpro (&Qtext);
24305 Qrisky_local_variable = intern ("risky-local-variable");
24306 staticpro (&Qrisky_local_variable);
24307 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
24308 staticpro (&Qinhibit_free_realized_faces);
24309
24310 list_of_error = Fcons (Fcons (intern ("error"),
24311 Fcons (intern ("void-variable"), Qnil)),
24312 Qnil);
24313 staticpro (&list_of_error);
24314
24315 Qlast_arrow_position = intern ("last-arrow-position");
24316 staticpro (&Qlast_arrow_position);
24317 Qlast_arrow_string = intern ("last-arrow-string");
24318 staticpro (&Qlast_arrow_string);
24319
24320 Qoverlay_arrow_string = intern ("overlay-arrow-string");
24321 staticpro (&Qoverlay_arrow_string);
24322 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
24323 staticpro (&Qoverlay_arrow_bitmap);
24324
24325 echo_buffer[0] = echo_buffer[1] = Qnil;
24326 staticpro (&echo_buffer[0]);
24327 staticpro (&echo_buffer[1]);
24328
24329 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
24330 staticpro (&echo_area_buffer[0]);
24331 staticpro (&echo_area_buffer[1]);
24332
24333 Vmessages_buffer_name = build_string ("*Messages*");
24334 staticpro (&Vmessages_buffer_name);
24335
24336 mode_line_proptrans_alist = Qnil;
24337 staticpro (&mode_line_proptrans_alist);
24338 mode_line_string_list = Qnil;
24339 staticpro (&mode_line_string_list);
24340 mode_line_string_face = Qnil;
24341 staticpro (&mode_line_string_face);
24342 mode_line_string_face_prop = Qnil;
24343 staticpro (&mode_line_string_face_prop);
24344 Vmode_line_unwind_vector = Qnil;
24345 staticpro (&Vmode_line_unwind_vector);
24346
24347 help_echo_string = Qnil;
24348 staticpro (&help_echo_string);
24349 help_echo_object = Qnil;
24350 staticpro (&help_echo_object);
24351 help_echo_window = Qnil;
24352 staticpro (&help_echo_window);
24353 previous_help_echo_string = Qnil;
24354 staticpro (&previous_help_echo_string);
24355 help_echo_pos = -1;
24356
24357 #ifdef HAVE_WINDOW_SYSTEM
24358 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
24359 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
24360 For example, if a block cursor is over a tab, it will be drawn as
24361 wide as that tab on the display. */);
24362 x_stretch_cursor_p = 0;
24363 #endif
24364
24365 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
24366 doc: /* *Non-nil means highlight trailing whitespace.
24367 The face used for trailing whitespace is `trailing-whitespace'. */);
24368 Vshow_trailing_whitespace = Qnil;
24369
24370 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
24371 doc: /* *Control highlighting of nobreak space and soft hyphen.
24372 A value of t means highlight the character itself (for nobreak space,
24373 use face `nobreak-space').
24374 A value of nil means no highlighting.
24375 Other values mean display the escape glyph followed by an ordinary
24376 space or ordinary hyphen. */);
24377 Vnobreak_char_display = Qt;
24378
24379 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
24380 doc: /* *The pointer shape to show in void text areas.
24381 A value of nil means to show the text pointer. Other options are `arrow',
24382 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
24383 Vvoid_text_area_pointer = Qarrow;
24384
24385 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
24386 doc: /* Non-nil means don't actually do any redisplay.
24387 This is used for internal purposes. */);
24388 Vinhibit_redisplay = Qnil;
24389
24390 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
24391 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
24392 Vglobal_mode_string = Qnil;
24393
24394 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
24395 doc: /* Marker for where to display an arrow on top of the buffer text.
24396 This must be the beginning of a line in order to work.
24397 See also `overlay-arrow-string'. */);
24398 Voverlay_arrow_position = Qnil;
24399
24400 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
24401 doc: /* String to display as an arrow in non-window frames.
24402 See also `overlay-arrow-position'. */);
24403 Voverlay_arrow_string = build_string ("=>");
24404
24405 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
24406 doc: /* List of variables (symbols) which hold markers for overlay arrows.
24407 The symbols on this list are examined during redisplay to determine
24408 where to display overlay arrows. */);
24409 Voverlay_arrow_variable_list
24410 = Fcons (intern ("overlay-arrow-position"), Qnil);
24411
24412 DEFVAR_INT ("scroll-step", &scroll_step,
24413 doc: /* *The number of lines to try scrolling a window by when point moves out.
24414 If that fails to bring point back on frame, point is centered instead.
24415 If this is zero, point is always centered after it moves off frame.
24416 If you want scrolling to always be a line at a time, you should set
24417 `scroll-conservatively' to a large value rather than set this to 1. */);
24418
24419 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
24420 doc: /* *Scroll up to this many lines, to bring point back on screen.
24421 A value of zero means to scroll the text to center point vertically
24422 in the window. */);
24423 scroll_conservatively = 0;
24424
24425 DEFVAR_INT ("scroll-margin", &scroll_margin,
24426 doc: /* *Number of lines of margin at the top and bottom of a window.
24427 Recenter the window whenever point gets within this many lines
24428 of the top or bottom of the window. */);
24429 scroll_margin = 0;
24430
24431 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
24432 doc: /* Pixels per inch value for non-window system displays.
24433 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
24434 Vdisplay_pixels_per_inch = make_float (72.0);
24435
24436 #if GLYPH_DEBUG
24437 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
24438 #endif
24439
24440 DEFVAR_BOOL ("truncate-partial-width-windows",
24441 &truncate_partial_width_windows,
24442 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
24443 truncate_partial_width_windows = 1;
24444
24445 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
24446 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
24447 Any other value means to use the appropriate face, `mode-line',
24448 `header-line', or `menu' respectively. */);
24449 mode_line_inverse_video = 1;
24450
24451 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
24452 doc: /* *Maximum buffer size for which line number should be displayed.
24453 If the buffer is bigger than this, the line number does not appear
24454 in the mode line. A value of nil means no limit. */);
24455 Vline_number_display_limit = Qnil;
24456
24457 DEFVAR_INT ("line-number-display-limit-width",
24458 &line_number_display_limit_width,
24459 doc: /* *Maximum line width (in characters) for line number display.
24460 If the average length of the lines near point is bigger than this, then the
24461 line number may be omitted from the mode line. */);
24462 line_number_display_limit_width = 200;
24463
24464 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
24465 doc: /* *Non-nil means highlight region even in nonselected windows. */);
24466 highlight_nonselected_windows = 0;
24467
24468 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
24469 doc: /* Non-nil if more than one frame is visible on this display.
24470 Minibuffer-only frames don't count, but iconified frames do.
24471 This variable is not guaranteed to be accurate except while processing
24472 `frame-title-format' and `icon-title-format'. */);
24473
24474 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
24475 doc: /* Template for displaying the title bar of visible frames.
24476 \(Assuming the window manager supports this feature.)
24477
24478 This variable has the same structure as `mode-line-format', except that
24479 the %c and %l constructs are ignored. It is used only on frames for
24480 which no explicit name has been set \(see `modify-frame-parameters'). */);
24481
24482 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
24483 doc: /* Template for displaying the title bar of an iconified frame.
24484 \(Assuming the window manager supports this feature.)
24485 This variable has the same structure as `mode-line-format' (which see),
24486 and is used only on frames for which no explicit name has been set
24487 \(see `modify-frame-parameters'). */);
24488 Vicon_title_format
24489 = Vframe_title_format
24490 = Fcons (intern ("multiple-frames"),
24491 Fcons (build_string ("%b"),
24492 Fcons (Fcons (empty_unibyte_string,
24493 Fcons (intern ("invocation-name"),
24494 Fcons (build_string ("@"),
24495 Fcons (intern ("system-name"),
24496 Qnil)))),
24497 Qnil)));
24498
24499 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
24500 doc: /* Maximum number of lines to keep in the message log buffer.
24501 If nil, disable message logging. If t, log messages but don't truncate
24502 the buffer when it becomes large. */);
24503 Vmessage_log_max = make_number (100);
24504
24505 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
24506 doc: /* Functions called before redisplay, if window sizes have changed.
24507 The value should be a list of functions that take one argument.
24508 Just before redisplay, for each frame, if any of its windows have changed
24509 size since the last redisplay, or have been split or deleted,
24510 all the functions in the list are called, with the frame as argument. */);
24511 Vwindow_size_change_functions = Qnil;
24512
24513 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
24514 doc: /* List of functions to call before redisplaying a window with scrolling.
24515 Each function is called with two arguments, the window
24516 and its new display-start position. Note that the value of `window-end'
24517 is not valid when these functions are called. */);
24518 Vwindow_scroll_functions = Qnil;
24519
24520 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
24521 doc: /* Functions called when redisplay of a window reaches the end trigger.
24522 Each function is called with two arguments, the window and the end trigger value.
24523 See `set-window-redisplay-end-trigger'. */);
24524 Vredisplay_end_trigger_functions = Qnil;
24525
24526 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
24527 doc: /* *Non-nil means autoselect window with mouse pointer.
24528 If nil, do not autoselect windows.
24529 A positive number means delay autoselection by that many seconds: a
24530 window is autoselected only after the mouse has remained in that
24531 window for the duration of the delay.
24532 A negative number has a similar effect, but causes windows to be
24533 autoselected only after the mouse has stopped moving. \(Because of
24534 the way Emacs compares mouse events, you will occasionally wait twice
24535 that time before the window gets selected.\)
24536 Any other value means to autoselect window instantaneously when the
24537 mouse pointer enters it.
24538
24539 Autoselection selects the minibuffer only if it is active, and never
24540 unselects the minibuffer if it is active.
24541
24542 When customizing this variable make sure that the actual value of
24543 `focus-follows-mouse' matches the behavior of your window manager. */);
24544 Vmouse_autoselect_window = Qnil;
24545
24546 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
24547 doc: /* *Non-nil means automatically resize tool-bars.
24548 This dynamically changes the tool-bar's height to the minimum height
24549 that is needed to make all tool-bar items visible.
24550 If value is `grow-only', the tool-bar's height is only increased
24551 automatically; to decrease the tool-bar height, use \\[recenter]. */);
24552 Vauto_resize_tool_bars = Qt;
24553
24554 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
24555 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
24556 auto_raise_tool_bar_buttons_p = 1;
24557
24558 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
24559 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
24560 make_cursor_line_fully_visible_p = 1;
24561
24562 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
24563 doc: /* *Border below tool-bar in pixels.
24564 If an integer, use it as the height of the border.
24565 If it is one of `internal-border-width' or `border-width', use the
24566 value of the corresponding frame parameter.
24567 Otherwise, no border is added below the tool-bar. */);
24568 Vtool_bar_border = Qinternal_border_width;
24569
24570 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
24571 doc: /* *Margin around tool-bar buttons in pixels.
24572 If an integer, use that for both horizontal and vertical margins.
24573 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
24574 HORZ specifying the horizontal margin, and VERT specifying the
24575 vertical margin. */);
24576 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
24577
24578 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
24579 doc: /* *Relief thickness of tool-bar buttons. */);
24580 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
24581
24582 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
24583 doc: /* List of functions to call to fontify regions of text.
24584 Each function is called with one argument POS. Functions must
24585 fontify a region starting at POS in the current buffer, and give
24586 fontified regions the property `fontified'. */);
24587 Vfontification_functions = Qnil;
24588 Fmake_variable_buffer_local (Qfontification_functions);
24589
24590 DEFVAR_BOOL ("unibyte-display-via-language-environment",
24591 &unibyte_display_via_language_environment,
24592 doc: /* *Non-nil means display unibyte text according to language environment.
24593 Specifically this means that unibyte non-ASCII characters
24594 are displayed by converting them to the equivalent multibyte characters
24595 according to the current language environment. As a result, they are
24596 displayed according to the current fontset. */);
24597 unibyte_display_via_language_environment = 0;
24598
24599 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
24600 doc: /* *Maximum height for resizing mini-windows.
24601 If a float, it specifies a fraction of the mini-window frame's height.
24602 If an integer, it specifies a number of lines. */);
24603 Vmax_mini_window_height = make_float (0.25);
24604
24605 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
24606 doc: /* *How to resize mini-windows.
24607 A value of nil means don't automatically resize mini-windows.
24608 A value of t means resize them to fit the text displayed in them.
24609 A value of `grow-only', the default, means let mini-windows grow
24610 only, until their display becomes empty, at which point the windows
24611 go back to their normal size. */);
24612 Vresize_mini_windows = Qgrow_only;
24613
24614 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
24615 doc: /* Alist specifying how to blink the cursor off.
24616 Each element has the form (ON-STATE . OFF-STATE). Whenever the
24617 `cursor-type' frame-parameter or variable equals ON-STATE,
24618 comparing using `equal', Emacs uses OFF-STATE to specify
24619 how to blink it off. ON-STATE and OFF-STATE are values for
24620 the `cursor-type' frame parameter.
24621
24622 If a frame's ON-STATE has no entry in this list,
24623 the frame's other specifications determine how to blink the cursor off. */);
24624 Vblink_cursor_alist = Qnil;
24625
24626 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
24627 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
24628 automatic_hscrolling_p = 1;
24629
24630 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
24631 doc: /* *How many columns away from the window edge point is allowed to get
24632 before automatic hscrolling will horizontally scroll the window. */);
24633 hscroll_margin = 5;
24634
24635 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
24636 doc: /* *How many columns to scroll the window when point gets too close to the edge.
24637 When point is less than `hscroll-margin' columns from the window
24638 edge, automatic hscrolling will scroll the window by the amount of columns
24639 determined by this variable. If its value is a positive integer, scroll that
24640 many columns. If it's a positive floating-point number, it specifies the
24641 fraction of the window's width to scroll. If it's nil or zero, point will be
24642 centered horizontally after the scroll. Any other value, including negative
24643 numbers, are treated as if the value were zero.
24644
24645 Automatic hscrolling always moves point outside the scroll margin, so if
24646 point was more than scroll step columns inside the margin, the window will
24647 scroll more than the value given by the scroll step.
24648
24649 Note that the lower bound for automatic hscrolling specified by `scroll-left'
24650 and `scroll-right' overrides this variable's effect. */);
24651 Vhscroll_step = make_number (0);
24652
24653 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
24654 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
24655 Bind this around calls to `message' to let it take effect. */);
24656 message_truncate_lines = 0;
24657
24658 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
24659 doc: /* Normal hook run to update the menu bar definitions.
24660 Redisplay runs this hook before it redisplays the menu bar.
24661 This is used to update submenus such as Buffers,
24662 whose contents depend on various data. */);
24663 Vmenu_bar_update_hook = Qnil;
24664
24665 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
24666 doc: /* Frame for which we are updating a menu.
24667 The enable predicate for a menu binding should check this variable. */);
24668 Vmenu_updating_frame = Qnil;
24669
24670 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
24671 doc: /* Non-nil means don't update menu bars. Internal use only. */);
24672 inhibit_menubar_update = 0;
24673
24674 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
24675 doc: /* Non-nil means don't eval Lisp during redisplay. */);
24676 inhibit_eval_during_redisplay = 0;
24677
24678 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
24679 doc: /* Non-nil means don't free realized faces. Internal use only. */);
24680 inhibit_free_realized_faces = 0;
24681
24682 #if GLYPH_DEBUG
24683 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
24684 doc: /* Inhibit try_window_id display optimization. */);
24685 inhibit_try_window_id = 0;
24686
24687 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
24688 doc: /* Inhibit try_window_reusing display optimization. */);
24689 inhibit_try_window_reusing = 0;
24690
24691 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
24692 doc: /* Inhibit try_cursor_movement display optimization. */);
24693 inhibit_try_cursor_movement = 0;
24694 #endif /* GLYPH_DEBUG */
24695
24696 DEFVAR_INT ("overline-margin", &overline_margin,
24697 doc: /* *Space between overline and text, in pixels.
24698 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
24699 margin to the caracter height. */);
24700 overline_margin = 2;
24701 }
24702
24703
24704 /* Initialize this module when Emacs starts. */
24705
24706 void
24707 init_xdisp ()
24708 {
24709 Lisp_Object root_window;
24710 struct window *mini_w;
24711
24712 current_header_line_height = current_mode_line_height = -1;
24713
24714 CHARPOS (this_line_start_pos) = 0;
24715
24716 mini_w = XWINDOW (minibuf_window);
24717 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
24718
24719 if (!noninteractive)
24720 {
24721 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
24722 int i;
24723
24724 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
24725 set_window_height (root_window,
24726 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
24727 0);
24728 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
24729 set_window_height (minibuf_window, 1, 0);
24730
24731 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
24732 mini_w->total_cols = make_number (FRAME_COLS (f));
24733
24734 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
24735 scratch_glyph_row.glyphs[TEXT_AREA + 1]
24736 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
24737
24738 /* The default ellipsis glyphs `...'. */
24739 for (i = 0; i < 3; ++i)
24740 default_invis_vector[i] = make_number ('.');
24741 }
24742
24743 {
24744 /* Allocate the buffer for frame titles.
24745 Also used for `format-mode-line'. */
24746 int size = 100;
24747 mode_line_noprop_buf = (char *) xmalloc (size);
24748 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
24749 mode_line_noprop_ptr = mode_line_noprop_buf;
24750 mode_line_target = MODE_LINE_DISPLAY;
24751 }
24752
24753 help_echo_showing_p = 0;
24754 }
24755
24756
24757 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
24758 (do not change this comment) */