]> code.delx.au - gnu-emacs/blob - src/xdisp.c
(redisplay_internal): Make sure Elisp code always sees
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
3 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005, 2006, 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 "charset.h"
181 #include "indent.h"
182 #include "commands.h"
183 #include "keymap.h"
184 #include "macros.h"
185 #include "disptab.h"
186 #include "termhooks.h"
187 #include "intervals.h"
188 #include "coding.h"
189 #include "process.h"
190 #include "region-cache.h"
191 #include "fontset.h"
192 #include "blockinput.h"
193
194 #ifdef HAVE_X_WINDOWS
195 #include "xterm.h"
196 #endif
197 #ifdef WINDOWSNT
198 #include "w32term.h"
199 #endif
200 #ifdef MAC_OS
201 #include "macterm.h"
202 #endif
203
204 #ifndef FRAME_X_OUTPUT
205 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
206 #endif
207
208 #define INFINITY 10000000
209
210 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
211 || defined (USE_GTK)
212 extern void set_frame_menubar P_ ((struct frame *f, int, int));
213 extern int pending_menu_activation;
214 #endif
215
216 extern int interrupt_input;
217 extern int command_loop_level;
218
219 extern Lisp_Object do_mouse_tracking;
220
221 extern int minibuffer_auto_raise;
222 extern Lisp_Object Vminibuffer_list;
223
224 extern Lisp_Object Qface;
225 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226
227 extern Lisp_Object Voverriding_local_map;
228 extern Lisp_Object Voverriding_local_map_menu_flag;
229 extern Lisp_Object Qmenu_item;
230 extern Lisp_Object Qwhen;
231 extern Lisp_Object Qhelp_echo;
232
233 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
234 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
235 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
236 Lisp_Object Qinhibit_point_motion_hooks;
237 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
238 Lisp_Object Qfontified;
239 Lisp_Object Qgrow_only;
240 Lisp_Object Qinhibit_eval_during_redisplay;
241 Lisp_Object Qbuffer_position, Qposition, Qobject;
242
243 /* Cursor shapes */
244 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245
246 /* Pointer shapes */
247 Lisp_Object Qarrow, Qhand, Qtext;
248
249 Lisp_Object Qrisky_local_variable;
250
251 /* Holds the list (error). */
252 Lisp_Object list_of_error;
253
254 /* Functions called to fontify regions of text. */
255
256 Lisp_Object Vfontification_functions;
257 Lisp_Object Qfontification_functions;
258
259 /* Non-nil means automatically select any window when the mouse
260 cursor moves into it. */
261 Lisp_Object Vmouse_autoselect_window;
262
263 /* Non-zero means draw tool bar buttons raised when the mouse moves
264 over them. */
265
266 int auto_raise_tool_bar_buttons_p;
267
268 /* Non-zero means to reposition window if cursor line is only partially visible. */
269
270 int make_cursor_line_fully_visible_p;
271
272 /* Margin below tool bar in pixels. 0 or nil means no margin.
273 If value is `internal-border-width' or `border-width',
274 the corresponding frame parameter is used. */
275
276 Lisp_Object Vtool_bar_border;
277
278 /* Margin around tool bar buttons in pixels. */
279
280 Lisp_Object Vtool_bar_button_margin;
281
282 /* Thickness of shadow to draw around tool bar buttons. */
283
284 EMACS_INT tool_bar_button_relief;
285
286 /* Non-nil means automatically resize tool-bars so that all tool-bar
287 items are visible, and no blank lines remain.
288
289 If value is `grow-only', only make tool-bar bigger. */
290
291 Lisp_Object Vauto_resize_tool_bars;
292
293 /* Non-zero means draw block and hollow cursor as wide as the glyph
294 under it. For example, if a block cursor is over a tab, it will be
295 drawn as wide as that tab on the display. */
296
297 int x_stretch_cursor_p;
298
299 /* Non-nil means don't actually do any redisplay. */
300
301 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
302
303 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
304
305 int inhibit_eval_during_redisplay;
306
307 /* Names of text properties relevant for redisplay. */
308
309 Lisp_Object Qdisplay;
310 extern Lisp_Object Qface, Qinvisible, Qwidth;
311
312 /* Symbols used in text property values. */
313
314 Lisp_Object Vdisplay_pixels_per_inch;
315 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
316 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
317 Lisp_Object Qslice;
318 Lisp_Object Qcenter;
319 Lisp_Object Qmargin, Qpointer;
320 Lisp_Object Qline_height;
321 extern Lisp_Object Qheight;
322 extern Lisp_Object QCwidth, QCheight, QCascent;
323 extern Lisp_Object Qscroll_bar;
324 extern Lisp_Object Qcursor;
325
326 /* Non-nil means highlight trailing whitespace. */
327
328 Lisp_Object Vshow_trailing_whitespace;
329
330 /* Non-nil means escape non-break space and hyphens. */
331
332 Lisp_Object Vnobreak_char_display;
333
334 #ifdef HAVE_WINDOW_SYSTEM
335 extern Lisp_Object Voverflow_newline_into_fringe;
336
337 /* Test if overflow newline into fringe. Called with iterator IT
338 at or past right window margin, and with IT->current_x set. */
339
340 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
341 (!NILP (Voverflow_newline_into_fringe) \
342 && FRAME_WINDOW_P (it->f) \
343 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
344 && it->current_x == it->last_visible_x)
345
346 #endif /* HAVE_WINDOW_SYSTEM */
347
348 /* Non-nil means show the text cursor in void text areas
349 i.e. in blank areas after eol and eob. This used to be
350 the default in 21.3. */
351
352 Lisp_Object Vvoid_text_area_pointer;
353
354 /* Name of the face used to highlight trailing whitespace. */
355
356 Lisp_Object Qtrailing_whitespace;
357
358 /* Name and number of the face used to highlight escape glyphs. */
359
360 Lisp_Object Qescape_glyph;
361
362 /* Name and number of the face used to highlight non-breaking spaces. */
363
364 Lisp_Object Qnobreak_space;
365
366 /* The symbol `image' which is the car of the lists used to represent
367 images in Lisp. */
368
369 Lisp_Object Qimage;
370
371 /* The image map types. */
372 Lisp_Object QCmap, QCpointer;
373 Lisp_Object Qrect, Qcircle, Qpoly;
374
375 /* Non-zero means print newline to stdout before next mini-buffer
376 message. */
377
378 int noninteractive_need_newline;
379
380 /* Non-zero means print newline to message log before next message. */
381
382 static int message_log_need_newline;
383
384 /* Three markers that message_dolog uses.
385 It could allocate them itself, but that causes trouble
386 in handling memory-full errors. */
387 static Lisp_Object message_dolog_marker1;
388 static Lisp_Object message_dolog_marker2;
389 static Lisp_Object message_dolog_marker3;
390 \f
391 /* The buffer position of the first character appearing entirely or
392 partially on the line of the selected window which contains the
393 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
394 redisplay optimization in redisplay_internal. */
395
396 static struct text_pos this_line_start_pos;
397
398 /* Number of characters past the end of the line above, including the
399 terminating newline. */
400
401 static struct text_pos this_line_end_pos;
402
403 /* The vertical positions and the height of this line. */
404
405 static int this_line_vpos;
406 static int this_line_y;
407 static int this_line_pixel_height;
408
409 /* X position at which this display line starts. Usually zero;
410 negative if first character is partially visible. */
411
412 static int this_line_start_x;
413
414 /* Buffer that this_line_.* variables are referring to. */
415
416 static struct buffer *this_line_buffer;
417
418 /* Nonzero means truncate lines in all windows less wide than the
419 frame. */
420
421 int truncate_partial_width_windows;
422
423 /* A flag to control how to display unibyte 8-bit character. */
424
425 int unibyte_display_via_language_environment;
426
427 /* Nonzero means we have more than one non-mini-buffer-only frame.
428 Not guaranteed to be accurate except while parsing
429 frame-title-format. */
430
431 int multiple_frames;
432
433 Lisp_Object Vglobal_mode_string;
434
435
436 /* List of variables (symbols) which hold markers for overlay arrows.
437 The symbols on this list are examined during redisplay to determine
438 where to display overlay arrows. */
439
440 Lisp_Object Voverlay_arrow_variable_list;
441
442 /* Marker for where to display an arrow on top of the buffer text. */
443
444 Lisp_Object Voverlay_arrow_position;
445
446 /* String to display for the arrow. Only used on terminal frames. */
447
448 Lisp_Object Voverlay_arrow_string;
449
450 /* Values of those variables at last redisplay are stored as
451 properties on `overlay-arrow-position' symbol. However, if
452 Voverlay_arrow_position is a marker, last-arrow-position is its
453 numerical position. */
454
455 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
456
457 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
458 properties on a symbol in overlay-arrow-variable-list. */
459
460 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
461
462 /* Like mode-line-format, but for the title bar on a visible frame. */
463
464 Lisp_Object Vframe_title_format;
465
466 /* Like mode-line-format, but for the title bar on an iconified frame. */
467
468 Lisp_Object Vicon_title_format;
469
470 /* List of functions to call when a window's size changes. These
471 functions get one arg, a frame on which one or more windows' sizes
472 have changed. */
473
474 static Lisp_Object Vwindow_size_change_functions;
475
476 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
477
478 /* Nonzero if an overlay arrow has been displayed in this window. */
479
480 static int overlay_arrow_seen;
481
482 /* Nonzero means highlight the region even in nonselected windows. */
483
484 int highlight_nonselected_windows;
485
486 /* If cursor motion alone moves point off frame, try scrolling this
487 many lines up or down if that will bring it back. */
488
489 static EMACS_INT scroll_step;
490
491 /* Nonzero means scroll just far enough to bring point back on the
492 screen, when appropriate. */
493
494 static EMACS_INT scroll_conservatively;
495
496 /* Recenter the window whenever point gets within this many lines of
497 the top or bottom of the window. This value is translated into a
498 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
499 that there is really a fixed pixel height scroll margin. */
500
501 EMACS_INT scroll_margin;
502
503 /* Number of windows showing the buffer of the selected window (or
504 another buffer with the same base buffer). keyboard.c refers to
505 this. */
506
507 int buffer_shared;
508
509 /* Vector containing glyphs for an ellipsis `...'. */
510
511 static Lisp_Object default_invis_vector[3];
512
513 /* Zero means display the mode-line/header-line/menu-bar in the default face
514 (this slightly odd definition is for compatibility with previous versions
515 of emacs), non-zero means display them using their respective faces.
516
517 This variable is deprecated. */
518
519 int mode_line_inverse_video;
520
521 /* Prompt to display in front of the mini-buffer contents. */
522
523 Lisp_Object minibuf_prompt;
524
525 /* Width of current mini-buffer prompt. Only set after display_line
526 of the line that contains the prompt. */
527
528 int minibuf_prompt_width;
529
530 /* This is the window where the echo area message was displayed. It
531 is always a mini-buffer window, but it may not be the same window
532 currently active as a mini-buffer. */
533
534 Lisp_Object echo_area_window;
535
536 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
537 pushes the current message and the value of
538 message_enable_multibyte on the stack, the function restore_message
539 pops the stack and displays MESSAGE again. */
540
541 Lisp_Object Vmessage_stack;
542
543 /* Nonzero means multibyte characters were enabled when the echo area
544 message was specified. */
545
546 int message_enable_multibyte;
547
548 /* Nonzero if we should redraw the mode lines on the next redisplay. */
549
550 int update_mode_lines;
551
552 /* Nonzero if window sizes or contents have changed since last
553 redisplay that finished. */
554
555 int windows_or_buffers_changed;
556
557 /* Nonzero means a frame's cursor type has been changed. */
558
559 int cursor_type_changed;
560
561 /* Nonzero after display_mode_line if %l was used and it displayed a
562 line number. */
563
564 int line_number_displayed;
565
566 /* Maximum buffer size for which to display line numbers. */
567
568 Lisp_Object Vline_number_display_limit;
569
570 /* Line width to consider when repositioning for line number display. */
571
572 static EMACS_INT line_number_display_limit_width;
573
574 /* Number of lines to keep in the message log buffer. t means
575 infinite. nil means don't log at all. */
576
577 Lisp_Object Vmessage_log_max;
578
579 /* The name of the *Messages* buffer, a string. */
580
581 static Lisp_Object Vmessages_buffer_name;
582
583 /* Current, index 0, and last displayed echo area message. Either
584 buffers from echo_buffers, or nil to indicate no message. */
585
586 Lisp_Object echo_area_buffer[2];
587
588 /* The buffers referenced from echo_area_buffer. */
589
590 static Lisp_Object echo_buffer[2];
591
592 /* A vector saved used in with_area_buffer to reduce consing. */
593
594 static Lisp_Object Vwith_echo_area_save_vector;
595
596 /* Non-zero means display_echo_area should display the last echo area
597 message again. Set by redisplay_preserve_echo_area. */
598
599 static int display_last_displayed_message_p;
600
601 /* Nonzero if echo area is being used by print; zero if being used by
602 message. */
603
604 int message_buf_print;
605
606 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
607
608 Lisp_Object Qinhibit_menubar_update;
609 int inhibit_menubar_update;
610
611 /* When evaluating expressions from menu bar items (enable conditions,
612 for instance), this is the frame they are being processed for. */
613
614 Lisp_Object Vmenu_updating_frame;
615
616 /* Maximum height for resizing mini-windows. Either a float
617 specifying a fraction of the available height, or an integer
618 specifying a number of lines. */
619
620 Lisp_Object Vmax_mini_window_height;
621
622 /* Non-zero means messages should be displayed with truncated
623 lines instead of being continued. */
624
625 int message_truncate_lines;
626 Lisp_Object Qmessage_truncate_lines;
627
628 /* Set to 1 in clear_message to make redisplay_internal aware
629 of an emptied echo area. */
630
631 static int message_cleared_p;
632
633 /* How to blink the default frame cursor off. */
634 Lisp_Object Vblink_cursor_alist;
635
636 /* A scratch glyph row with contents used for generating truncation
637 glyphs. Also used in direct_output_for_insert. */
638
639 #define MAX_SCRATCH_GLYPHS 100
640 struct glyph_row scratch_glyph_row;
641 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
642
643 /* Ascent and height of the last line processed by move_it_to. */
644
645 static int last_max_ascent, last_height;
646
647 /* Non-zero if there's a help-echo in the echo area. */
648
649 int help_echo_showing_p;
650
651 /* If >= 0, computed, exact values of mode-line and header-line height
652 to use in the macros CURRENT_MODE_LINE_HEIGHT and
653 CURRENT_HEADER_LINE_HEIGHT. */
654
655 int current_mode_line_height, current_header_line_height;
656
657 /* The maximum distance to look ahead for text properties. Values
658 that are too small let us call compute_char_face and similar
659 functions too often which is expensive. Values that are too large
660 let us call compute_char_face and alike too often because we
661 might not be interested in text properties that far away. */
662
663 #define TEXT_PROP_DISTANCE_LIMIT 100
664
665 #if GLYPH_DEBUG
666
667 /* Variables to turn off display optimizations from Lisp. */
668
669 int inhibit_try_window_id, inhibit_try_window_reusing;
670 int inhibit_try_cursor_movement;
671
672 /* Non-zero means print traces of redisplay if compiled with
673 GLYPH_DEBUG != 0. */
674
675 int trace_redisplay_p;
676
677 #endif /* GLYPH_DEBUG */
678
679 #ifdef DEBUG_TRACE_MOVE
680 /* Non-zero means trace with TRACE_MOVE to stderr. */
681 int trace_move;
682
683 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
684 #else
685 #define TRACE_MOVE(x) (void) 0
686 #endif
687
688 /* Non-zero means automatically scroll windows horizontally to make
689 point visible. */
690
691 int automatic_hscrolling_p;
692
693 /* How close to the margin can point get before the window is scrolled
694 horizontally. */
695 EMACS_INT hscroll_margin;
696
697 /* How much to scroll horizontally when point is inside the above margin. */
698 Lisp_Object Vhscroll_step;
699
700 /* The variable `resize-mini-windows'. If nil, don't resize
701 mini-windows. If t, always resize them to fit the text they
702 display. If `grow-only', let mini-windows grow only until they
703 become empty. */
704
705 Lisp_Object Vresize_mini_windows;
706
707 /* Buffer being redisplayed -- for redisplay_window_error. */
708
709 struct buffer *displayed_buffer;
710
711 /* Space between overline and text. */
712
713 EMACS_INT overline_margin;
714
715 /* Value returned from text property handlers (see below). */
716
717 enum prop_handled
718 {
719 HANDLED_NORMALLY,
720 HANDLED_RECOMPUTE_PROPS,
721 HANDLED_OVERLAY_STRING_CONSUMED,
722 HANDLED_RETURN
723 };
724
725 /* A description of text properties that redisplay is interested
726 in. */
727
728 struct props
729 {
730 /* The name of the property. */
731 Lisp_Object *name;
732
733 /* A unique index for the property. */
734 enum prop_idx idx;
735
736 /* A handler function called to set up iterator IT from the property
737 at IT's current position. Value is used to steer handle_stop. */
738 enum prop_handled (*handler) P_ ((struct it *it));
739 };
740
741 static enum prop_handled handle_face_prop P_ ((struct it *));
742 static enum prop_handled handle_invisible_prop P_ ((struct it *));
743 static enum prop_handled handle_display_prop P_ ((struct it *));
744 static enum prop_handled handle_composition_prop P_ ((struct it *));
745 static enum prop_handled handle_overlay_change P_ ((struct it *));
746 static enum prop_handled handle_fontified_prop P_ ((struct it *));
747
748 /* Properties handled by iterators. */
749
750 static struct props it_props[] =
751 {
752 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
753 /* Handle `face' before `display' because some sub-properties of
754 `display' need to know the face. */
755 {&Qface, FACE_PROP_IDX, handle_face_prop},
756 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
757 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
758 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
759 {NULL, 0, NULL}
760 };
761
762 /* Value is the position described by X. If X is a marker, value is
763 the marker_position of X. Otherwise, value is X. */
764
765 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
766
767 /* Enumeration returned by some move_it_.* functions internally. */
768
769 enum move_it_result
770 {
771 /* Not used. Undefined value. */
772 MOVE_UNDEFINED,
773
774 /* Move ended at the requested buffer position or ZV. */
775 MOVE_POS_MATCH_OR_ZV,
776
777 /* Move ended at the requested X pixel position. */
778 MOVE_X_REACHED,
779
780 /* Move within a line ended at the end of a line that must be
781 continued. */
782 MOVE_LINE_CONTINUED,
783
784 /* Move within a line ended at the end of a line that would
785 be displayed truncated. */
786 MOVE_LINE_TRUNCATED,
787
788 /* Move within a line ended at a line end. */
789 MOVE_NEWLINE_OR_CR
790 };
791
792 /* This counter is used to clear the face cache every once in a while
793 in redisplay_internal. It is incremented for each redisplay.
794 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
795 cleared. */
796
797 #define CLEAR_FACE_CACHE_COUNT 500
798 static int clear_face_cache_count;
799
800 /* Similarly for the image cache. */
801
802 #ifdef HAVE_WINDOW_SYSTEM
803 #define CLEAR_IMAGE_CACHE_COUNT 101
804 static int clear_image_cache_count;
805 #endif
806
807 /* Non-zero while redisplay_internal is in progress. */
808
809 int redisplaying_p;
810
811 /* Non-zero means don't free realized faces. Bound while freeing
812 realized faces is dangerous because glyph matrices might still
813 reference them. */
814
815 int inhibit_free_realized_faces;
816 Lisp_Object Qinhibit_free_realized_faces;
817
818 /* If a string, XTread_socket generates an event to display that string.
819 (The display is done in read_char.) */
820
821 Lisp_Object help_echo_string;
822 Lisp_Object help_echo_window;
823 Lisp_Object help_echo_object;
824 int help_echo_pos;
825
826 /* Temporary variable for XTread_socket. */
827
828 Lisp_Object previous_help_echo_string;
829
830 /* Null glyph slice */
831
832 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
833
834 \f
835 /* Function prototypes. */
836
837 static void setup_for_ellipsis P_ ((struct it *, int));
838 static void mark_window_display_accurate_1 P_ ((struct window *, int));
839 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
840 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
841 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
842 static int redisplay_mode_lines P_ ((Lisp_Object, int));
843 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
844
845 #if 0
846 static int invisible_text_between_p P_ ((struct it *, int, int));
847 #endif
848
849 static void pint2str P_ ((char *, int, int));
850 static void pint2hrstr P_ ((char *, int, int));
851 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
852 struct text_pos));
853 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
854 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
855 static void store_mode_line_noprop_char P_ ((char));
856 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
857 static void x_consider_frame_title P_ ((Lisp_Object));
858 static void handle_stop P_ ((struct it *));
859 static int tool_bar_lines_needed P_ ((struct frame *, int *));
860 static int single_display_spec_intangible_p P_ ((Lisp_Object));
861 static void ensure_echo_area_buffers P_ ((void));
862 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
863 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
864 static int with_echo_area_buffer P_ ((struct window *, int,
865 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
866 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
867 static void clear_garbaged_frames P_ ((void));
868 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
869 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
870 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
871 static int display_echo_area P_ ((struct window *));
872 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
873 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
874 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
875 static int string_char_and_length P_ ((const unsigned char *, int, int *));
876 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
877 struct text_pos));
878 static int compute_window_start_on_continuation_line P_ ((struct window *));
879 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
880 static void insert_left_trunc_glyphs P_ ((struct it *));
881 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
882 Lisp_Object));
883 static void extend_face_to_end_of_line P_ ((struct it *));
884 static int append_space_for_newline P_ ((struct it *, int));
885 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
886 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
887 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
888 static int trailing_whitespace_p P_ ((int));
889 static int message_log_check_duplicate P_ ((int, int, int, int));
890 static void push_it P_ ((struct it *));
891 static void pop_it P_ ((struct it *));
892 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
893 static void select_frame_for_redisplay P_ ((Lisp_Object));
894 static void redisplay_internal P_ ((int));
895 static int echo_area_display P_ ((int));
896 static void redisplay_windows P_ ((Lisp_Object));
897 static void redisplay_window P_ ((Lisp_Object, int));
898 static Lisp_Object redisplay_window_error ();
899 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
900 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
901 static int update_menu_bar P_ ((struct frame *, int, int));
902 static int try_window_reusing_current_matrix P_ ((struct window *));
903 static int try_window_id P_ ((struct window *));
904 static int display_line P_ ((struct it *));
905 static int display_mode_lines P_ ((struct window *));
906 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
907 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
908 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
909 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
910 static void display_menu_bar P_ ((struct window *));
911 static int display_count_lines P_ ((int, int, int, int, int *));
912 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
913 int, int, struct it *, int, int, int, int));
914 static void compute_line_metrics P_ ((struct it *));
915 static void run_redisplay_end_trigger_hook P_ ((struct it *));
916 static int get_overlay_strings P_ ((struct it *, int));
917 static int get_overlay_strings_1 P_ ((struct it *, int, int));
918 static void next_overlay_string P_ ((struct it *));
919 static void reseat P_ ((struct it *, struct text_pos, int));
920 static void reseat_1 P_ ((struct it *, struct text_pos, int));
921 static void back_to_previous_visible_line_start P_ ((struct it *));
922 void reseat_at_previous_visible_line_start P_ ((struct it *));
923 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
924 static int next_element_from_ellipsis P_ ((struct it *));
925 static int next_element_from_display_vector P_ ((struct it *));
926 static int next_element_from_string P_ ((struct it *));
927 static int next_element_from_c_string P_ ((struct it *));
928 static int next_element_from_buffer P_ ((struct it *));
929 static int next_element_from_composition P_ ((struct it *));
930 static int next_element_from_image P_ ((struct it *));
931 static int next_element_from_stretch P_ ((struct it *));
932 static void load_overlay_strings P_ ((struct it *, int));
933 static int init_from_display_pos P_ ((struct it *, struct window *,
934 struct display_pos *));
935 static void reseat_to_string P_ ((struct it *, unsigned char *,
936 Lisp_Object, int, int, int, int));
937 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
938 int, int, int));
939 void move_it_vertically_backward P_ ((struct it *, int));
940 static void init_to_row_start P_ ((struct it *, struct window *,
941 struct glyph_row *));
942 static int init_to_row_end P_ ((struct it *, struct window *,
943 struct glyph_row *));
944 static void back_to_previous_line_start P_ ((struct it *));
945 static int forward_to_next_line_start P_ ((struct it *, int *));
946 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
947 Lisp_Object, int));
948 static struct text_pos string_pos P_ ((int, Lisp_Object));
949 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
950 static int number_of_chars P_ ((unsigned char *, int));
951 static void compute_stop_pos P_ ((struct it *));
952 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
953 Lisp_Object));
954 static int face_before_or_after_it_pos P_ ((struct it *, int));
955 static int next_overlay_change P_ ((int));
956 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
957 Lisp_Object, struct text_pos *,
958 int));
959 static int underlying_face_id P_ ((struct it *));
960 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
961 struct window *));
962
963 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
964 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
965
966 #ifdef HAVE_WINDOW_SYSTEM
967
968 static void update_tool_bar P_ ((struct frame *, int));
969 static void build_desired_tool_bar_string P_ ((struct frame *f));
970 static int redisplay_tool_bar P_ ((struct frame *));
971 static void display_tool_bar_line P_ ((struct it *, int));
972 static void notice_overwritten_cursor P_ ((struct window *,
973 enum glyph_row_area,
974 int, int, int, int));
975
976
977
978 #endif /* HAVE_WINDOW_SYSTEM */
979
980 \f
981 /***********************************************************************
982 Window display dimensions
983 ***********************************************************************/
984
985 /* Return the bottom boundary y-position for text lines in window W.
986 This is the first y position at which a line cannot start.
987 It is relative to the top of the window.
988
989 This is the height of W minus the height of a mode line, if any. */
990
991 INLINE int
992 window_text_bottom_y (w)
993 struct window *w;
994 {
995 int height = WINDOW_TOTAL_HEIGHT (w);
996
997 if (WINDOW_WANTS_MODELINE_P (w))
998 height -= CURRENT_MODE_LINE_HEIGHT (w);
999 return height;
1000 }
1001
1002 /* Return the pixel width of display area AREA of window W. AREA < 0
1003 means return the total width of W, not including fringes to
1004 the left and right of the window. */
1005
1006 INLINE int
1007 window_box_width (w, area)
1008 struct window *w;
1009 int area;
1010 {
1011 int cols = XFASTINT (w->total_cols);
1012 int pixels = 0;
1013
1014 if (!w->pseudo_window_p)
1015 {
1016 cols -= WINDOW_SCROLL_BAR_COLS (w);
1017
1018 if (area == TEXT_AREA)
1019 {
1020 if (INTEGERP (w->left_margin_cols))
1021 cols -= XFASTINT (w->left_margin_cols);
1022 if (INTEGERP (w->right_margin_cols))
1023 cols -= XFASTINT (w->right_margin_cols);
1024 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1025 }
1026 else if (area == LEFT_MARGIN_AREA)
1027 {
1028 cols = (INTEGERP (w->left_margin_cols)
1029 ? XFASTINT (w->left_margin_cols) : 0);
1030 pixels = 0;
1031 }
1032 else if (area == RIGHT_MARGIN_AREA)
1033 {
1034 cols = (INTEGERP (w->right_margin_cols)
1035 ? XFASTINT (w->right_margin_cols) : 0);
1036 pixels = 0;
1037 }
1038 }
1039
1040 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1041 }
1042
1043
1044 /* Return the pixel height of the display area of window W, not
1045 including mode lines of W, if any. */
1046
1047 INLINE int
1048 window_box_height (w)
1049 struct window *w;
1050 {
1051 struct frame *f = XFRAME (w->frame);
1052 int height = WINDOW_TOTAL_HEIGHT (w);
1053
1054 xassert (height >= 0);
1055
1056 /* Note: the code below that determines the mode-line/header-line
1057 height is essentially the same as that contained in the macro
1058 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1059 the appropriate glyph row has its `mode_line_p' flag set,
1060 and if it doesn't, uses estimate_mode_line_height instead. */
1061
1062 if (WINDOW_WANTS_MODELINE_P (w))
1063 {
1064 struct glyph_row *ml_row
1065 = (w->current_matrix && w->current_matrix->rows
1066 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1067 : 0);
1068 if (ml_row && ml_row->mode_line_p)
1069 height -= ml_row->height;
1070 else
1071 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1072 }
1073
1074 if (WINDOW_WANTS_HEADER_LINE_P (w))
1075 {
1076 struct glyph_row *hl_row
1077 = (w->current_matrix && w->current_matrix->rows
1078 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1079 : 0);
1080 if (hl_row && hl_row->mode_line_p)
1081 height -= hl_row->height;
1082 else
1083 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1084 }
1085
1086 /* With a very small font and a mode-line that's taller than
1087 default, we might end up with a negative height. */
1088 return max (0, height);
1089 }
1090
1091 /* Return the window-relative coordinate of the left edge of display
1092 area AREA of window W. AREA < 0 means return the left edge of the
1093 whole window, to the right of the left fringe of W. */
1094
1095 INLINE int
1096 window_box_left_offset (w, area)
1097 struct window *w;
1098 int area;
1099 {
1100 int x;
1101
1102 if (w->pseudo_window_p)
1103 return 0;
1104
1105 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1106
1107 if (area == TEXT_AREA)
1108 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1109 + window_box_width (w, LEFT_MARGIN_AREA));
1110 else if (area == RIGHT_MARGIN_AREA)
1111 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1112 + window_box_width (w, LEFT_MARGIN_AREA)
1113 + window_box_width (w, TEXT_AREA)
1114 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1115 ? 0
1116 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1117 else if (area == LEFT_MARGIN_AREA
1118 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1119 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1120
1121 return x;
1122 }
1123
1124
1125 /* Return the window-relative coordinate of the right edge of display
1126 area AREA of window W. AREA < 0 means return the left edge of the
1127 whole window, to the left of the right fringe of W. */
1128
1129 INLINE int
1130 window_box_right_offset (w, area)
1131 struct window *w;
1132 int area;
1133 {
1134 return window_box_left_offset (w, area) + window_box_width (w, area);
1135 }
1136
1137 /* Return the frame-relative coordinate of the left edge of display
1138 area AREA of window W. AREA < 0 means return the left edge of the
1139 whole window, to the right of the left fringe of W. */
1140
1141 INLINE int
1142 window_box_left (w, area)
1143 struct window *w;
1144 int area;
1145 {
1146 struct frame *f = XFRAME (w->frame);
1147 int x;
1148
1149 if (w->pseudo_window_p)
1150 return FRAME_INTERNAL_BORDER_WIDTH (f);
1151
1152 x = (WINDOW_LEFT_EDGE_X (w)
1153 + window_box_left_offset (w, area));
1154
1155 return x;
1156 }
1157
1158
1159 /* Return the frame-relative coordinate of the right edge of display
1160 area AREA of window W. AREA < 0 means return the left edge of the
1161 whole window, to the left of the right fringe of W. */
1162
1163 INLINE int
1164 window_box_right (w, area)
1165 struct window *w;
1166 int area;
1167 {
1168 return window_box_left (w, area) + window_box_width (w, area);
1169 }
1170
1171 /* Get the bounding box of the display area AREA of window W, without
1172 mode lines, in frame-relative coordinates. AREA < 0 means the
1173 whole window, not including the left and right fringes of
1174 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1175 coordinates of the upper-left corner of the box. Return in
1176 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1177
1178 INLINE void
1179 window_box (w, area, box_x, box_y, box_width, box_height)
1180 struct window *w;
1181 int area;
1182 int *box_x, *box_y, *box_width, *box_height;
1183 {
1184 if (box_width)
1185 *box_width = window_box_width (w, area);
1186 if (box_height)
1187 *box_height = window_box_height (w);
1188 if (box_x)
1189 *box_x = window_box_left (w, area);
1190 if (box_y)
1191 {
1192 *box_y = WINDOW_TOP_EDGE_Y (w);
1193 if (WINDOW_WANTS_HEADER_LINE_P (w))
1194 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1195 }
1196 }
1197
1198
1199 /* Get the bounding box of the display area AREA of window W, without
1200 mode lines. AREA < 0 means the whole window, not including the
1201 left and right fringe of the window. Return in *TOP_LEFT_X
1202 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1203 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1204 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1205 box. */
1206
1207 INLINE void
1208 window_box_edges (w, area, top_left_x, top_left_y,
1209 bottom_right_x, bottom_right_y)
1210 struct window *w;
1211 int area;
1212 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1213 {
1214 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1215 bottom_right_y);
1216 *bottom_right_x += *top_left_x;
1217 *bottom_right_y += *top_left_y;
1218 }
1219
1220
1221 \f
1222 /***********************************************************************
1223 Utilities
1224 ***********************************************************************/
1225
1226 /* Return the bottom y-position of the line the iterator IT is in.
1227 This can modify IT's settings. */
1228
1229 int
1230 line_bottom_y (it)
1231 struct it *it;
1232 {
1233 int line_height = it->max_ascent + it->max_descent;
1234 int line_top_y = it->current_y;
1235
1236 if (line_height == 0)
1237 {
1238 if (last_height)
1239 line_height = last_height;
1240 else if (IT_CHARPOS (*it) < ZV)
1241 {
1242 move_it_by_lines (it, 1, 1);
1243 line_height = (it->max_ascent || it->max_descent
1244 ? it->max_ascent + it->max_descent
1245 : last_height);
1246 }
1247 else
1248 {
1249 struct glyph_row *row = it->glyph_row;
1250
1251 /* Use the default character height. */
1252 it->glyph_row = NULL;
1253 it->what = IT_CHARACTER;
1254 it->c = ' ';
1255 it->len = 1;
1256 PRODUCE_GLYPHS (it);
1257 line_height = it->ascent + it->descent;
1258 it->glyph_row = row;
1259 }
1260 }
1261
1262 return line_top_y + line_height;
1263 }
1264
1265
1266 /* Return 1 if position CHARPOS is visible in window W.
1267 CHARPOS < 0 means return info about WINDOW_END position.
1268 If visible, set *X and *Y to pixel coordinates of top left corner.
1269 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1270 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1271
1272 int
1273 pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
1274 struct window *w;
1275 int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
1276 {
1277 struct it it;
1278 struct text_pos top;
1279 int visible_p = 0;
1280 struct buffer *old_buffer = NULL;
1281
1282 if (noninteractive)
1283 return visible_p;
1284
1285 if (XBUFFER (w->buffer) != current_buffer)
1286 {
1287 old_buffer = current_buffer;
1288 set_buffer_internal_1 (XBUFFER (w->buffer));
1289 }
1290
1291 SET_TEXT_POS_FROM_MARKER (top, w->start);
1292
1293 /* Compute exact mode line heights. */
1294 if (WINDOW_WANTS_MODELINE_P (w))
1295 current_mode_line_height
1296 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1297 current_buffer->mode_line_format);
1298
1299 if (WINDOW_WANTS_HEADER_LINE_P (w))
1300 current_header_line_height
1301 = display_mode_line (w, HEADER_LINE_FACE_ID,
1302 current_buffer->header_line_format);
1303
1304 start_display (&it, w, top);
1305 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1306 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1307
1308 /* Note that we may overshoot because of invisible text. */
1309 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1310 {
1311 int top_x = it.current_x;
1312 int top_y = it.current_y;
1313 int bottom_y = (last_height = 0, line_bottom_y (&it));
1314 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1315
1316 if (top_y < window_top_y)
1317 visible_p = bottom_y > window_top_y;
1318 else if (top_y < it.last_visible_y)
1319 visible_p = 1;
1320 if (visible_p)
1321 {
1322 *x = top_x;
1323 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1324 *rtop = max (0, window_top_y - top_y);
1325 *rbot = max (0, bottom_y - it.last_visible_y);
1326 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1327 - max (top_y, window_top_y)));
1328 *vpos = it.vpos;
1329 }
1330 }
1331 else
1332 {
1333 struct it it2;
1334
1335 it2 = it;
1336 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1337 move_it_by_lines (&it, 1, 0);
1338 if (charpos < IT_CHARPOS (it)
1339 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1340 {
1341 visible_p = 1;
1342 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1343 *x = it2.current_x;
1344 *y = it2.current_y + it2.max_ascent - it2.ascent;
1345 *rtop = max (0, -it2.current_y);
1346 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1347 - it.last_visible_y));
1348 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1349 it.last_visible_y)
1350 - max (it2.current_y,
1351 WINDOW_HEADER_LINE_HEIGHT (w))));
1352 *vpos = it2.vpos;
1353 }
1354 }
1355
1356 if (old_buffer)
1357 set_buffer_internal_1 (old_buffer);
1358
1359 current_header_line_height = current_mode_line_height = -1;
1360
1361 if (visible_p && XFASTINT (w->hscroll) > 0)
1362 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1363
1364 #if 0
1365 /* Debugging code. */
1366 if (visible_p)
1367 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1368 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1369 else
1370 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1371 #endif
1372
1373 return visible_p;
1374 }
1375
1376
1377 /* Return the next character from STR which is MAXLEN bytes long.
1378 Return in *LEN the length of the character. This is like
1379 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1380 we find one, we return a `?', but with the length of the invalid
1381 character. */
1382
1383 static INLINE int
1384 string_char_and_length (str, maxlen, len)
1385 const unsigned char *str;
1386 int maxlen, *len;
1387 {
1388 int c;
1389
1390 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1391 if (!CHAR_VALID_P (c, 1))
1392 /* We may not change the length here because other places in Emacs
1393 don't use this function, i.e. they silently accept invalid
1394 characters. */
1395 c = '?';
1396
1397 return c;
1398 }
1399
1400
1401
1402 /* Given a position POS containing a valid character and byte position
1403 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1404
1405 static struct text_pos
1406 string_pos_nchars_ahead (pos, string, nchars)
1407 struct text_pos pos;
1408 Lisp_Object string;
1409 int nchars;
1410 {
1411 xassert (STRINGP (string) && nchars >= 0);
1412
1413 if (STRING_MULTIBYTE (string))
1414 {
1415 int rest = SBYTES (string) - BYTEPOS (pos);
1416 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1417 int len;
1418
1419 while (nchars--)
1420 {
1421 string_char_and_length (p, rest, &len);
1422 p += len, rest -= len;
1423 xassert (rest >= 0);
1424 CHARPOS (pos) += 1;
1425 BYTEPOS (pos) += len;
1426 }
1427 }
1428 else
1429 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1430
1431 return pos;
1432 }
1433
1434
1435 /* Value is the text position, i.e. character and byte position,
1436 for character position CHARPOS in STRING. */
1437
1438 static INLINE struct text_pos
1439 string_pos (charpos, string)
1440 int charpos;
1441 Lisp_Object string;
1442 {
1443 struct text_pos pos;
1444 xassert (STRINGP (string));
1445 xassert (charpos >= 0);
1446 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1447 return pos;
1448 }
1449
1450
1451 /* Value is a text position, i.e. character and byte position, for
1452 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1453 means recognize multibyte characters. */
1454
1455 static struct text_pos
1456 c_string_pos (charpos, s, multibyte_p)
1457 int charpos;
1458 unsigned char *s;
1459 int multibyte_p;
1460 {
1461 struct text_pos pos;
1462
1463 xassert (s != NULL);
1464 xassert (charpos >= 0);
1465
1466 if (multibyte_p)
1467 {
1468 int rest = strlen (s), len;
1469
1470 SET_TEXT_POS (pos, 0, 0);
1471 while (charpos--)
1472 {
1473 string_char_and_length (s, rest, &len);
1474 s += len, rest -= len;
1475 xassert (rest >= 0);
1476 CHARPOS (pos) += 1;
1477 BYTEPOS (pos) += len;
1478 }
1479 }
1480 else
1481 SET_TEXT_POS (pos, charpos, charpos);
1482
1483 return pos;
1484 }
1485
1486
1487 /* Value is the number of characters in C string S. MULTIBYTE_P
1488 non-zero means recognize multibyte characters. */
1489
1490 static int
1491 number_of_chars (s, multibyte_p)
1492 unsigned char *s;
1493 int multibyte_p;
1494 {
1495 int nchars;
1496
1497 if (multibyte_p)
1498 {
1499 int rest = strlen (s), len;
1500 unsigned char *p = (unsigned char *) s;
1501
1502 for (nchars = 0; rest > 0; ++nchars)
1503 {
1504 string_char_and_length (p, rest, &len);
1505 rest -= len, p += len;
1506 }
1507 }
1508 else
1509 nchars = strlen (s);
1510
1511 return nchars;
1512 }
1513
1514
1515 /* Compute byte position NEWPOS->bytepos corresponding to
1516 NEWPOS->charpos. POS is a known position in string STRING.
1517 NEWPOS->charpos must be >= POS.charpos. */
1518
1519 static void
1520 compute_string_pos (newpos, pos, string)
1521 struct text_pos *newpos, pos;
1522 Lisp_Object string;
1523 {
1524 xassert (STRINGP (string));
1525 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1526
1527 if (STRING_MULTIBYTE (string))
1528 *newpos = string_pos_nchars_ahead (pos, string,
1529 CHARPOS (*newpos) - CHARPOS (pos));
1530 else
1531 BYTEPOS (*newpos) = CHARPOS (*newpos);
1532 }
1533
1534 /* EXPORT:
1535 Return an estimation of the pixel height of mode or top lines on
1536 frame F. FACE_ID specifies what line's height to estimate. */
1537
1538 int
1539 estimate_mode_line_height (f, face_id)
1540 struct frame *f;
1541 enum face_id face_id;
1542 {
1543 #ifdef HAVE_WINDOW_SYSTEM
1544 if (FRAME_WINDOW_P (f))
1545 {
1546 int height = FONT_HEIGHT (FRAME_FONT (f));
1547
1548 /* This function is called so early when Emacs starts that the face
1549 cache and mode line face are not yet initialized. */
1550 if (FRAME_FACE_CACHE (f))
1551 {
1552 struct face *face = FACE_FROM_ID (f, face_id);
1553 if (face)
1554 {
1555 if (face->font)
1556 height = FONT_HEIGHT (face->font);
1557 if (face->box_line_width > 0)
1558 height += 2 * face->box_line_width;
1559 }
1560 }
1561
1562 return height;
1563 }
1564 #endif
1565
1566 return 1;
1567 }
1568
1569 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1570 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1571 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1572 not force the value into range. */
1573
1574 void
1575 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1576 FRAME_PTR f;
1577 register int pix_x, pix_y;
1578 int *x, *y;
1579 NativeRectangle *bounds;
1580 int noclip;
1581 {
1582
1583 #ifdef HAVE_WINDOW_SYSTEM
1584 if (FRAME_WINDOW_P (f))
1585 {
1586 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1587 even for negative values. */
1588 if (pix_x < 0)
1589 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1590 if (pix_y < 0)
1591 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1592
1593 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1594 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1595
1596 if (bounds)
1597 STORE_NATIVE_RECT (*bounds,
1598 FRAME_COL_TO_PIXEL_X (f, pix_x),
1599 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1600 FRAME_COLUMN_WIDTH (f) - 1,
1601 FRAME_LINE_HEIGHT (f) - 1);
1602
1603 if (!noclip)
1604 {
1605 if (pix_x < 0)
1606 pix_x = 0;
1607 else if (pix_x > FRAME_TOTAL_COLS (f))
1608 pix_x = FRAME_TOTAL_COLS (f);
1609
1610 if (pix_y < 0)
1611 pix_y = 0;
1612 else if (pix_y > FRAME_LINES (f))
1613 pix_y = FRAME_LINES (f);
1614 }
1615 }
1616 #endif
1617
1618 *x = pix_x;
1619 *y = pix_y;
1620 }
1621
1622
1623 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1624 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1625 can't tell the positions because W's display is not up to date,
1626 return 0. */
1627
1628 int
1629 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1630 struct window *w;
1631 int hpos, vpos;
1632 int *frame_x, *frame_y;
1633 {
1634 #ifdef HAVE_WINDOW_SYSTEM
1635 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1636 {
1637 int success_p;
1638
1639 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1640 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1641
1642 if (display_completed)
1643 {
1644 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1645 struct glyph *glyph = row->glyphs[TEXT_AREA];
1646 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1647
1648 hpos = row->x;
1649 vpos = row->y;
1650 while (glyph < end)
1651 {
1652 hpos += glyph->pixel_width;
1653 ++glyph;
1654 }
1655
1656 /* If first glyph is partially visible, its first visible position is still 0. */
1657 if (hpos < 0)
1658 hpos = 0;
1659
1660 success_p = 1;
1661 }
1662 else
1663 {
1664 hpos = vpos = 0;
1665 success_p = 0;
1666 }
1667
1668 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1669 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1670 return success_p;
1671 }
1672 #endif
1673
1674 *frame_x = hpos;
1675 *frame_y = vpos;
1676 return 1;
1677 }
1678
1679
1680 #ifdef HAVE_WINDOW_SYSTEM
1681
1682 /* Find the glyph under window-relative coordinates X/Y in window W.
1683 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1684 strings. Return in *HPOS and *VPOS the row and column number of
1685 the glyph found. Return in *AREA the glyph area containing X.
1686 Value is a pointer to the glyph found or null if X/Y is not on
1687 text, or we can't tell because W's current matrix is not up to
1688 date. */
1689
1690 static struct glyph *
1691 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1692 struct window *w;
1693 int x, y;
1694 int *hpos, *vpos, *dx, *dy, *area;
1695 {
1696 struct glyph *glyph, *end;
1697 struct glyph_row *row = NULL;
1698 int x0, i;
1699
1700 /* Find row containing Y. Give up if some row is not enabled. */
1701 for (i = 0; i < w->current_matrix->nrows; ++i)
1702 {
1703 row = MATRIX_ROW (w->current_matrix, i);
1704 if (!row->enabled_p)
1705 return NULL;
1706 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1707 break;
1708 }
1709
1710 *vpos = i;
1711 *hpos = 0;
1712
1713 /* Give up if Y is not in the window. */
1714 if (i == w->current_matrix->nrows)
1715 return NULL;
1716
1717 /* Get the glyph area containing X. */
1718 if (w->pseudo_window_p)
1719 {
1720 *area = TEXT_AREA;
1721 x0 = 0;
1722 }
1723 else
1724 {
1725 if (x < window_box_left_offset (w, TEXT_AREA))
1726 {
1727 *area = LEFT_MARGIN_AREA;
1728 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1729 }
1730 else if (x < window_box_right_offset (w, TEXT_AREA))
1731 {
1732 *area = TEXT_AREA;
1733 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1734 }
1735 else
1736 {
1737 *area = RIGHT_MARGIN_AREA;
1738 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1739 }
1740 }
1741
1742 /* Find glyph containing X. */
1743 glyph = row->glyphs[*area];
1744 end = glyph + row->used[*area];
1745 x -= x0;
1746 while (glyph < end && x >= glyph->pixel_width)
1747 {
1748 x -= glyph->pixel_width;
1749 ++glyph;
1750 }
1751
1752 if (glyph == end)
1753 return NULL;
1754
1755 if (dx)
1756 {
1757 *dx = x;
1758 *dy = y - (row->y + row->ascent - glyph->ascent);
1759 }
1760
1761 *hpos = glyph - row->glyphs[*area];
1762 return glyph;
1763 }
1764
1765
1766 /* EXPORT:
1767 Convert frame-relative x/y to coordinates relative to window W.
1768 Takes pseudo-windows into account. */
1769
1770 void
1771 frame_to_window_pixel_xy (w, x, y)
1772 struct window *w;
1773 int *x, *y;
1774 {
1775 if (w->pseudo_window_p)
1776 {
1777 /* A pseudo-window is always full-width, and starts at the
1778 left edge of the frame, plus a frame border. */
1779 struct frame *f = XFRAME (w->frame);
1780 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1781 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1782 }
1783 else
1784 {
1785 *x -= WINDOW_LEFT_EDGE_X (w);
1786 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1787 }
1788 }
1789
1790 /* EXPORT:
1791 Return in RECTS[] at most N clipping rectangles for glyph string S.
1792 Return the number of stored rectangles. */
1793
1794 int
1795 get_glyph_string_clip_rects (s, rects, n)
1796 struct glyph_string *s;
1797 NativeRectangle *rects;
1798 int n;
1799 {
1800 XRectangle r;
1801
1802 if (n <= 0)
1803 return 0;
1804
1805 if (s->row->full_width_p)
1806 {
1807 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1808 r.x = WINDOW_LEFT_EDGE_X (s->w);
1809 r.width = WINDOW_TOTAL_WIDTH (s->w);
1810
1811 /* Unless displaying a mode or menu bar line, which are always
1812 fully visible, clip to the visible part of the row. */
1813 if (s->w->pseudo_window_p)
1814 r.height = s->row->visible_height;
1815 else
1816 r.height = s->height;
1817 }
1818 else
1819 {
1820 /* This is a text line that may be partially visible. */
1821 r.x = window_box_left (s->w, s->area);
1822 r.width = window_box_width (s->w, s->area);
1823 r.height = s->row->visible_height;
1824 }
1825
1826 if (s->clip_head)
1827 if (r.x < s->clip_head->x)
1828 {
1829 if (r.width >= s->clip_head->x - r.x)
1830 r.width -= s->clip_head->x - r.x;
1831 else
1832 r.width = 0;
1833 r.x = s->clip_head->x;
1834 }
1835 if (s->clip_tail)
1836 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1837 {
1838 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1839 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1840 else
1841 r.width = 0;
1842 }
1843
1844 /* If S draws overlapping rows, it's sufficient to use the top and
1845 bottom of the window for clipping because this glyph string
1846 intentionally draws over other lines. */
1847 if (s->for_overlaps)
1848 {
1849 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1850 r.height = window_text_bottom_y (s->w) - r.y;
1851
1852 /* Alas, the above simple strategy does not work for the
1853 environments with anti-aliased text: if the same text is
1854 drawn onto the same place multiple times, it gets thicker.
1855 If the overlap we are processing is for the erased cursor, we
1856 take the intersection with the rectagle of the cursor. */
1857 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1858 {
1859 XRectangle rc, r_save = r;
1860
1861 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1862 rc.y = s->w->phys_cursor.y;
1863 rc.width = s->w->phys_cursor_width;
1864 rc.height = s->w->phys_cursor_height;
1865
1866 x_intersect_rectangles (&r_save, &rc, &r);
1867 }
1868 }
1869 else
1870 {
1871 /* Don't use S->y for clipping because it doesn't take partially
1872 visible lines into account. For example, it can be negative for
1873 partially visible lines at the top of a window. */
1874 if (!s->row->full_width_p
1875 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1876 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1877 else
1878 r.y = max (0, s->row->y);
1879
1880 /* If drawing a tool-bar window, draw it over the internal border
1881 at the top of the window. */
1882 if (WINDOWP (s->f->tool_bar_window)
1883 && s->w == XWINDOW (s->f->tool_bar_window))
1884 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1885 }
1886
1887 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1888
1889 /* If drawing the cursor, don't let glyph draw outside its
1890 advertised boundaries. Cleartype does this under some circumstances. */
1891 if (s->hl == DRAW_CURSOR)
1892 {
1893 struct glyph *glyph = s->first_glyph;
1894 int height, max_y;
1895
1896 if (s->x > r.x)
1897 {
1898 r.width -= s->x - r.x;
1899 r.x = s->x;
1900 }
1901 r.width = min (r.width, glyph->pixel_width);
1902
1903 /* If r.y is below window bottom, ensure that we still see a cursor. */
1904 height = min (glyph->ascent + glyph->descent,
1905 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1906 max_y = window_text_bottom_y (s->w) - height;
1907 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1908 if (s->ybase - glyph->ascent > max_y)
1909 {
1910 r.y = max_y;
1911 r.height = height;
1912 }
1913 else
1914 {
1915 /* Don't draw cursor glyph taller than our actual glyph. */
1916 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1917 if (height < r.height)
1918 {
1919 max_y = r.y + r.height;
1920 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1921 r.height = min (max_y - r.y, height);
1922 }
1923 }
1924 }
1925
1926 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1927 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1928 {
1929 #ifdef CONVERT_FROM_XRECT
1930 CONVERT_FROM_XRECT (r, *rects);
1931 #else
1932 *rects = r;
1933 #endif
1934 return 1;
1935 }
1936 else
1937 {
1938 /* If we are processing overlapping and allowed to return
1939 multiple clipping rectangles, we exclude the row of the glyph
1940 string from the clipping rectangle. This is to avoid drawing
1941 the same text on the environment with anti-aliasing. */
1942 #ifdef CONVERT_FROM_XRECT
1943 XRectangle rs[2];
1944 #else
1945 XRectangle *rs = rects;
1946 #endif
1947 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1948
1949 if (s->for_overlaps & OVERLAPS_PRED)
1950 {
1951 rs[i] = r;
1952 if (r.y + r.height > row_y)
1953 {
1954 if (r.y < row_y)
1955 rs[i].height = row_y - r.y;
1956 else
1957 rs[i].height = 0;
1958 }
1959 i++;
1960 }
1961 if (s->for_overlaps & OVERLAPS_SUCC)
1962 {
1963 rs[i] = r;
1964 if (r.y < row_y + s->row->visible_height)
1965 {
1966 if (r.y + r.height > row_y + s->row->visible_height)
1967 {
1968 rs[i].y = row_y + s->row->visible_height;
1969 rs[i].height = r.y + r.height - rs[i].y;
1970 }
1971 else
1972 rs[i].height = 0;
1973 }
1974 i++;
1975 }
1976
1977 n = i;
1978 #ifdef CONVERT_FROM_XRECT
1979 for (i = 0; i < n; i++)
1980 CONVERT_FROM_XRECT (rs[i], rects[i]);
1981 #endif
1982 return n;
1983 }
1984 }
1985
1986 /* EXPORT:
1987 Return in *NR the clipping rectangle for glyph string S. */
1988
1989 void
1990 get_glyph_string_clip_rect (s, nr)
1991 struct glyph_string *s;
1992 NativeRectangle *nr;
1993 {
1994 get_glyph_string_clip_rects (s, nr, 1);
1995 }
1996
1997
1998 /* EXPORT:
1999 Return the position and height of the phys cursor in window W.
2000 Set w->phys_cursor_width to width of phys cursor.
2001 */
2002
2003 void
2004 get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
2005 struct window *w;
2006 struct glyph_row *row;
2007 struct glyph *glyph;
2008 int *xp, *yp, *heightp;
2009 {
2010 struct frame *f = XFRAME (WINDOW_FRAME (w));
2011 int x, y, wd, h, h0, y0;
2012
2013 /* Compute the width of the rectangle to draw. If on a stretch
2014 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2015 rectangle as wide as the glyph, but use a canonical character
2016 width instead. */
2017 wd = glyph->pixel_width - 1;
2018 #ifdef HAVE_NTGUI
2019 wd++; /* Why? */
2020 #endif
2021
2022 x = w->phys_cursor.x;
2023 if (x < 0)
2024 {
2025 wd += x;
2026 x = 0;
2027 }
2028
2029 if (glyph->type == STRETCH_GLYPH
2030 && !x_stretch_cursor_p)
2031 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2032 w->phys_cursor_width = wd;
2033
2034 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2035
2036 /* If y is below window bottom, ensure that we still see a cursor. */
2037 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2038
2039 h = max (h0, glyph->ascent + glyph->descent);
2040 h0 = min (h0, glyph->ascent + glyph->descent);
2041
2042 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2043 if (y < y0)
2044 {
2045 h = max (h - (y0 - y) + 1, h0);
2046 y = y0 - 1;
2047 }
2048 else
2049 {
2050 y0 = window_text_bottom_y (w) - h0;
2051 if (y > y0)
2052 {
2053 h += y - y0;
2054 y = y0;
2055 }
2056 }
2057
2058 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2059 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2060 *heightp = h;
2061 }
2062
2063 /*
2064 * Remember which glyph the mouse is over.
2065 */
2066
2067 void
2068 remember_mouse_glyph (f, gx, gy, rect)
2069 struct frame *f;
2070 int gx, gy;
2071 NativeRectangle *rect;
2072 {
2073 Lisp_Object window;
2074 struct window *w;
2075 struct glyph_row *r, *gr, *end_row;
2076 enum window_part part;
2077 enum glyph_row_area area;
2078 int x, y, width, height;
2079
2080 /* Try to determine frame pixel position and size of the glyph under
2081 frame pixel coordinates X/Y on frame F. */
2082
2083 if (!f->glyphs_initialized_p
2084 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2085 NILP (window)))
2086 {
2087 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2088 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2089 goto virtual_glyph;
2090 }
2091
2092 w = XWINDOW (window);
2093 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2094 height = WINDOW_FRAME_LINE_HEIGHT (w);
2095
2096 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2097 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2098
2099 if (w->pseudo_window_p)
2100 {
2101 area = TEXT_AREA;
2102 part = ON_MODE_LINE; /* Don't adjust margin. */
2103 goto text_glyph;
2104 }
2105
2106 switch (part)
2107 {
2108 case ON_LEFT_MARGIN:
2109 area = LEFT_MARGIN_AREA;
2110 goto text_glyph;
2111
2112 case ON_RIGHT_MARGIN:
2113 area = RIGHT_MARGIN_AREA;
2114 goto text_glyph;
2115
2116 case ON_HEADER_LINE:
2117 case ON_MODE_LINE:
2118 gr = (part == ON_HEADER_LINE
2119 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2120 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2121 gy = gr->y;
2122 area = TEXT_AREA;
2123 goto text_glyph_row_found;
2124
2125 case ON_TEXT:
2126 area = TEXT_AREA;
2127
2128 text_glyph:
2129 gr = 0; gy = 0;
2130 for (; r <= end_row && r->enabled_p; ++r)
2131 if (r->y + r->height > y)
2132 {
2133 gr = r; gy = r->y;
2134 break;
2135 }
2136
2137 text_glyph_row_found:
2138 if (gr && gy <= y)
2139 {
2140 struct glyph *g = gr->glyphs[area];
2141 struct glyph *end = g + gr->used[area];
2142
2143 height = gr->height;
2144 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2145 if (gx + g->pixel_width > x)
2146 break;
2147
2148 if (g < end)
2149 {
2150 if (g->type == IMAGE_GLYPH)
2151 {
2152 /* Don't remember when mouse is over image, as
2153 image may have hot-spots. */
2154 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2155 return;
2156 }
2157 width = g->pixel_width;
2158 }
2159 else
2160 {
2161 /* Use nominal char spacing at end of line. */
2162 x -= gx;
2163 gx += (x / width) * width;
2164 }
2165
2166 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2167 gx += window_box_left_offset (w, area);
2168 }
2169 else
2170 {
2171 /* Use nominal line height at end of window. */
2172 gx = (x / width) * width;
2173 y -= gy;
2174 gy += (y / height) * height;
2175 }
2176 break;
2177
2178 case ON_LEFT_FRINGE:
2179 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2180 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2181 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2182 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2183 goto row_glyph;
2184
2185 case ON_RIGHT_FRINGE:
2186 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2187 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2188 : window_box_right_offset (w, TEXT_AREA));
2189 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2190 goto row_glyph;
2191
2192 case ON_SCROLL_BAR:
2193 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2194 ? 0
2195 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2196 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2197 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2198 : 0)));
2199 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2200
2201 row_glyph:
2202 gr = 0, gy = 0;
2203 for (; r <= end_row && r->enabled_p; ++r)
2204 if (r->y + r->height > y)
2205 {
2206 gr = r; gy = r->y;
2207 break;
2208 }
2209
2210 if (gr && gy <= y)
2211 height = gr->height;
2212 else
2213 {
2214 /* Use nominal line height at end of window. */
2215 y -= gy;
2216 gy += (y / height) * height;
2217 }
2218 break;
2219
2220 default:
2221 ;
2222 virtual_glyph:
2223 /* If there is no glyph under the mouse, then we divide the screen
2224 into a grid of the smallest glyph in the frame, and use that
2225 as our "glyph". */
2226
2227 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2228 round down even for negative values. */
2229 if (gx < 0)
2230 gx -= width - 1;
2231 if (gy < 0)
2232 gy -= height - 1;
2233
2234 gx = (gx / width) * width;
2235 gy = (gy / height) * height;
2236
2237 goto store_rect;
2238 }
2239
2240 gx += WINDOW_LEFT_EDGE_X (w);
2241 gy += WINDOW_TOP_EDGE_Y (w);
2242
2243 store_rect:
2244 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2245
2246 /* Visible feedback for debugging. */
2247 #if 0
2248 #if HAVE_X_WINDOWS
2249 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2250 f->output_data.x->normal_gc,
2251 gx, gy, width, height);
2252 #endif
2253 #endif
2254 }
2255
2256
2257 #endif /* HAVE_WINDOW_SYSTEM */
2258
2259 \f
2260 /***********************************************************************
2261 Lisp form evaluation
2262 ***********************************************************************/
2263
2264 /* Error handler for safe_eval and safe_call. */
2265
2266 static Lisp_Object
2267 safe_eval_handler (arg)
2268 Lisp_Object arg;
2269 {
2270 add_to_log ("Error during redisplay: %s", arg, Qnil);
2271 return Qnil;
2272 }
2273
2274
2275 /* Evaluate SEXPR and return the result, or nil if something went
2276 wrong. Prevent redisplay during the evaluation. */
2277
2278 Lisp_Object
2279 safe_eval (sexpr)
2280 Lisp_Object sexpr;
2281 {
2282 Lisp_Object val;
2283
2284 if (inhibit_eval_during_redisplay)
2285 val = Qnil;
2286 else
2287 {
2288 int count = SPECPDL_INDEX ();
2289 struct gcpro gcpro1;
2290
2291 GCPRO1 (sexpr);
2292 specbind (Qinhibit_redisplay, Qt);
2293 /* Use Qt to ensure debugger does not run,
2294 so there is no possibility of wanting to redisplay. */
2295 val = internal_condition_case_1 (Feval, sexpr, Qt,
2296 safe_eval_handler);
2297 UNGCPRO;
2298 val = unbind_to (count, val);
2299 }
2300
2301 return val;
2302 }
2303
2304
2305 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2306 Return the result, or nil if something went wrong. Prevent
2307 redisplay during the evaluation. */
2308
2309 Lisp_Object
2310 safe_call (nargs, args)
2311 int nargs;
2312 Lisp_Object *args;
2313 {
2314 Lisp_Object val;
2315
2316 if (inhibit_eval_during_redisplay)
2317 val = Qnil;
2318 else
2319 {
2320 int count = SPECPDL_INDEX ();
2321 struct gcpro gcpro1;
2322
2323 GCPRO1 (args[0]);
2324 gcpro1.nvars = nargs;
2325 specbind (Qinhibit_redisplay, Qt);
2326 /* Use Qt to ensure debugger does not run,
2327 so there is no possibility of wanting to redisplay. */
2328 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2329 safe_eval_handler);
2330 UNGCPRO;
2331 val = unbind_to (count, val);
2332 }
2333
2334 return val;
2335 }
2336
2337
2338 /* Call function FN with one argument ARG.
2339 Return the result, or nil if something went wrong. */
2340
2341 Lisp_Object
2342 safe_call1 (fn, arg)
2343 Lisp_Object fn, arg;
2344 {
2345 Lisp_Object args[2];
2346 args[0] = fn;
2347 args[1] = arg;
2348 return safe_call (2, args);
2349 }
2350
2351
2352 \f
2353 /***********************************************************************
2354 Debugging
2355 ***********************************************************************/
2356
2357 #if 0
2358
2359 /* Define CHECK_IT to perform sanity checks on iterators.
2360 This is for debugging. It is too slow to do unconditionally. */
2361
2362 static void
2363 check_it (it)
2364 struct it *it;
2365 {
2366 if (it->method == GET_FROM_STRING)
2367 {
2368 xassert (STRINGP (it->string));
2369 xassert (IT_STRING_CHARPOS (*it) >= 0);
2370 }
2371 else
2372 {
2373 xassert (IT_STRING_CHARPOS (*it) < 0);
2374 if (it->method == GET_FROM_BUFFER)
2375 {
2376 /* Check that character and byte positions agree. */
2377 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2378 }
2379 }
2380
2381 if (it->dpvec)
2382 xassert (it->current.dpvec_index >= 0);
2383 else
2384 xassert (it->current.dpvec_index < 0);
2385 }
2386
2387 #define CHECK_IT(IT) check_it ((IT))
2388
2389 #else /* not 0 */
2390
2391 #define CHECK_IT(IT) (void) 0
2392
2393 #endif /* not 0 */
2394
2395
2396 #if GLYPH_DEBUG
2397
2398 /* Check that the window end of window W is what we expect it
2399 to be---the last row in the current matrix displaying text. */
2400
2401 static void
2402 check_window_end (w)
2403 struct window *w;
2404 {
2405 if (!MINI_WINDOW_P (w)
2406 && !NILP (w->window_end_valid))
2407 {
2408 struct glyph_row *row;
2409 xassert ((row = MATRIX_ROW (w->current_matrix,
2410 XFASTINT (w->window_end_vpos)),
2411 !row->enabled_p
2412 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2413 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2414 }
2415 }
2416
2417 #define CHECK_WINDOW_END(W) check_window_end ((W))
2418
2419 #else /* not GLYPH_DEBUG */
2420
2421 #define CHECK_WINDOW_END(W) (void) 0
2422
2423 #endif /* not GLYPH_DEBUG */
2424
2425
2426 \f
2427 /***********************************************************************
2428 Iterator initialization
2429 ***********************************************************************/
2430
2431 /* Initialize IT for displaying current_buffer in window W, starting
2432 at character position CHARPOS. CHARPOS < 0 means that no buffer
2433 position is specified which is useful when the iterator is assigned
2434 a position later. BYTEPOS is the byte position corresponding to
2435 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2436
2437 If ROW is not null, calls to produce_glyphs with IT as parameter
2438 will produce glyphs in that row.
2439
2440 BASE_FACE_ID is the id of a base face to use. It must be one of
2441 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2442 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2443 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2444
2445 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2446 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2447 will be initialized to use the corresponding mode line glyph row of
2448 the desired matrix of W. */
2449
2450 void
2451 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2452 struct it *it;
2453 struct window *w;
2454 int charpos, bytepos;
2455 struct glyph_row *row;
2456 enum face_id base_face_id;
2457 {
2458 int highlight_region_p;
2459
2460 /* Some precondition checks. */
2461 xassert (w != NULL && it != NULL);
2462 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2463 && charpos <= ZV));
2464
2465 /* If face attributes have been changed since the last redisplay,
2466 free realized faces now because they depend on face definitions
2467 that might have changed. Don't free faces while there might be
2468 desired matrices pending which reference these faces. */
2469 if (face_change_count && !inhibit_free_realized_faces)
2470 {
2471 face_change_count = 0;
2472 free_all_realized_faces (Qnil);
2473 }
2474
2475 /* Use one of the mode line rows of W's desired matrix if
2476 appropriate. */
2477 if (row == NULL)
2478 {
2479 if (base_face_id == MODE_LINE_FACE_ID
2480 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2481 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2482 else if (base_face_id == HEADER_LINE_FACE_ID)
2483 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2484 }
2485
2486 /* Clear IT. */
2487 bzero (it, sizeof *it);
2488 it->current.overlay_string_index = -1;
2489 it->current.dpvec_index = -1;
2490 it->base_face_id = base_face_id;
2491 it->string = Qnil;
2492 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2493
2494 /* The window in which we iterate over current_buffer: */
2495 XSETWINDOW (it->window, w);
2496 it->w = w;
2497 it->f = XFRAME (w->frame);
2498
2499 /* Extra space between lines (on window systems only). */
2500 if (base_face_id == DEFAULT_FACE_ID
2501 && FRAME_WINDOW_P (it->f))
2502 {
2503 if (NATNUMP (current_buffer->extra_line_spacing))
2504 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2505 else if (FLOATP (current_buffer->extra_line_spacing))
2506 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2507 * FRAME_LINE_HEIGHT (it->f));
2508 else if (it->f->extra_line_spacing > 0)
2509 it->extra_line_spacing = it->f->extra_line_spacing;
2510 it->max_extra_line_spacing = 0;
2511 }
2512
2513 /* If realized faces have been removed, e.g. because of face
2514 attribute changes of named faces, recompute them. When running
2515 in batch mode, the face cache of the initial frame is null. If
2516 we happen to get called, make a dummy face cache. */
2517 if (FRAME_FACE_CACHE (it->f) == NULL)
2518 init_frame_faces (it->f);
2519 if (FRAME_FACE_CACHE (it->f)->used == 0)
2520 recompute_basic_faces (it->f);
2521
2522 /* Current value of the `slice', `space-width', and 'height' properties. */
2523 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2524 it->space_width = Qnil;
2525 it->font_height = Qnil;
2526 it->override_ascent = -1;
2527
2528 /* Are control characters displayed as `^C'? */
2529 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2530
2531 /* -1 means everything between a CR and the following line end
2532 is invisible. >0 means lines indented more than this value are
2533 invisible. */
2534 it->selective = (INTEGERP (current_buffer->selective_display)
2535 ? XFASTINT (current_buffer->selective_display)
2536 : (!NILP (current_buffer->selective_display)
2537 ? -1 : 0));
2538 it->selective_display_ellipsis_p
2539 = !NILP (current_buffer->selective_display_ellipses);
2540
2541 /* Display table to use. */
2542 it->dp = window_display_table (w);
2543
2544 /* Are multibyte characters enabled in current_buffer? */
2545 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2546
2547 /* Non-zero if we should highlight the region. */
2548 highlight_region_p
2549 = (!NILP (Vtransient_mark_mode)
2550 && !NILP (current_buffer->mark_active)
2551 && XMARKER (current_buffer->mark)->buffer != 0);
2552
2553 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2554 start and end of a visible region in window IT->w. Set both to
2555 -1 to indicate no region. */
2556 if (highlight_region_p
2557 /* Maybe highlight only in selected window. */
2558 && (/* Either show region everywhere. */
2559 highlight_nonselected_windows
2560 /* Or show region in the selected window. */
2561 || w == XWINDOW (selected_window)
2562 /* Or show the region if we are in the mini-buffer and W is
2563 the window the mini-buffer refers to. */
2564 || (MINI_WINDOW_P (XWINDOW (selected_window))
2565 && WINDOWP (minibuf_selected_window)
2566 && w == XWINDOW (minibuf_selected_window))))
2567 {
2568 int charpos = marker_position (current_buffer->mark);
2569 it->region_beg_charpos = min (PT, charpos);
2570 it->region_end_charpos = max (PT, charpos);
2571 }
2572 else
2573 it->region_beg_charpos = it->region_end_charpos = -1;
2574
2575 /* Get the position at which the redisplay_end_trigger hook should
2576 be run, if it is to be run at all. */
2577 if (MARKERP (w->redisplay_end_trigger)
2578 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2579 it->redisplay_end_trigger_charpos
2580 = marker_position (w->redisplay_end_trigger);
2581 else if (INTEGERP (w->redisplay_end_trigger))
2582 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2583
2584 /* Correct bogus values of tab_width. */
2585 it->tab_width = XINT (current_buffer->tab_width);
2586 if (it->tab_width <= 0 || it->tab_width > 1000)
2587 it->tab_width = 8;
2588
2589 /* Are lines in the display truncated? */
2590 it->truncate_lines_p
2591 = (base_face_id != DEFAULT_FACE_ID
2592 || XINT (it->w->hscroll)
2593 || (truncate_partial_width_windows
2594 && !WINDOW_FULL_WIDTH_P (it->w))
2595 || !NILP (current_buffer->truncate_lines));
2596
2597 /* Get dimensions of truncation and continuation glyphs. These are
2598 displayed as fringe bitmaps under X, so we don't need them for such
2599 frames. */
2600 if (!FRAME_WINDOW_P (it->f))
2601 {
2602 if (it->truncate_lines_p)
2603 {
2604 /* We will need the truncation glyph. */
2605 xassert (it->glyph_row == NULL);
2606 produce_special_glyphs (it, IT_TRUNCATION);
2607 it->truncation_pixel_width = it->pixel_width;
2608 }
2609 else
2610 {
2611 /* We will need the continuation glyph. */
2612 xassert (it->glyph_row == NULL);
2613 produce_special_glyphs (it, IT_CONTINUATION);
2614 it->continuation_pixel_width = it->pixel_width;
2615 }
2616
2617 /* Reset these values to zero because the produce_special_glyphs
2618 above has changed them. */
2619 it->pixel_width = it->ascent = it->descent = 0;
2620 it->phys_ascent = it->phys_descent = 0;
2621 }
2622
2623 /* Set this after getting the dimensions of truncation and
2624 continuation glyphs, so that we don't produce glyphs when calling
2625 produce_special_glyphs, above. */
2626 it->glyph_row = row;
2627 it->area = TEXT_AREA;
2628
2629 /* Get the dimensions of the display area. The display area
2630 consists of the visible window area plus a horizontally scrolled
2631 part to the left of the window. All x-values are relative to the
2632 start of this total display area. */
2633 if (base_face_id != DEFAULT_FACE_ID)
2634 {
2635 /* Mode lines, menu bar in terminal frames. */
2636 it->first_visible_x = 0;
2637 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2638 }
2639 else
2640 {
2641 it->first_visible_x
2642 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2643 it->last_visible_x = (it->first_visible_x
2644 + window_box_width (w, TEXT_AREA));
2645
2646 /* If we truncate lines, leave room for the truncator glyph(s) at
2647 the right margin. Otherwise, leave room for the continuation
2648 glyph(s). Truncation and continuation glyphs are not inserted
2649 for window-based redisplay. */
2650 if (!FRAME_WINDOW_P (it->f))
2651 {
2652 if (it->truncate_lines_p)
2653 it->last_visible_x -= it->truncation_pixel_width;
2654 else
2655 it->last_visible_x -= it->continuation_pixel_width;
2656 }
2657
2658 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2659 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2660 }
2661
2662 /* Leave room for a border glyph. */
2663 if (!FRAME_WINDOW_P (it->f)
2664 && !WINDOW_RIGHTMOST_P (it->w))
2665 it->last_visible_x -= 1;
2666
2667 it->last_visible_y = window_text_bottom_y (w);
2668
2669 /* For mode lines and alike, arrange for the first glyph having a
2670 left box line if the face specifies a box. */
2671 if (base_face_id != DEFAULT_FACE_ID)
2672 {
2673 struct face *face;
2674
2675 it->face_id = base_face_id;
2676
2677 /* If we have a boxed mode line, make the first character appear
2678 with a left box line. */
2679 face = FACE_FROM_ID (it->f, base_face_id);
2680 if (face->box != FACE_NO_BOX)
2681 it->start_of_box_run_p = 1;
2682 }
2683
2684 /* If a buffer position was specified, set the iterator there,
2685 getting overlays and face properties from that position. */
2686 if (charpos >= BUF_BEG (current_buffer))
2687 {
2688 it->end_charpos = ZV;
2689 it->face_id = -1;
2690 IT_CHARPOS (*it) = charpos;
2691
2692 /* Compute byte position if not specified. */
2693 if (bytepos < charpos)
2694 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2695 else
2696 IT_BYTEPOS (*it) = bytepos;
2697
2698 it->start = it->current;
2699
2700 /* Compute faces etc. */
2701 reseat (it, it->current.pos, 1);
2702 }
2703
2704 CHECK_IT (it);
2705 }
2706
2707
2708 /* Initialize IT for the display of window W with window start POS. */
2709
2710 void
2711 start_display (it, w, pos)
2712 struct it *it;
2713 struct window *w;
2714 struct text_pos pos;
2715 {
2716 struct glyph_row *row;
2717 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2718
2719 row = w->desired_matrix->rows + first_vpos;
2720 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2721 it->first_vpos = first_vpos;
2722
2723 /* Don't reseat to previous visible line start if current start
2724 position is in a string or image. */
2725 if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p)
2726 {
2727 int start_at_line_beg_p;
2728 int first_y = it->current_y;
2729
2730 /* If window start is not at a line start, skip forward to POS to
2731 get the correct continuation lines width. */
2732 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2733 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2734 if (!start_at_line_beg_p)
2735 {
2736 int new_x;
2737
2738 reseat_at_previous_visible_line_start (it);
2739 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2740
2741 new_x = it->current_x + it->pixel_width;
2742
2743 /* If lines are continued, this line may end in the middle
2744 of a multi-glyph character (e.g. a control character
2745 displayed as \003, or in the middle of an overlay
2746 string). In this case move_it_to above will not have
2747 taken us to the start of the continuation line but to the
2748 end of the continued line. */
2749 if (it->current_x > 0
2750 && !it->truncate_lines_p /* Lines are continued. */
2751 && (/* And glyph doesn't fit on the line. */
2752 new_x > it->last_visible_x
2753 /* Or it fits exactly and we're on a window
2754 system frame. */
2755 || (new_x == it->last_visible_x
2756 && FRAME_WINDOW_P (it->f))))
2757 {
2758 if (it->current.dpvec_index >= 0
2759 || it->current.overlay_string_index >= 0)
2760 {
2761 set_iterator_to_next (it, 1);
2762 move_it_in_display_line_to (it, -1, -1, 0);
2763 }
2764
2765 it->continuation_lines_width += it->current_x;
2766 }
2767
2768 /* We're starting a new display line, not affected by the
2769 height of the continued line, so clear the appropriate
2770 fields in the iterator structure. */
2771 it->max_ascent = it->max_descent = 0;
2772 it->max_phys_ascent = it->max_phys_descent = 0;
2773
2774 it->current_y = first_y;
2775 it->vpos = 0;
2776 it->current_x = it->hpos = 0;
2777 }
2778 }
2779
2780 #if 0 /* Don't assert the following because start_display is sometimes
2781 called intentionally with a window start that is not at a
2782 line start. Please leave this code in as a comment. */
2783
2784 /* Window start should be on a line start, now. */
2785 xassert (it->continuation_lines_width
2786 || IT_CHARPOS (it) == BEGV
2787 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2788 #endif /* 0 */
2789 }
2790
2791
2792 /* Return 1 if POS is a position in ellipses displayed for invisible
2793 text. W is the window we display, for text property lookup. */
2794
2795 static int
2796 in_ellipses_for_invisible_text_p (pos, w)
2797 struct display_pos *pos;
2798 struct window *w;
2799 {
2800 Lisp_Object prop, window;
2801 int ellipses_p = 0;
2802 int charpos = CHARPOS (pos->pos);
2803
2804 /* If POS specifies a position in a display vector, this might
2805 be for an ellipsis displayed for invisible text. We won't
2806 get the iterator set up for delivering that ellipsis unless
2807 we make sure that it gets aware of the invisible text. */
2808 if (pos->dpvec_index >= 0
2809 && pos->overlay_string_index < 0
2810 && CHARPOS (pos->string_pos) < 0
2811 && charpos > BEGV
2812 && (XSETWINDOW (window, w),
2813 prop = Fget_char_property (make_number (charpos),
2814 Qinvisible, window),
2815 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2816 {
2817 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2818 window);
2819 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2820 }
2821
2822 return ellipses_p;
2823 }
2824
2825
2826 /* Initialize IT for stepping through current_buffer in window W,
2827 starting at position POS that includes overlay string and display
2828 vector/ control character translation position information. Value
2829 is zero if there are overlay strings with newlines at POS. */
2830
2831 static int
2832 init_from_display_pos (it, w, pos)
2833 struct it *it;
2834 struct window *w;
2835 struct display_pos *pos;
2836 {
2837 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2838 int i, overlay_strings_with_newlines = 0;
2839
2840 /* If POS specifies a position in a display vector, this might
2841 be for an ellipsis displayed for invisible text. We won't
2842 get the iterator set up for delivering that ellipsis unless
2843 we make sure that it gets aware of the invisible text. */
2844 if (in_ellipses_for_invisible_text_p (pos, w))
2845 {
2846 --charpos;
2847 bytepos = 0;
2848 }
2849
2850 /* Keep in mind: the call to reseat in init_iterator skips invisible
2851 text, so we might end up at a position different from POS. This
2852 is only a problem when POS is a row start after a newline and an
2853 overlay starts there with an after-string, and the overlay has an
2854 invisible property. Since we don't skip invisible text in
2855 display_line and elsewhere immediately after consuming the
2856 newline before the row start, such a POS will not be in a string,
2857 but the call to init_iterator below will move us to the
2858 after-string. */
2859 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2860
2861 /* This only scans the current chunk -- it should scan all chunks.
2862 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2863 to 16 in 22.1 to make this a lesser problem. */
2864 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2865 {
2866 const char *s = SDATA (it->overlay_strings[i]);
2867 const char *e = s + SBYTES (it->overlay_strings[i]);
2868
2869 while (s < e && *s != '\n')
2870 ++s;
2871
2872 if (s < e)
2873 {
2874 overlay_strings_with_newlines = 1;
2875 break;
2876 }
2877 }
2878
2879 /* If position is within an overlay string, set up IT to the right
2880 overlay string. */
2881 if (pos->overlay_string_index >= 0)
2882 {
2883 int relative_index;
2884
2885 /* If the first overlay string happens to have a `display'
2886 property for an image, the iterator will be set up for that
2887 image, and we have to undo that setup first before we can
2888 correct the overlay string index. */
2889 if (it->method == GET_FROM_IMAGE)
2890 pop_it (it);
2891
2892 /* We already have the first chunk of overlay strings in
2893 IT->overlay_strings. Load more until the one for
2894 pos->overlay_string_index is in IT->overlay_strings. */
2895 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2896 {
2897 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2898 it->current.overlay_string_index = 0;
2899 while (n--)
2900 {
2901 load_overlay_strings (it, 0);
2902 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2903 }
2904 }
2905
2906 it->current.overlay_string_index = pos->overlay_string_index;
2907 relative_index = (it->current.overlay_string_index
2908 % OVERLAY_STRING_CHUNK_SIZE);
2909 it->string = it->overlay_strings[relative_index];
2910 xassert (STRINGP (it->string));
2911 it->current.string_pos = pos->string_pos;
2912 it->method = GET_FROM_STRING;
2913 }
2914
2915 #if 0 /* This is bogus because POS not having an overlay string
2916 position does not mean it's after the string. Example: A
2917 line starting with a before-string and initialization of IT
2918 to the previous row's end position. */
2919 else if (it->current.overlay_string_index >= 0)
2920 {
2921 /* If POS says we're already after an overlay string ending at
2922 POS, make sure to pop the iterator because it will be in
2923 front of that overlay string. When POS is ZV, we've thereby
2924 also ``processed'' overlay strings at ZV. */
2925 while (it->sp)
2926 pop_it (it);
2927 xassert (it->current.overlay_string_index == -1);
2928 xassert (it->method == GET_FROM_BUFFER);
2929 if (CHARPOS (pos->pos) == ZV)
2930 it->overlay_strings_at_end_processed_p = 1;
2931 }
2932 #endif /* 0 */
2933
2934 if (CHARPOS (pos->string_pos) >= 0)
2935 {
2936 /* Recorded position is not in an overlay string, but in another
2937 string. This can only be a string from a `display' property.
2938 IT should already be filled with that string. */
2939 it->current.string_pos = pos->string_pos;
2940 xassert (STRINGP (it->string));
2941 }
2942
2943 /* Restore position in display vector translations, control
2944 character translations or ellipses. */
2945 if (pos->dpvec_index >= 0)
2946 {
2947 if (it->dpvec == NULL)
2948 get_next_display_element (it);
2949 xassert (it->dpvec && it->current.dpvec_index == 0);
2950 it->current.dpvec_index = pos->dpvec_index;
2951 }
2952
2953 CHECK_IT (it);
2954 return !overlay_strings_with_newlines;
2955 }
2956
2957
2958 /* Initialize IT for stepping through current_buffer in window W
2959 starting at ROW->start. */
2960
2961 static void
2962 init_to_row_start (it, w, row)
2963 struct it *it;
2964 struct window *w;
2965 struct glyph_row *row;
2966 {
2967 init_from_display_pos (it, w, &row->start);
2968 it->start = row->start;
2969 it->continuation_lines_width = row->continuation_lines_width;
2970 CHECK_IT (it);
2971 }
2972
2973
2974 /* Initialize IT for stepping through current_buffer in window W
2975 starting in the line following ROW, i.e. starting at ROW->end.
2976 Value is zero if there are overlay strings with newlines at ROW's
2977 end position. */
2978
2979 static int
2980 init_to_row_end (it, w, row)
2981 struct it *it;
2982 struct window *w;
2983 struct glyph_row *row;
2984 {
2985 int success = 0;
2986
2987 if (init_from_display_pos (it, w, &row->end))
2988 {
2989 if (row->continued_p)
2990 it->continuation_lines_width
2991 = row->continuation_lines_width + row->pixel_width;
2992 CHECK_IT (it);
2993 success = 1;
2994 }
2995
2996 return success;
2997 }
2998
2999
3000
3001 \f
3002 /***********************************************************************
3003 Text properties
3004 ***********************************************************************/
3005
3006 /* Called when IT reaches IT->stop_charpos. Handle text property and
3007 overlay changes. Set IT->stop_charpos to the next position where
3008 to stop. */
3009
3010 static void
3011 handle_stop (it)
3012 struct it *it;
3013 {
3014 enum prop_handled handled;
3015 int handle_overlay_change_p;
3016 struct props *p;
3017
3018 it->dpvec = NULL;
3019 it->current.dpvec_index = -1;
3020 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3021 it->ignore_overlay_strings_at_pos_p = 0;
3022
3023 /* Use face of preceding text for ellipsis (if invisible) */
3024 if (it->selective_display_ellipsis_p)
3025 it->saved_face_id = it->face_id;
3026
3027 do
3028 {
3029 handled = HANDLED_NORMALLY;
3030
3031 /* Call text property handlers. */
3032 for (p = it_props; p->handler; ++p)
3033 {
3034 handled = p->handler (it);
3035
3036 if (handled == HANDLED_RECOMPUTE_PROPS)
3037 break;
3038 else if (handled == HANDLED_RETURN)
3039 {
3040 /* We still want to show before and after strings from
3041 overlays even if the actual buffer text is replaced. */
3042 if (!handle_overlay_change_p || it->sp > 1)
3043 return;
3044 if (!get_overlay_strings_1 (it, 0, 0))
3045 return;
3046 it->ignore_overlay_strings_at_pos_p = 1;
3047 it->string_from_display_prop_p = 0;
3048 handle_overlay_change_p = 0;
3049 handled = HANDLED_RECOMPUTE_PROPS;
3050 break;
3051 }
3052 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3053 handle_overlay_change_p = 0;
3054 }
3055
3056 if (handled != HANDLED_RECOMPUTE_PROPS)
3057 {
3058 /* Don't check for overlay strings below when set to deliver
3059 characters from a display vector. */
3060 if (it->method == GET_FROM_DISPLAY_VECTOR)
3061 handle_overlay_change_p = 0;
3062
3063 /* Handle overlay changes. */
3064 if (handle_overlay_change_p)
3065 handled = handle_overlay_change (it);
3066
3067 /* Determine where to stop next. */
3068 if (handled == HANDLED_NORMALLY)
3069 compute_stop_pos (it);
3070 }
3071 }
3072 while (handled == HANDLED_RECOMPUTE_PROPS);
3073 }
3074
3075
3076 /* Compute IT->stop_charpos from text property and overlay change
3077 information for IT's current position. */
3078
3079 static void
3080 compute_stop_pos (it)
3081 struct it *it;
3082 {
3083 register INTERVAL iv, next_iv;
3084 Lisp_Object object, limit, position;
3085
3086 /* If nowhere else, stop at the end. */
3087 it->stop_charpos = it->end_charpos;
3088
3089 if (STRINGP (it->string))
3090 {
3091 /* Strings are usually short, so don't limit the search for
3092 properties. */
3093 object = it->string;
3094 limit = Qnil;
3095 position = make_number (IT_STRING_CHARPOS (*it));
3096 }
3097 else
3098 {
3099 int charpos;
3100
3101 /* If next overlay change is in front of the current stop pos
3102 (which is IT->end_charpos), stop there. Note: value of
3103 next_overlay_change is point-max if no overlay change
3104 follows. */
3105 charpos = next_overlay_change (IT_CHARPOS (*it));
3106 if (charpos < it->stop_charpos)
3107 it->stop_charpos = charpos;
3108
3109 /* If showing the region, we have to stop at the region
3110 start or end because the face might change there. */
3111 if (it->region_beg_charpos > 0)
3112 {
3113 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3114 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3115 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3116 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3117 }
3118
3119 /* Set up variables for computing the stop position from text
3120 property changes. */
3121 XSETBUFFER (object, current_buffer);
3122 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3123 position = make_number (IT_CHARPOS (*it));
3124
3125 }
3126
3127 /* Get the interval containing IT's position. Value is a null
3128 interval if there isn't such an interval. */
3129 iv = validate_interval_range (object, &position, &position, 0);
3130 if (!NULL_INTERVAL_P (iv))
3131 {
3132 Lisp_Object values_here[LAST_PROP_IDX];
3133 struct props *p;
3134
3135 /* Get properties here. */
3136 for (p = it_props; p->handler; ++p)
3137 values_here[p->idx] = textget (iv->plist, *p->name);
3138
3139 /* Look for an interval following iv that has different
3140 properties. */
3141 for (next_iv = next_interval (iv);
3142 (!NULL_INTERVAL_P (next_iv)
3143 && (NILP (limit)
3144 || XFASTINT (limit) > next_iv->position));
3145 next_iv = next_interval (next_iv))
3146 {
3147 for (p = it_props; p->handler; ++p)
3148 {
3149 Lisp_Object new_value;
3150
3151 new_value = textget (next_iv->plist, *p->name);
3152 if (!EQ (values_here[p->idx], new_value))
3153 break;
3154 }
3155
3156 if (p->handler)
3157 break;
3158 }
3159
3160 if (!NULL_INTERVAL_P (next_iv))
3161 {
3162 if (INTEGERP (limit)
3163 && next_iv->position >= XFASTINT (limit))
3164 /* No text property change up to limit. */
3165 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3166 else
3167 /* Text properties change in next_iv. */
3168 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3169 }
3170 }
3171
3172 xassert (STRINGP (it->string)
3173 || (it->stop_charpos >= BEGV
3174 && it->stop_charpos >= IT_CHARPOS (*it)));
3175 }
3176
3177
3178 /* Return the position of the next overlay change after POS in
3179 current_buffer. Value is point-max if no overlay change
3180 follows. This is like `next-overlay-change' but doesn't use
3181 xmalloc. */
3182
3183 static int
3184 next_overlay_change (pos)
3185 int pos;
3186 {
3187 int noverlays;
3188 int endpos;
3189 Lisp_Object *overlays;
3190 int i;
3191
3192 /* Get all overlays at the given position. */
3193 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3194
3195 /* If any of these overlays ends before endpos,
3196 use its ending point instead. */
3197 for (i = 0; i < noverlays; ++i)
3198 {
3199 Lisp_Object oend;
3200 int oendpos;
3201
3202 oend = OVERLAY_END (overlays[i]);
3203 oendpos = OVERLAY_POSITION (oend);
3204 endpos = min (endpos, oendpos);
3205 }
3206
3207 return endpos;
3208 }
3209
3210
3211 \f
3212 /***********************************************************************
3213 Fontification
3214 ***********************************************************************/
3215
3216 /* Handle changes in the `fontified' property of the current buffer by
3217 calling hook functions from Qfontification_functions to fontify
3218 regions of text. */
3219
3220 static enum prop_handled
3221 handle_fontified_prop (it)
3222 struct it *it;
3223 {
3224 Lisp_Object prop, pos;
3225 enum prop_handled handled = HANDLED_NORMALLY;
3226
3227 if (!NILP (Vmemory_full))
3228 return handled;
3229
3230 /* Get the value of the `fontified' property at IT's current buffer
3231 position. (The `fontified' property doesn't have a special
3232 meaning in strings.) If the value is nil, call functions from
3233 Qfontification_functions. */
3234 if (!STRINGP (it->string)
3235 && it->s == NULL
3236 && !NILP (Vfontification_functions)
3237 && !NILP (Vrun_hooks)
3238 && (pos = make_number (IT_CHARPOS (*it)),
3239 prop = Fget_char_property (pos, Qfontified, Qnil),
3240 /* Ignore the special cased nil value always present at EOB since
3241 no amount of fontifying will be able to change it. */
3242 NILP (prop) && IT_CHARPOS (*it) < Z))
3243 {
3244 int count = SPECPDL_INDEX ();
3245 Lisp_Object val;
3246
3247 val = Vfontification_functions;
3248 specbind (Qfontification_functions, Qnil);
3249
3250 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3251 safe_call1 (val, pos);
3252 else
3253 {
3254 Lisp_Object globals, fn;
3255 struct gcpro gcpro1, gcpro2;
3256
3257 globals = Qnil;
3258 GCPRO2 (val, globals);
3259
3260 for (; CONSP (val); val = XCDR (val))
3261 {
3262 fn = XCAR (val);
3263
3264 if (EQ (fn, Qt))
3265 {
3266 /* A value of t indicates this hook has a local
3267 binding; it means to run the global binding too.
3268 In a global value, t should not occur. If it
3269 does, we must ignore it to avoid an endless
3270 loop. */
3271 for (globals = Fdefault_value (Qfontification_functions);
3272 CONSP (globals);
3273 globals = XCDR (globals))
3274 {
3275 fn = XCAR (globals);
3276 if (!EQ (fn, Qt))
3277 safe_call1 (fn, pos);
3278 }
3279 }
3280 else
3281 safe_call1 (fn, pos);
3282 }
3283
3284 UNGCPRO;
3285 }
3286
3287 unbind_to (count, Qnil);
3288
3289 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3290 something. This avoids an endless loop if they failed to
3291 fontify the text for which reason ever. */
3292 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3293 handled = HANDLED_RECOMPUTE_PROPS;
3294 }
3295
3296 return handled;
3297 }
3298
3299
3300 \f
3301 /***********************************************************************
3302 Faces
3303 ***********************************************************************/
3304
3305 /* Set up iterator IT from face properties at its current position.
3306 Called from handle_stop. */
3307
3308 static enum prop_handled
3309 handle_face_prop (it)
3310 struct it *it;
3311 {
3312 int new_face_id, next_stop;
3313
3314 if (!STRINGP (it->string))
3315 {
3316 new_face_id
3317 = face_at_buffer_position (it->w,
3318 IT_CHARPOS (*it),
3319 it->region_beg_charpos,
3320 it->region_end_charpos,
3321 &next_stop,
3322 (IT_CHARPOS (*it)
3323 + TEXT_PROP_DISTANCE_LIMIT),
3324 0);
3325
3326 /* Is this a start of a run of characters with box face?
3327 Caveat: this can be called for a freshly initialized
3328 iterator; face_id is -1 in this case. We know that the new
3329 face will not change until limit, i.e. if the new face has a
3330 box, all characters up to limit will have one. But, as
3331 usual, we don't know whether limit is really the end. */
3332 if (new_face_id != it->face_id)
3333 {
3334 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3335
3336 /* If new face has a box but old face has not, this is
3337 the start of a run of characters with box, i.e. it has
3338 a shadow on the left side. The value of face_id of the
3339 iterator will be -1 if this is the initial call that gets
3340 the face. In this case, we have to look in front of IT's
3341 position and see whether there is a face != new_face_id. */
3342 it->start_of_box_run_p
3343 = (new_face->box != FACE_NO_BOX
3344 && (it->face_id >= 0
3345 || IT_CHARPOS (*it) == BEG
3346 || new_face_id != face_before_it_pos (it)));
3347 it->face_box_p = new_face->box != FACE_NO_BOX;
3348 }
3349 }
3350 else
3351 {
3352 int base_face_id, bufpos;
3353
3354 if (it->current.overlay_string_index >= 0)
3355 bufpos = IT_CHARPOS (*it);
3356 else
3357 bufpos = 0;
3358
3359 /* For strings from a buffer, i.e. overlay strings or strings
3360 from a `display' property, use the face at IT's current
3361 buffer position as the base face to merge with, so that
3362 overlay strings appear in the same face as surrounding
3363 text, unless they specify their own faces. */
3364 base_face_id = underlying_face_id (it);
3365
3366 new_face_id = face_at_string_position (it->w,
3367 it->string,
3368 IT_STRING_CHARPOS (*it),
3369 bufpos,
3370 it->region_beg_charpos,
3371 it->region_end_charpos,
3372 &next_stop,
3373 base_face_id, 0);
3374
3375 #if 0 /* This shouldn't be neccessary. Let's check it. */
3376 /* If IT is used to display a mode line we would really like to
3377 use the mode line face instead of the frame's default face. */
3378 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3379 && new_face_id == DEFAULT_FACE_ID)
3380 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3381 #endif
3382
3383 /* Is this a start of a run of characters with box? Caveat:
3384 this can be called for a freshly allocated iterator; face_id
3385 is -1 is this case. We know that the new face will not
3386 change until the next check pos, i.e. if the new face has a
3387 box, all characters up to that position will have a
3388 box. But, as usual, we don't know whether that position
3389 is really the end. */
3390 if (new_face_id != it->face_id)
3391 {
3392 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3393 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3394
3395 /* If new face has a box but old face hasn't, this is the
3396 start of a run of characters with box, i.e. it has a
3397 shadow on the left side. */
3398 it->start_of_box_run_p
3399 = new_face->box && (old_face == NULL || !old_face->box);
3400 it->face_box_p = new_face->box != FACE_NO_BOX;
3401 }
3402 }
3403
3404 it->face_id = new_face_id;
3405 return HANDLED_NORMALLY;
3406 }
3407
3408
3409 /* Return the ID of the face ``underlying'' IT's current position,
3410 which is in a string. If the iterator is associated with a
3411 buffer, return the face at IT's current buffer position.
3412 Otherwise, use the iterator's base_face_id. */
3413
3414 static int
3415 underlying_face_id (it)
3416 struct it *it;
3417 {
3418 int face_id = it->base_face_id, i;
3419
3420 xassert (STRINGP (it->string));
3421
3422 for (i = it->sp - 1; i >= 0; --i)
3423 if (NILP (it->stack[i].string))
3424 face_id = it->stack[i].face_id;
3425
3426 return face_id;
3427 }
3428
3429
3430 /* Compute the face one character before or after the current position
3431 of IT. BEFORE_P non-zero means get the face in front of IT's
3432 position. Value is the id of the face. */
3433
3434 static int
3435 face_before_or_after_it_pos (it, before_p)
3436 struct it *it;
3437 int before_p;
3438 {
3439 int face_id, limit;
3440 int next_check_charpos;
3441 struct text_pos pos;
3442
3443 xassert (it->s == NULL);
3444
3445 if (STRINGP (it->string))
3446 {
3447 int bufpos, base_face_id;
3448
3449 /* No face change past the end of the string (for the case
3450 we are padding with spaces). No face change before the
3451 string start. */
3452 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3453 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3454 return it->face_id;
3455
3456 /* Set pos to the position before or after IT's current position. */
3457 if (before_p)
3458 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3459 else
3460 /* For composition, we must check the character after the
3461 composition. */
3462 pos = (it->what == IT_COMPOSITION
3463 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3464 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3465
3466 if (it->current.overlay_string_index >= 0)
3467 bufpos = IT_CHARPOS (*it);
3468 else
3469 bufpos = 0;
3470
3471 base_face_id = underlying_face_id (it);
3472
3473 /* Get the face for ASCII, or unibyte. */
3474 face_id = face_at_string_position (it->w,
3475 it->string,
3476 CHARPOS (pos),
3477 bufpos,
3478 it->region_beg_charpos,
3479 it->region_end_charpos,
3480 &next_check_charpos,
3481 base_face_id, 0);
3482
3483 /* Correct the face for charsets different from ASCII. Do it
3484 for the multibyte case only. The face returned above is
3485 suitable for unibyte text if IT->string is unibyte. */
3486 if (STRING_MULTIBYTE (it->string))
3487 {
3488 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3489 int rest = SBYTES (it->string) - BYTEPOS (pos);
3490 int c, len;
3491 struct face *face = FACE_FROM_ID (it->f, face_id);
3492
3493 c = string_char_and_length (p, rest, &len);
3494 face_id = FACE_FOR_CHAR (it->f, face, c);
3495 }
3496 }
3497 else
3498 {
3499 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3500 || (IT_CHARPOS (*it) <= BEGV && before_p))
3501 return it->face_id;
3502
3503 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3504 pos = it->current.pos;
3505
3506 if (before_p)
3507 DEC_TEXT_POS (pos, it->multibyte_p);
3508 else
3509 {
3510 if (it->what == IT_COMPOSITION)
3511 /* For composition, we must check the position after the
3512 composition. */
3513 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3514 else
3515 INC_TEXT_POS (pos, it->multibyte_p);
3516 }
3517
3518 /* Determine face for CHARSET_ASCII, or unibyte. */
3519 face_id = face_at_buffer_position (it->w,
3520 CHARPOS (pos),
3521 it->region_beg_charpos,
3522 it->region_end_charpos,
3523 &next_check_charpos,
3524 limit, 0);
3525
3526 /* Correct the face for charsets different from ASCII. Do it
3527 for the multibyte case only. The face returned above is
3528 suitable for unibyte text if current_buffer is unibyte. */
3529 if (it->multibyte_p)
3530 {
3531 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3532 struct face *face = FACE_FROM_ID (it->f, face_id);
3533 face_id = FACE_FOR_CHAR (it->f, face, c);
3534 }
3535 }
3536
3537 return face_id;
3538 }
3539
3540
3541 \f
3542 /***********************************************************************
3543 Invisible text
3544 ***********************************************************************/
3545
3546 /* Set up iterator IT from invisible properties at its current
3547 position. Called from handle_stop. */
3548
3549 static enum prop_handled
3550 handle_invisible_prop (it)
3551 struct it *it;
3552 {
3553 enum prop_handled handled = HANDLED_NORMALLY;
3554
3555 if (STRINGP (it->string))
3556 {
3557 extern Lisp_Object Qinvisible;
3558 Lisp_Object prop, end_charpos, limit, charpos;
3559
3560 /* Get the value of the invisible text property at the
3561 current position. Value will be nil if there is no such
3562 property. */
3563 charpos = make_number (IT_STRING_CHARPOS (*it));
3564 prop = Fget_text_property (charpos, Qinvisible, it->string);
3565
3566 if (!NILP (prop)
3567 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3568 {
3569 handled = HANDLED_RECOMPUTE_PROPS;
3570
3571 /* Get the position at which the next change of the
3572 invisible text property can be found in IT->string.
3573 Value will be nil if the property value is the same for
3574 all the rest of IT->string. */
3575 XSETINT (limit, SCHARS (it->string));
3576 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3577 it->string, limit);
3578
3579 /* Text at current position is invisible. The next
3580 change in the property is at position end_charpos.
3581 Move IT's current position to that position. */
3582 if (INTEGERP (end_charpos)
3583 && XFASTINT (end_charpos) < XFASTINT (limit))
3584 {
3585 struct text_pos old;
3586 old = it->current.string_pos;
3587 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3588 compute_string_pos (&it->current.string_pos, old, it->string);
3589 }
3590 else
3591 {
3592 /* The rest of the string is invisible. If this is an
3593 overlay string, proceed with the next overlay string
3594 or whatever comes and return a character from there. */
3595 if (it->current.overlay_string_index >= 0)
3596 {
3597 next_overlay_string (it);
3598 /* Don't check for overlay strings when we just
3599 finished processing them. */
3600 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3601 }
3602 else
3603 {
3604 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3605 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3606 }
3607 }
3608 }
3609 }
3610 else
3611 {
3612 int invis_p, newpos, next_stop, start_charpos;
3613 Lisp_Object pos, prop, overlay;
3614
3615 /* First of all, is there invisible text at this position? */
3616 start_charpos = IT_CHARPOS (*it);
3617 pos = make_number (IT_CHARPOS (*it));
3618 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3619 &overlay);
3620 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3621
3622 /* If we are on invisible text, skip over it. */
3623 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3624 {
3625 /* Record whether we have to display an ellipsis for the
3626 invisible text. */
3627 int display_ellipsis_p = invis_p == 2;
3628
3629 handled = HANDLED_RECOMPUTE_PROPS;
3630
3631 /* Loop skipping over invisible text. The loop is left at
3632 ZV or with IT on the first char being visible again. */
3633 do
3634 {
3635 /* Try to skip some invisible text. Return value is the
3636 position reached which can be equal to IT's position
3637 if there is nothing invisible here. This skips both
3638 over invisible text properties and overlays with
3639 invisible property. */
3640 newpos = skip_invisible (IT_CHARPOS (*it),
3641 &next_stop, ZV, it->window);
3642
3643 /* If we skipped nothing at all we weren't at invisible
3644 text in the first place. If everything to the end of
3645 the buffer was skipped, end the loop. */
3646 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3647 invis_p = 0;
3648 else
3649 {
3650 /* We skipped some characters but not necessarily
3651 all there are. Check if we ended up on visible
3652 text. Fget_char_property returns the property of
3653 the char before the given position, i.e. if we
3654 get invis_p = 0, this means that the char at
3655 newpos is visible. */
3656 pos = make_number (newpos);
3657 prop = Fget_char_property (pos, Qinvisible, it->window);
3658 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3659 }
3660
3661 /* If we ended up on invisible text, proceed to
3662 skip starting with next_stop. */
3663 if (invis_p)
3664 IT_CHARPOS (*it) = next_stop;
3665
3666 /* If there are adjacent invisible texts, don't lose the
3667 second one's ellipsis. */
3668 if (invis_p == 2)
3669 display_ellipsis_p = 1;
3670 }
3671 while (invis_p);
3672
3673 /* The position newpos is now either ZV or on visible text. */
3674 IT_CHARPOS (*it) = newpos;
3675 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3676
3677 /* If there are before-strings at the start of invisible
3678 text, and the text is invisible because of a text
3679 property, arrange to show before-strings because 20.x did
3680 it that way. (If the text is invisible because of an
3681 overlay property instead of a text property, this is
3682 already handled in the overlay code.) */
3683 if (NILP (overlay)
3684 && get_overlay_strings (it, start_charpos))
3685 {
3686 handled = HANDLED_RECOMPUTE_PROPS;
3687 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3688 }
3689 else if (display_ellipsis_p)
3690 {
3691 /* Make sure that the glyphs of the ellipsis will get
3692 correct `charpos' values. If we would not update
3693 it->position here, the glyphs would belong to the
3694 last visible character _before_ the invisible
3695 text, which confuses `set_cursor_from_row'.
3696
3697 We use the last invisible position instead of the
3698 first because this way the cursor is always drawn on
3699 the first "." of the ellipsis, whenever PT is inside
3700 the invisible text. Otherwise the cursor would be
3701 placed _after_ the ellipsis when the point is after the
3702 first invisible character. */
3703 if (!STRINGP (it->object))
3704 {
3705 it->position.charpos = IT_CHARPOS (*it) - 1;
3706 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3707 }
3708 setup_for_ellipsis (it, 0);
3709 }
3710 }
3711 }
3712
3713 return handled;
3714 }
3715
3716
3717 /* Make iterator IT return `...' next.
3718 Replaces LEN characters from buffer. */
3719
3720 static void
3721 setup_for_ellipsis (it, len)
3722 struct it *it;
3723 int len;
3724 {
3725 /* Use the display table definition for `...'. Invalid glyphs
3726 will be handled by the method returning elements from dpvec. */
3727 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3728 {
3729 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3730 it->dpvec = v->contents;
3731 it->dpend = v->contents + v->size;
3732 }
3733 else
3734 {
3735 /* Default `...'. */
3736 it->dpvec = default_invis_vector;
3737 it->dpend = default_invis_vector + 3;
3738 }
3739
3740 it->dpvec_char_len = len;
3741 it->current.dpvec_index = 0;
3742 it->dpvec_face_id = -1;
3743
3744 /* Remember the current face id in case glyphs specify faces.
3745 IT's face is restored in set_iterator_to_next.
3746 saved_face_id was set to preceding char's face in handle_stop. */
3747 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3748 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3749
3750 it->method = GET_FROM_DISPLAY_VECTOR;
3751 it->ellipsis_p = 1;
3752 }
3753
3754
3755 \f
3756 /***********************************************************************
3757 'display' property
3758 ***********************************************************************/
3759
3760 /* Set up iterator IT from `display' property at its current position.
3761 Called from handle_stop.
3762 We return HANDLED_RETURN if some part of the display property
3763 overrides the display of the buffer text itself.
3764 Otherwise we return HANDLED_NORMALLY. */
3765
3766 static enum prop_handled
3767 handle_display_prop (it)
3768 struct it *it;
3769 {
3770 Lisp_Object prop, object;
3771 struct text_pos *position;
3772 /* Nonzero if some property replaces the display of the text itself. */
3773 int display_replaced_p = 0;
3774
3775 if (STRINGP (it->string))
3776 {
3777 object = it->string;
3778 position = &it->current.string_pos;
3779 }
3780 else
3781 {
3782 XSETWINDOW (object, it->w);
3783 position = &it->current.pos;
3784 }
3785
3786 /* Reset those iterator values set from display property values. */
3787 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3788 it->space_width = Qnil;
3789 it->font_height = Qnil;
3790 it->voffset = 0;
3791
3792 /* We don't support recursive `display' properties, i.e. string
3793 values that have a string `display' property, that have a string
3794 `display' property etc. */
3795 if (!it->string_from_display_prop_p)
3796 it->area = TEXT_AREA;
3797
3798 prop = Fget_char_property (make_number (position->charpos),
3799 Qdisplay, object);
3800 if (NILP (prop))
3801 return HANDLED_NORMALLY;
3802
3803 if (!STRINGP (it->string))
3804 object = it->w->buffer;
3805
3806 if (CONSP (prop)
3807 /* Simple properties. */
3808 && !EQ (XCAR (prop), Qimage)
3809 && !EQ (XCAR (prop), Qspace)
3810 && !EQ (XCAR (prop), Qwhen)
3811 && !EQ (XCAR (prop), Qslice)
3812 && !EQ (XCAR (prop), Qspace_width)
3813 && !EQ (XCAR (prop), Qheight)
3814 && !EQ (XCAR (prop), Qraise)
3815 /* Marginal area specifications. */
3816 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3817 && !EQ (XCAR (prop), Qleft_fringe)
3818 && !EQ (XCAR (prop), Qright_fringe)
3819 && !NILP (XCAR (prop)))
3820 {
3821 for (; CONSP (prop); prop = XCDR (prop))
3822 {
3823 if (handle_single_display_spec (it, XCAR (prop), object,
3824 position, display_replaced_p))
3825 display_replaced_p = 1;
3826 }
3827 }
3828 else if (VECTORP (prop))
3829 {
3830 int i;
3831 for (i = 0; i < ASIZE (prop); ++i)
3832 if (handle_single_display_spec (it, AREF (prop, i), object,
3833 position, display_replaced_p))
3834 display_replaced_p = 1;
3835 }
3836 else
3837 {
3838 int ret = handle_single_display_spec (it, prop, object, position, 0);
3839 if (ret < 0) /* Replaced by "", i.e. nothing. */
3840 return HANDLED_RECOMPUTE_PROPS;
3841 if (ret)
3842 display_replaced_p = 1;
3843 }
3844
3845 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3846 }
3847
3848
3849 /* Value is the position of the end of the `display' property starting
3850 at START_POS in OBJECT. */
3851
3852 static struct text_pos
3853 display_prop_end (it, object, start_pos)
3854 struct it *it;
3855 Lisp_Object object;
3856 struct text_pos start_pos;
3857 {
3858 Lisp_Object end;
3859 struct text_pos end_pos;
3860
3861 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3862 Qdisplay, object, Qnil);
3863 CHARPOS (end_pos) = XFASTINT (end);
3864 if (STRINGP (object))
3865 compute_string_pos (&end_pos, start_pos, it->string);
3866 else
3867 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3868
3869 return end_pos;
3870 }
3871
3872
3873 /* Set up IT from a single `display' specification PROP. OBJECT
3874 is the object in which the `display' property was found. *POSITION
3875 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3876 means that we previously saw a display specification which already
3877 replaced text display with something else, for example an image;
3878 we ignore such properties after the first one has been processed.
3879
3880 If PROP is a `space' or `image' specification, and in some other
3881 cases too, set *POSITION to the position where the `display'
3882 property ends.
3883
3884 Value is non-zero if something was found which replaces the display
3885 of buffer or string text. Specifically, the value is -1 if that
3886 "something" is "nothing". */
3887
3888 static int
3889 handle_single_display_spec (it, spec, object, position,
3890 display_replaced_before_p)
3891 struct it *it;
3892 Lisp_Object spec;
3893 Lisp_Object object;
3894 struct text_pos *position;
3895 int display_replaced_before_p;
3896 {
3897 Lisp_Object form;
3898 Lisp_Object location, value;
3899 struct text_pos start_pos, save_pos;
3900 int valid_p;
3901
3902 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3903 If the result is non-nil, use VALUE instead of SPEC. */
3904 form = Qt;
3905 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3906 {
3907 spec = XCDR (spec);
3908 if (!CONSP (spec))
3909 return 0;
3910 form = XCAR (spec);
3911 spec = XCDR (spec);
3912 }
3913
3914 if (!NILP (form) && !EQ (form, Qt))
3915 {
3916 int count = SPECPDL_INDEX ();
3917 struct gcpro gcpro1;
3918
3919 /* Bind `object' to the object having the `display' property, a
3920 buffer or string. Bind `position' to the position in the
3921 object where the property was found, and `buffer-position'
3922 to the current position in the buffer. */
3923 specbind (Qobject, object);
3924 specbind (Qposition, make_number (CHARPOS (*position)));
3925 specbind (Qbuffer_position,
3926 make_number (STRINGP (object)
3927 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3928 GCPRO1 (form);
3929 form = safe_eval (form);
3930 UNGCPRO;
3931 unbind_to (count, Qnil);
3932 }
3933
3934 if (NILP (form))
3935 return 0;
3936
3937 /* Handle `(height HEIGHT)' specifications. */
3938 if (CONSP (spec)
3939 && EQ (XCAR (spec), Qheight)
3940 && CONSP (XCDR (spec)))
3941 {
3942 if (!FRAME_WINDOW_P (it->f))
3943 return 0;
3944
3945 it->font_height = XCAR (XCDR (spec));
3946 if (!NILP (it->font_height))
3947 {
3948 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3949 int new_height = -1;
3950
3951 if (CONSP (it->font_height)
3952 && (EQ (XCAR (it->font_height), Qplus)
3953 || EQ (XCAR (it->font_height), Qminus))
3954 && CONSP (XCDR (it->font_height))
3955 && INTEGERP (XCAR (XCDR (it->font_height))))
3956 {
3957 /* `(+ N)' or `(- N)' where N is an integer. */
3958 int steps = XINT (XCAR (XCDR (it->font_height)));
3959 if (EQ (XCAR (it->font_height), Qplus))
3960 steps = - steps;
3961 it->face_id = smaller_face (it->f, it->face_id, steps);
3962 }
3963 else if (FUNCTIONP (it->font_height))
3964 {
3965 /* Call function with current height as argument.
3966 Value is the new height. */
3967 Lisp_Object height;
3968 height = safe_call1 (it->font_height,
3969 face->lface[LFACE_HEIGHT_INDEX]);
3970 if (NUMBERP (height))
3971 new_height = XFLOATINT (height);
3972 }
3973 else if (NUMBERP (it->font_height))
3974 {
3975 /* Value is a multiple of the canonical char height. */
3976 struct face *face;
3977
3978 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3979 new_height = (XFLOATINT (it->font_height)
3980 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3981 }
3982 else
3983 {
3984 /* Evaluate IT->font_height with `height' bound to the
3985 current specified height to get the new height. */
3986 int count = SPECPDL_INDEX ();
3987
3988 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3989 value = safe_eval (it->font_height);
3990 unbind_to (count, Qnil);
3991
3992 if (NUMBERP (value))
3993 new_height = XFLOATINT (value);
3994 }
3995
3996 if (new_height > 0)
3997 it->face_id = face_with_height (it->f, it->face_id, new_height);
3998 }
3999
4000 return 0;
4001 }
4002
4003 /* Handle `(space_width WIDTH)'. */
4004 if (CONSP (spec)
4005 && EQ (XCAR (spec), Qspace_width)
4006 && CONSP (XCDR (spec)))
4007 {
4008 if (!FRAME_WINDOW_P (it->f))
4009 return 0;
4010
4011 value = XCAR (XCDR (spec));
4012 if (NUMBERP (value) && XFLOATINT (value) > 0)
4013 it->space_width = value;
4014
4015 return 0;
4016 }
4017
4018 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4019 if (CONSP (spec)
4020 && EQ (XCAR (spec), Qslice))
4021 {
4022 Lisp_Object tem;
4023
4024 if (!FRAME_WINDOW_P (it->f))
4025 return 0;
4026
4027 if (tem = XCDR (spec), CONSP (tem))
4028 {
4029 it->slice.x = XCAR (tem);
4030 if (tem = XCDR (tem), CONSP (tem))
4031 {
4032 it->slice.y = XCAR (tem);
4033 if (tem = XCDR (tem), CONSP (tem))
4034 {
4035 it->slice.width = XCAR (tem);
4036 if (tem = XCDR (tem), CONSP (tem))
4037 it->slice.height = XCAR (tem);
4038 }
4039 }
4040 }
4041
4042 return 0;
4043 }
4044
4045 /* Handle `(raise FACTOR)'. */
4046 if (CONSP (spec)
4047 && EQ (XCAR (spec), Qraise)
4048 && CONSP (XCDR (spec)))
4049 {
4050 if (!FRAME_WINDOW_P (it->f))
4051 return 0;
4052
4053 #ifdef HAVE_WINDOW_SYSTEM
4054 value = XCAR (XCDR (spec));
4055 if (NUMBERP (value))
4056 {
4057 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4058 it->voffset = - (XFLOATINT (value)
4059 * (FONT_HEIGHT (face->font)));
4060 }
4061 #endif /* HAVE_WINDOW_SYSTEM */
4062
4063 return 0;
4064 }
4065
4066 /* Don't handle the other kinds of display specifications
4067 inside a string that we got from a `display' property. */
4068 if (it->string_from_display_prop_p)
4069 return 0;
4070
4071 /* Characters having this form of property are not displayed, so
4072 we have to find the end of the property. */
4073 start_pos = *position;
4074 *position = display_prop_end (it, object, start_pos);
4075 value = Qnil;
4076
4077 /* Stop the scan at that end position--we assume that all
4078 text properties change there. */
4079 it->stop_charpos = position->charpos;
4080
4081 /* Handle `(left-fringe BITMAP [FACE])'
4082 and `(right-fringe BITMAP [FACE])'. */
4083 if (CONSP (spec)
4084 && (EQ (XCAR (spec), Qleft_fringe)
4085 || EQ (XCAR (spec), Qright_fringe))
4086 && CONSP (XCDR (spec)))
4087 {
4088 int face_id = DEFAULT_FACE_ID;
4089 int fringe_bitmap;
4090
4091 if (!FRAME_WINDOW_P (it->f))
4092 /* If we return here, POSITION has been advanced
4093 across the text with this property. */
4094 return 0;
4095
4096 #ifdef HAVE_WINDOW_SYSTEM
4097 value = XCAR (XCDR (spec));
4098 if (!SYMBOLP (value)
4099 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4100 /* If we return here, POSITION has been advanced
4101 across the text with this property. */
4102 return 0;
4103
4104 if (CONSP (XCDR (XCDR (spec))))
4105 {
4106 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4107 int face_id2 = lookup_derived_face (it->f, face_name,
4108 'A', FRINGE_FACE_ID, 0);
4109 if (face_id2 >= 0)
4110 face_id = face_id2;
4111 }
4112
4113 /* Save current settings of IT so that we can restore them
4114 when we are finished with the glyph property value. */
4115
4116 save_pos = it->position;
4117 it->position = *position;
4118 push_it (it);
4119 it->position = save_pos;
4120
4121 it->area = TEXT_AREA;
4122 it->what = IT_IMAGE;
4123 it->image_id = -1; /* no image */
4124 it->position = start_pos;
4125 it->object = NILP (object) ? it->w->buffer : object;
4126 it->method = GET_FROM_IMAGE;
4127 it->face_id = face_id;
4128
4129 /* Say that we haven't consumed the characters with
4130 `display' property yet. The call to pop_it in
4131 set_iterator_to_next will clean this up. */
4132 *position = start_pos;
4133
4134 if (EQ (XCAR (spec), Qleft_fringe))
4135 {
4136 it->left_user_fringe_bitmap = fringe_bitmap;
4137 it->left_user_fringe_face_id = face_id;
4138 }
4139 else
4140 {
4141 it->right_user_fringe_bitmap = fringe_bitmap;
4142 it->right_user_fringe_face_id = face_id;
4143 }
4144 #endif /* HAVE_WINDOW_SYSTEM */
4145 return 1;
4146 }
4147
4148 /* Prepare to handle `((margin left-margin) ...)',
4149 `((margin right-margin) ...)' and `((margin nil) ...)'
4150 prefixes for display specifications. */
4151 location = Qunbound;
4152 if (CONSP (spec) && CONSP (XCAR (spec)))
4153 {
4154 Lisp_Object tem;
4155
4156 value = XCDR (spec);
4157 if (CONSP (value))
4158 value = XCAR (value);
4159
4160 tem = XCAR (spec);
4161 if (EQ (XCAR (tem), Qmargin)
4162 && (tem = XCDR (tem),
4163 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4164 (NILP (tem)
4165 || EQ (tem, Qleft_margin)
4166 || EQ (tem, Qright_margin))))
4167 location = tem;
4168 }
4169
4170 if (EQ (location, Qunbound))
4171 {
4172 location = Qnil;
4173 value = spec;
4174 }
4175
4176 /* After this point, VALUE is the property after any
4177 margin prefix has been stripped. It must be a string,
4178 an image specification, or `(space ...)'.
4179
4180 LOCATION specifies where to display: `left-margin',
4181 `right-margin' or nil. */
4182
4183 valid_p = (STRINGP (value)
4184 #ifdef HAVE_WINDOW_SYSTEM
4185 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4186 #endif /* not HAVE_WINDOW_SYSTEM */
4187 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4188
4189 if (valid_p && !display_replaced_before_p)
4190 {
4191 /* Save current settings of IT so that we can restore them
4192 when we are finished with the glyph property value. */
4193 save_pos = it->position;
4194 it->position = *position;
4195 push_it (it);
4196 it->position = save_pos;
4197
4198 if (NILP (location))
4199 it->area = TEXT_AREA;
4200 else if (EQ (location, Qleft_margin))
4201 it->area = LEFT_MARGIN_AREA;
4202 else
4203 it->area = RIGHT_MARGIN_AREA;
4204
4205 if (STRINGP (value))
4206 {
4207 if (SCHARS (value) == 0)
4208 {
4209 pop_it (it);
4210 return -1; /* Replaced by "", i.e. nothing. */
4211 }
4212 it->string = value;
4213 it->multibyte_p = STRING_MULTIBYTE (it->string);
4214 it->current.overlay_string_index = -1;
4215 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4216 it->end_charpos = it->string_nchars = SCHARS (it->string);
4217 it->method = GET_FROM_STRING;
4218 it->stop_charpos = 0;
4219 it->string_from_display_prop_p = 1;
4220 /* Say that we haven't consumed the characters with
4221 `display' property yet. The call to pop_it in
4222 set_iterator_to_next will clean this up. */
4223 *position = start_pos;
4224 }
4225 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4226 {
4227 it->method = GET_FROM_STRETCH;
4228 it->object = value;
4229 *position = it->position = start_pos;
4230 }
4231 #ifdef HAVE_WINDOW_SYSTEM
4232 else
4233 {
4234 it->what = IT_IMAGE;
4235 it->image_id = lookup_image (it->f, value);
4236 it->position = start_pos;
4237 it->object = NILP (object) ? it->w->buffer : object;
4238 it->method = GET_FROM_IMAGE;
4239
4240 /* Say that we haven't consumed the characters with
4241 `display' property yet. The call to pop_it in
4242 set_iterator_to_next will clean this up. */
4243 *position = start_pos;
4244 }
4245 #endif /* HAVE_WINDOW_SYSTEM */
4246
4247 return 1;
4248 }
4249
4250 /* Invalid property or property not supported. Restore
4251 POSITION to what it was before. */
4252 *position = start_pos;
4253 return 0;
4254 }
4255
4256
4257 /* Check if SPEC is a display sub-property value whose text should be
4258 treated as intangible. */
4259
4260 static int
4261 single_display_spec_intangible_p (prop)
4262 Lisp_Object prop;
4263 {
4264 /* Skip over `when FORM'. */
4265 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4266 {
4267 prop = XCDR (prop);
4268 if (!CONSP (prop))
4269 return 0;
4270 prop = XCDR (prop);
4271 }
4272
4273 if (STRINGP (prop))
4274 return 1;
4275
4276 if (!CONSP (prop))
4277 return 0;
4278
4279 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4280 we don't need to treat text as intangible. */
4281 if (EQ (XCAR (prop), Qmargin))
4282 {
4283 prop = XCDR (prop);
4284 if (!CONSP (prop))
4285 return 0;
4286
4287 prop = XCDR (prop);
4288 if (!CONSP (prop)
4289 || EQ (XCAR (prop), Qleft_margin)
4290 || EQ (XCAR (prop), Qright_margin))
4291 return 0;
4292 }
4293
4294 return (CONSP (prop)
4295 && (EQ (XCAR (prop), Qimage)
4296 || EQ (XCAR (prop), Qspace)));
4297 }
4298
4299
4300 /* Check if PROP is a display property value whose text should be
4301 treated as intangible. */
4302
4303 int
4304 display_prop_intangible_p (prop)
4305 Lisp_Object prop;
4306 {
4307 if (CONSP (prop)
4308 && CONSP (XCAR (prop))
4309 && !EQ (Qmargin, XCAR (XCAR (prop))))
4310 {
4311 /* A list of sub-properties. */
4312 while (CONSP (prop))
4313 {
4314 if (single_display_spec_intangible_p (XCAR (prop)))
4315 return 1;
4316 prop = XCDR (prop);
4317 }
4318 }
4319 else if (VECTORP (prop))
4320 {
4321 /* A vector of sub-properties. */
4322 int i;
4323 for (i = 0; i < ASIZE (prop); ++i)
4324 if (single_display_spec_intangible_p (AREF (prop, i)))
4325 return 1;
4326 }
4327 else
4328 return single_display_spec_intangible_p (prop);
4329
4330 return 0;
4331 }
4332
4333
4334 /* Return 1 if PROP is a display sub-property value containing STRING. */
4335
4336 static int
4337 single_display_spec_string_p (prop, string)
4338 Lisp_Object prop, string;
4339 {
4340 if (EQ (string, prop))
4341 return 1;
4342
4343 /* Skip over `when FORM'. */
4344 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4345 {
4346 prop = XCDR (prop);
4347 if (!CONSP (prop))
4348 return 0;
4349 prop = XCDR (prop);
4350 }
4351
4352 if (CONSP (prop))
4353 /* Skip over `margin LOCATION'. */
4354 if (EQ (XCAR (prop), Qmargin))
4355 {
4356 prop = XCDR (prop);
4357 if (!CONSP (prop))
4358 return 0;
4359
4360 prop = XCDR (prop);
4361 if (!CONSP (prop))
4362 return 0;
4363 }
4364
4365 return CONSP (prop) && EQ (XCAR (prop), string);
4366 }
4367
4368
4369 /* Return 1 if STRING appears in the `display' property PROP. */
4370
4371 static int
4372 display_prop_string_p (prop, string)
4373 Lisp_Object prop, string;
4374 {
4375 if (CONSP (prop)
4376 && CONSP (XCAR (prop))
4377 && !EQ (Qmargin, XCAR (XCAR (prop))))
4378 {
4379 /* A list of sub-properties. */
4380 while (CONSP (prop))
4381 {
4382 if (single_display_spec_string_p (XCAR (prop), string))
4383 return 1;
4384 prop = XCDR (prop);
4385 }
4386 }
4387 else if (VECTORP (prop))
4388 {
4389 /* A vector of sub-properties. */
4390 int i;
4391 for (i = 0; i < ASIZE (prop); ++i)
4392 if (single_display_spec_string_p (AREF (prop, i), string))
4393 return 1;
4394 }
4395 else
4396 return single_display_spec_string_p (prop, string);
4397
4398 return 0;
4399 }
4400
4401
4402 /* Determine from which buffer position in W's buffer STRING comes
4403 from. AROUND_CHARPOS is an approximate position where it could
4404 be from. Value is the buffer position or 0 if it couldn't be
4405 determined.
4406
4407 W's buffer must be current.
4408
4409 This function is necessary because we don't record buffer positions
4410 in glyphs generated from strings (to keep struct glyph small).
4411 This function may only use code that doesn't eval because it is
4412 called asynchronously from note_mouse_highlight. */
4413
4414 int
4415 string_buffer_position (w, string, around_charpos)
4416 struct window *w;
4417 Lisp_Object string;
4418 int around_charpos;
4419 {
4420 Lisp_Object limit, prop, pos;
4421 const int MAX_DISTANCE = 1000;
4422 int found = 0;
4423
4424 pos = make_number (around_charpos);
4425 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4426 while (!found && !EQ (pos, limit))
4427 {
4428 prop = Fget_char_property (pos, Qdisplay, Qnil);
4429 if (!NILP (prop) && display_prop_string_p (prop, string))
4430 found = 1;
4431 else
4432 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4433 }
4434
4435 if (!found)
4436 {
4437 pos = make_number (around_charpos);
4438 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4439 while (!found && !EQ (pos, limit))
4440 {
4441 prop = Fget_char_property (pos, Qdisplay, Qnil);
4442 if (!NILP (prop) && display_prop_string_p (prop, string))
4443 found = 1;
4444 else
4445 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4446 limit);
4447 }
4448 }
4449
4450 return found ? XINT (pos) : 0;
4451 }
4452
4453
4454 \f
4455 /***********************************************************************
4456 `composition' property
4457 ***********************************************************************/
4458
4459 /* Set up iterator IT from `composition' property at its current
4460 position. Called from handle_stop. */
4461
4462 static enum prop_handled
4463 handle_composition_prop (it)
4464 struct it *it;
4465 {
4466 Lisp_Object prop, string;
4467 int pos, pos_byte, end;
4468 enum prop_handled handled = HANDLED_NORMALLY;
4469
4470 if (STRINGP (it->string))
4471 {
4472 pos = IT_STRING_CHARPOS (*it);
4473 pos_byte = IT_STRING_BYTEPOS (*it);
4474 string = it->string;
4475 }
4476 else
4477 {
4478 pos = IT_CHARPOS (*it);
4479 pos_byte = IT_BYTEPOS (*it);
4480 string = Qnil;
4481 }
4482
4483 /* If there's a valid composition and point is not inside of the
4484 composition (in the case that the composition is from the current
4485 buffer), draw a glyph composed from the composition components. */
4486 if (find_composition (pos, -1, &pos, &end, &prop, string)
4487 && COMPOSITION_VALID_P (pos, end, prop)
4488 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4489 {
4490 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4491
4492 if (id >= 0)
4493 {
4494 struct composition *cmp = composition_table[id];
4495
4496 if (cmp->glyph_len == 0)
4497 {
4498 /* No glyph. */
4499 if (STRINGP (it->string))
4500 {
4501 IT_STRING_CHARPOS (*it) = end;
4502 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string,
4503 end);
4504 }
4505 else
4506 {
4507 IT_CHARPOS (*it) = end;
4508 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end);
4509 }
4510 return HANDLED_RECOMPUTE_PROPS;
4511 }
4512
4513 it->stop_charpos = end;
4514 push_it (it);
4515
4516 it->method = GET_FROM_COMPOSITION;
4517 it->cmp_id = id;
4518 it->cmp_len = COMPOSITION_LENGTH (prop);
4519 /* For a terminal, draw only the first character of the
4520 components. */
4521 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4522 it->len = (STRINGP (it->string)
4523 ? string_char_to_byte (it->string, end)
4524 : CHAR_TO_BYTE (end)) - pos_byte;
4525 handled = HANDLED_RETURN;
4526 }
4527 }
4528
4529 return handled;
4530 }
4531
4532
4533 \f
4534 /***********************************************************************
4535 Overlay strings
4536 ***********************************************************************/
4537
4538 /* The following structure is used to record overlay strings for
4539 later sorting in load_overlay_strings. */
4540
4541 struct overlay_entry
4542 {
4543 Lisp_Object overlay;
4544 Lisp_Object string;
4545 int priority;
4546 int after_string_p;
4547 };
4548
4549
4550 /* Set up iterator IT from overlay strings at its current position.
4551 Called from handle_stop. */
4552
4553 static enum prop_handled
4554 handle_overlay_change (it)
4555 struct it *it;
4556 {
4557 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4558 return HANDLED_RECOMPUTE_PROPS;
4559 else
4560 return HANDLED_NORMALLY;
4561 }
4562
4563
4564 /* Set up the next overlay string for delivery by IT, if there is an
4565 overlay string to deliver. Called by set_iterator_to_next when the
4566 end of the current overlay string is reached. If there are more
4567 overlay strings to display, IT->string and
4568 IT->current.overlay_string_index are set appropriately here.
4569 Otherwise IT->string is set to nil. */
4570
4571 static void
4572 next_overlay_string (it)
4573 struct it *it;
4574 {
4575 ++it->current.overlay_string_index;
4576 if (it->current.overlay_string_index == it->n_overlay_strings)
4577 {
4578 /* No more overlay strings. Restore IT's settings to what
4579 they were before overlay strings were processed, and
4580 continue to deliver from current_buffer. */
4581 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4582
4583 pop_it (it);
4584 xassert (it->sp > 0
4585 || it->method == GET_FROM_COMPOSITION
4586 || (NILP (it->string)
4587 && it->method == GET_FROM_BUFFER
4588 && it->stop_charpos >= BEGV
4589 && it->stop_charpos <= it->end_charpos));
4590 it->current.overlay_string_index = -1;
4591 it->n_overlay_strings = 0;
4592
4593 /* If we're at the end of the buffer, record that we have
4594 processed the overlay strings there already, so that
4595 next_element_from_buffer doesn't try it again. */
4596 if (IT_CHARPOS (*it) >= it->end_charpos)
4597 it->overlay_strings_at_end_processed_p = 1;
4598
4599 /* If we have to display `...' for invisible text, set
4600 the iterator up for that. */
4601 if (display_ellipsis_p)
4602 setup_for_ellipsis (it, 0);
4603 }
4604 else
4605 {
4606 /* There are more overlay strings to process. If
4607 IT->current.overlay_string_index has advanced to a position
4608 where we must load IT->overlay_strings with more strings, do
4609 it. */
4610 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4611
4612 if (it->current.overlay_string_index && i == 0)
4613 load_overlay_strings (it, 0);
4614
4615 /* Initialize IT to deliver display elements from the overlay
4616 string. */
4617 it->string = it->overlay_strings[i];
4618 it->multibyte_p = STRING_MULTIBYTE (it->string);
4619 SET_TEXT_POS (it->current.string_pos, 0, 0);
4620 it->method = GET_FROM_STRING;
4621 it->stop_charpos = 0;
4622 }
4623
4624 CHECK_IT (it);
4625 }
4626
4627
4628 /* Compare two overlay_entry structures E1 and E2. Used as a
4629 comparison function for qsort in load_overlay_strings. Overlay
4630 strings for the same position are sorted so that
4631
4632 1. All after-strings come in front of before-strings, except
4633 when they come from the same overlay.
4634
4635 2. Within after-strings, strings are sorted so that overlay strings
4636 from overlays with higher priorities come first.
4637
4638 2. Within before-strings, strings are sorted so that overlay
4639 strings from overlays with higher priorities come last.
4640
4641 Value is analogous to strcmp. */
4642
4643
4644 static int
4645 compare_overlay_entries (e1, e2)
4646 void *e1, *e2;
4647 {
4648 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4649 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4650 int result;
4651
4652 if (entry1->after_string_p != entry2->after_string_p)
4653 {
4654 /* Let after-strings appear in front of before-strings if
4655 they come from different overlays. */
4656 if (EQ (entry1->overlay, entry2->overlay))
4657 result = entry1->after_string_p ? 1 : -1;
4658 else
4659 result = entry1->after_string_p ? -1 : 1;
4660 }
4661 else if (entry1->after_string_p)
4662 /* After-strings sorted in order of decreasing priority. */
4663 result = entry2->priority - entry1->priority;
4664 else
4665 /* Before-strings sorted in order of increasing priority. */
4666 result = entry1->priority - entry2->priority;
4667
4668 return result;
4669 }
4670
4671
4672 /* Load the vector IT->overlay_strings with overlay strings from IT's
4673 current buffer position, or from CHARPOS if that is > 0. Set
4674 IT->n_overlays to the total number of overlay strings found.
4675
4676 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4677 a time. On entry into load_overlay_strings,
4678 IT->current.overlay_string_index gives the number of overlay
4679 strings that have already been loaded by previous calls to this
4680 function.
4681
4682 IT->add_overlay_start contains an additional overlay start
4683 position to consider for taking overlay strings from, if non-zero.
4684 This position comes into play when the overlay has an `invisible'
4685 property, and both before and after-strings. When we've skipped to
4686 the end of the overlay, because of its `invisible' property, we
4687 nevertheless want its before-string to appear.
4688 IT->add_overlay_start will contain the overlay start position
4689 in this case.
4690
4691 Overlay strings are sorted so that after-string strings come in
4692 front of before-string strings. Within before and after-strings,
4693 strings are sorted by overlay priority. See also function
4694 compare_overlay_entries. */
4695
4696 static void
4697 load_overlay_strings (it, charpos)
4698 struct it *it;
4699 int charpos;
4700 {
4701 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4702 Lisp_Object overlay, window, str, invisible;
4703 struct Lisp_Overlay *ov;
4704 int start, end;
4705 int size = 20;
4706 int n = 0, i, j, invis_p;
4707 struct overlay_entry *entries
4708 = (struct overlay_entry *) alloca (size * sizeof *entries);
4709
4710 if (charpos <= 0)
4711 charpos = IT_CHARPOS (*it);
4712
4713 /* Append the overlay string STRING of overlay OVERLAY to vector
4714 `entries' which has size `size' and currently contains `n'
4715 elements. AFTER_P non-zero means STRING is an after-string of
4716 OVERLAY. */
4717 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4718 do \
4719 { \
4720 Lisp_Object priority; \
4721 \
4722 if (n == size) \
4723 { \
4724 int new_size = 2 * size; \
4725 struct overlay_entry *old = entries; \
4726 entries = \
4727 (struct overlay_entry *) alloca (new_size \
4728 * sizeof *entries); \
4729 bcopy (old, entries, size * sizeof *entries); \
4730 size = new_size; \
4731 } \
4732 \
4733 entries[n].string = (STRING); \
4734 entries[n].overlay = (OVERLAY); \
4735 priority = Foverlay_get ((OVERLAY), Qpriority); \
4736 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4737 entries[n].after_string_p = (AFTER_P); \
4738 ++n; \
4739 } \
4740 while (0)
4741
4742 /* Process overlay before the overlay center. */
4743 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4744 {
4745 XSETMISC (overlay, ov);
4746 xassert (OVERLAYP (overlay));
4747 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4748 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4749
4750 if (end < charpos)
4751 break;
4752
4753 /* Skip this overlay if it doesn't start or end at IT's current
4754 position. */
4755 if (end != charpos && start != charpos)
4756 continue;
4757
4758 /* Skip this overlay if it doesn't apply to IT->w. */
4759 window = Foverlay_get (overlay, Qwindow);
4760 if (WINDOWP (window) && XWINDOW (window) != it->w)
4761 continue;
4762
4763 /* If the text ``under'' the overlay is invisible, both before-
4764 and after-strings from this overlay are visible; start and
4765 end position are indistinguishable. */
4766 invisible = Foverlay_get (overlay, Qinvisible);
4767 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4768
4769 /* If overlay has a non-empty before-string, record it. */
4770 if ((start == charpos || (end == charpos && invis_p))
4771 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4772 && SCHARS (str))
4773 RECORD_OVERLAY_STRING (overlay, str, 0);
4774
4775 /* If overlay has a non-empty after-string, record it. */
4776 if ((end == charpos || (start == charpos && invis_p))
4777 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4778 && SCHARS (str))
4779 RECORD_OVERLAY_STRING (overlay, str, 1);
4780 }
4781
4782 /* Process overlays after the overlay center. */
4783 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4784 {
4785 XSETMISC (overlay, ov);
4786 xassert (OVERLAYP (overlay));
4787 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4788 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4789
4790 if (start > charpos)
4791 break;
4792
4793 /* Skip this overlay if it doesn't start or end at IT's current
4794 position. */
4795 if (end != charpos && start != charpos)
4796 continue;
4797
4798 /* Skip this overlay if it doesn't apply to IT->w. */
4799 window = Foverlay_get (overlay, Qwindow);
4800 if (WINDOWP (window) && XWINDOW (window) != it->w)
4801 continue;
4802
4803 /* If the text ``under'' the overlay is invisible, it has a zero
4804 dimension, and both before- and after-strings apply. */
4805 invisible = Foverlay_get (overlay, Qinvisible);
4806 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4807
4808 /* If overlay has a non-empty before-string, record it. */
4809 if ((start == charpos || (end == charpos && invis_p))
4810 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4811 && SCHARS (str))
4812 RECORD_OVERLAY_STRING (overlay, str, 0);
4813
4814 /* If overlay has a non-empty after-string, record it. */
4815 if ((end == charpos || (start == charpos && invis_p))
4816 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4817 && SCHARS (str))
4818 RECORD_OVERLAY_STRING (overlay, str, 1);
4819 }
4820
4821 #undef RECORD_OVERLAY_STRING
4822
4823 /* Sort entries. */
4824 if (n > 1)
4825 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4826
4827 /* Record the total number of strings to process. */
4828 it->n_overlay_strings = n;
4829
4830 /* IT->current.overlay_string_index is the number of overlay strings
4831 that have already been consumed by IT. Copy some of the
4832 remaining overlay strings to IT->overlay_strings. */
4833 i = 0;
4834 j = it->current.overlay_string_index;
4835 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4836 it->overlay_strings[i++] = entries[j++].string;
4837
4838 CHECK_IT (it);
4839 }
4840
4841
4842 /* Get the first chunk of overlay strings at IT's current buffer
4843 position, or at CHARPOS if that is > 0. Value is non-zero if at
4844 least one overlay string was found. */
4845
4846 static int
4847 get_overlay_strings_1 (it, charpos, compute_stop_p)
4848 struct it *it;
4849 int charpos;
4850 {
4851 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4852 process. This fills IT->overlay_strings with strings, and sets
4853 IT->n_overlay_strings to the total number of strings to process.
4854 IT->pos.overlay_string_index has to be set temporarily to zero
4855 because load_overlay_strings needs this; it must be set to -1
4856 when no overlay strings are found because a zero value would
4857 indicate a position in the first overlay string. */
4858 it->current.overlay_string_index = 0;
4859 load_overlay_strings (it, charpos);
4860
4861 /* If we found overlay strings, set up IT to deliver display
4862 elements from the first one. Otherwise set up IT to deliver
4863 from current_buffer. */
4864 if (it->n_overlay_strings)
4865 {
4866 /* Make sure we know settings in current_buffer, so that we can
4867 restore meaningful values when we're done with the overlay
4868 strings. */
4869 if (compute_stop_p)
4870 compute_stop_pos (it);
4871 xassert (it->face_id >= 0);
4872
4873 /* Save IT's settings. They are restored after all overlay
4874 strings have been processed. */
4875 xassert (!compute_stop_p || it->sp == 0);
4876 push_it (it);
4877
4878 /* Set up IT to deliver display elements from the first overlay
4879 string. */
4880 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4881 it->string = it->overlay_strings[0];
4882 it->stop_charpos = 0;
4883 xassert (STRINGP (it->string));
4884 it->end_charpos = SCHARS (it->string);
4885 it->multibyte_p = STRING_MULTIBYTE (it->string);
4886 it->method = GET_FROM_STRING;
4887 return 1;
4888 }
4889
4890 it->current.overlay_string_index = -1;
4891 return 0;
4892 }
4893
4894 static int
4895 get_overlay_strings (it, charpos)
4896 struct it *it;
4897 int charpos;
4898 {
4899 it->string = Qnil;
4900 it->method = GET_FROM_BUFFER;
4901
4902 (void) get_overlay_strings_1 (it, charpos, 1);
4903
4904 CHECK_IT (it);
4905
4906 /* Value is non-zero if we found at least one overlay string. */
4907 return STRINGP (it->string);
4908 }
4909
4910
4911 \f
4912 /***********************************************************************
4913 Saving and restoring state
4914 ***********************************************************************/
4915
4916 /* Save current settings of IT on IT->stack. Called, for example,
4917 before setting up IT for an overlay string, to be able to restore
4918 IT's settings to what they were after the overlay string has been
4919 processed. */
4920
4921 static void
4922 push_it (it)
4923 struct it *it;
4924 {
4925 struct iterator_stack_entry *p;
4926
4927 xassert (it->sp < IT_STACK_SIZE);
4928 p = it->stack + it->sp;
4929
4930 p->stop_charpos = it->stop_charpos;
4931 xassert (it->face_id >= 0);
4932 p->face_id = it->face_id;
4933 p->string = it->string;
4934 p->method = it->method;
4935 switch (p->method)
4936 {
4937 case GET_FROM_IMAGE:
4938 p->u.image.object = it->object;
4939 p->u.image.image_id = it->image_id;
4940 p->u.image.slice = it->slice;
4941 break;
4942 case GET_FROM_COMPOSITION:
4943 p->u.comp.object = it->object;
4944 p->u.comp.c = it->c;
4945 p->u.comp.len = it->len;
4946 p->u.comp.cmp_id = it->cmp_id;
4947 p->u.comp.cmp_len = it->cmp_len;
4948 break;
4949 case GET_FROM_STRETCH:
4950 p->u.stretch.object = it->object;
4951 break;
4952 }
4953 p->position = it->position;
4954 p->current = it->current;
4955 p->end_charpos = it->end_charpos;
4956 p->string_nchars = it->string_nchars;
4957 p->area = it->area;
4958 p->multibyte_p = it->multibyte_p;
4959 p->space_width = it->space_width;
4960 p->font_height = it->font_height;
4961 p->voffset = it->voffset;
4962 p->string_from_display_prop_p = it->string_from_display_prop_p;
4963 p->display_ellipsis_p = 0;
4964 ++it->sp;
4965 }
4966
4967
4968 /* Restore IT's settings from IT->stack. Called, for example, when no
4969 more overlay strings must be processed, and we return to delivering
4970 display elements from a buffer, or when the end of a string from a
4971 `display' property is reached and we return to delivering display
4972 elements from an overlay string, or from a buffer. */
4973
4974 static void
4975 pop_it (it)
4976 struct it *it;
4977 {
4978 struct iterator_stack_entry *p;
4979
4980 xassert (it->sp > 0);
4981 --it->sp;
4982 p = it->stack + it->sp;
4983 it->stop_charpos = p->stop_charpos;
4984 it->face_id = p->face_id;
4985 it->current = p->current;
4986 it->position = p->position;
4987 it->string = p->string;
4988 if (NILP (it->string))
4989 SET_TEXT_POS (it->current.string_pos, -1, -1);
4990 it->method = p->method;
4991 switch (it->method)
4992 {
4993 case GET_FROM_IMAGE:
4994 it->image_id = p->u.image.image_id;
4995 it->object = p->u.image.object;
4996 it->slice = p->u.image.slice;
4997 break;
4998 case GET_FROM_COMPOSITION:
4999 it->object = p->u.comp.object;
5000 it->c = p->u.comp.c;
5001 it->len = p->u.comp.len;
5002 it->cmp_id = p->u.comp.cmp_id;
5003 it->cmp_len = p->u.comp.cmp_len;
5004 break;
5005 case GET_FROM_STRETCH:
5006 it->object = p->u.comp.object;
5007 break;
5008 case GET_FROM_BUFFER:
5009 it->object = it->w->buffer;
5010 break;
5011 case GET_FROM_STRING:
5012 it->object = it->string;
5013 break;
5014 }
5015 it->end_charpos = p->end_charpos;
5016 it->string_nchars = p->string_nchars;
5017 it->area = p->area;
5018 it->multibyte_p = p->multibyte_p;
5019 it->space_width = p->space_width;
5020 it->font_height = p->font_height;
5021 it->voffset = p->voffset;
5022 it->string_from_display_prop_p = p->string_from_display_prop_p;
5023 }
5024
5025
5026 \f
5027 /***********************************************************************
5028 Moving over lines
5029 ***********************************************************************/
5030
5031 /* Set IT's current position to the previous line start. */
5032
5033 static void
5034 back_to_previous_line_start (it)
5035 struct it *it;
5036 {
5037 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5038 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5039 }
5040
5041
5042 /* Move IT to the next line start.
5043
5044 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5045 we skipped over part of the text (as opposed to moving the iterator
5046 continuously over the text). Otherwise, don't change the value
5047 of *SKIPPED_P.
5048
5049 Newlines may come from buffer text, overlay strings, or strings
5050 displayed via the `display' property. That's the reason we can't
5051 simply use find_next_newline_no_quit.
5052
5053 Note that this function may not skip over invisible text that is so
5054 because of text properties and immediately follows a newline. If
5055 it would, function reseat_at_next_visible_line_start, when called
5056 from set_iterator_to_next, would effectively make invisible
5057 characters following a newline part of the wrong glyph row, which
5058 leads to wrong cursor motion. */
5059
5060 static int
5061 forward_to_next_line_start (it, skipped_p)
5062 struct it *it;
5063 int *skipped_p;
5064 {
5065 int old_selective, newline_found_p, n;
5066 const int MAX_NEWLINE_DISTANCE = 500;
5067
5068 /* If already on a newline, just consume it to avoid unintended
5069 skipping over invisible text below. */
5070 if (it->what == IT_CHARACTER
5071 && it->c == '\n'
5072 && CHARPOS (it->position) == IT_CHARPOS (*it))
5073 {
5074 set_iterator_to_next (it, 0);
5075 it->c = 0;
5076 return 1;
5077 }
5078
5079 /* Don't handle selective display in the following. It's (a)
5080 unnecessary because it's done by the caller, and (b) leads to an
5081 infinite recursion because next_element_from_ellipsis indirectly
5082 calls this function. */
5083 old_selective = it->selective;
5084 it->selective = 0;
5085
5086 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5087 from buffer text. */
5088 for (n = newline_found_p = 0;
5089 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5090 n += STRINGP (it->string) ? 0 : 1)
5091 {
5092 if (!get_next_display_element (it))
5093 return 0;
5094 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5095 set_iterator_to_next (it, 0);
5096 }
5097
5098 /* If we didn't find a newline near enough, see if we can use a
5099 short-cut. */
5100 if (!newline_found_p)
5101 {
5102 int start = IT_CHARPOS (*it);
5103 int limit = find_next_newline_no_quit (start, 1);
5104 Lisp_Object pos;
5105
5106 xassert (!STRINGP (it->string));
5107
5108 /* If there isn't any `display' property in sight, and no
5109 overlays, we can just use the position of the newline in
5110 buffer text. */
5111 if (it->stop_charpos >= limit
5112 || ((pos = Fnext_single_property_change (make_number (start),
5113 Qdisplay,
5114 Qnil, make_number (limit)),
5115 NILP (pos))
5116 && next_overlay_change (start) == ZV))
5117 {
5118 IT_CHARPOS (*it) = limit;
5119 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5120 *skipped_p = newline_found_p = 1;
5121 }
5122 else
5123 {
5124 while (get_next_display_element (it)
5125 && !newline_found_p)
5126 {
5127 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5128 set_iterator_to_next (it, 0);
5129 }
5130 }
5131 }
5132
5133 it->selective = old_selective;
5134 return newline_found_p;
5135 }
5136
5137
5138 /* Set IT's current position to the previous visible line start. Skip
5139 invisible text that is so either due to text properties or due to
5140 selective display. Caution: this does not change IT->current_x and
5141 IT->hpos. */
5142
5143 static void
5144 back_to_previous_visible_line_start (it)
5145 struct it *it;
5146 {
5147 while (IT_CHARPOS (*it) > BEGV)
5148 {
5149 back_to_previous_line_start (it);
5150
5151 if (IT_CHARPOS (*it) <= BEGV)
5152 break;
5153
5154 /* If selective > 0, then lines indented more than that values
5155 are invisible. */
5156 if (it->selective > 0
5157 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5158 (double) it->selective)) /* iftc */
5159 continue;
5160
5161 /* Check the newline before point for invisibility. */
5162 {
5163 Lisp_Object prop;
5164 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5165 Qinvisible, it->window);
5166 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5167 continue;
5168 }
5169
5170 if (IT_CHARPOS (*it) <= BEGV)
5171 break;
5172
5173 {
5174 struct it it2;
5175 int pos;
5176 int beg, end;
5177 Lisp_Object val, overlay;
5178
5179 /* If newline is part of a composition, continue from start of composition */
5180 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5181 && beg < IT_CHARPOS (*it))
5182 goto replaced;
5183
5184 /* If newline is replaced by a display property, find start of overlay
5185 or interval and continue search from that point. */
5186 it2 = *it;
5187 pos = --IT_CHARPOS (it2);
5188 --IT_BYTEPOS (it2);
5189 it2.sp = 0;
5190 if (handle_display_prop (&it2) == HANDLED_RETURN
5191 && !NILP (val = get_char_property_and_overlay
5192 (make_number (pos), Qdisplay, Qnil, &overlay))
5193 && (OVERLAYP (overlay)
5194 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5195 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5196 goto replaced;
5197
5198 /* Newline is not replaced by anything -- so we are done. */
5199 break;
5200
5201 replaced:
5202 if (beg < BEGV)
5203 beg = BEGV;
5204 IT_CHARPOS (*it) = beg;
5205 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5206 }
5207 }
5208
5209 it->continuation_lines_width = 0;
5210
5211 xassert (IT_CHARPOS (*it) >= BEGV);
5212 xassert (IT_CHARPOS (*it) == BEGV
5213 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5214 CHECK_IT (it);
5215 }
5216
5217
5218 /* Reseat iterator IT at the previous visible line start. Skip
5219 invisible text that is so either due to text properties or due to
5220 selective display. At the end, update IT's overlay information,
5221 face information etc. */
5222
5223 void
5224 reseat_at_previous_visible_line_start (it)
5225 struct it *it;
5226 {
5227 back_to_previous_visible_line_start (it);
5228 reseat (it, it->current.pos, 1);
5229 CHECK_IT (it);
5230 }
5231
5232
5233 /* Reseat iterator IT on the next visible line start in the current
5234 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5235 preceding the line start. Skip over invisible text that is so
5236 because of selective display. Compute faces, overlays etc at the
5237 new position. Note that this function does not skip over text that
5238 is invisible because of text properties. */
5239
5240 static void
5241 reseat_at_next_visible_line_start (it, on_newline_p)
5242 struct it *it;
5243 int on_newline_p;
5244 {
5245 int newline_found_p, skipped_p = 0;
5246
5247 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5248
5249 /* Skip over lines that are invisible because they are indented
5250 more than the value of IT->selective. */
5251 if (it->selective > 0)
5252 while (IT_CHARPOS (*it) < ZV
5253 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5254 (double) it->selective)) /* iftc */
5255 {
5256 xassert (IT_BYTEPOS (*it) == BEGV
5257 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5258 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5259 }
5260
5261 /* Position on the newline if that's what's requested. */
5262 if (on_newline_p && newline_found_p)
5263 {
5264 if (STRINGP (it->string))
5265 {
5266 if (IT_STRING_CHARPOS (*it) > 0)
5267 {
5268 --IT_STRING_CHARPOS (*it);
5269 --IT_STRING_BYTEPOS (*it);
5270 }
5271 }
5272 else if (IT_CHARPOS (*it) > BEGV)
5273 {
5274 --IT_CHARPOS (*it);
5275 --IT_BYTEPOS (*it);
5276 reseat (it, it->current.pos, 0);
5277 }
5278 }
5279 else if (skipped_p)
5280 reseat (it, it->current.pos, 0);
5281
5282 CHECK_IT (it);
5283 }
5284
5285
5286 \f
5287 /***********************************************************************
5288 Changing an iterator's position
5289 ***********************************************************************/
5290
5291 /* Change IT's current position to POS in current_buffer. If FORCE_P
5292 is non-zero, always check for text properties at the new position.
5293 Otherwise, text properties are only looked up if POS >=
5294 IT->check_charpos of a property. */
5295
5296 static void
5297 reseat (it, pos, force_p)
5298 struct it *it;
5299 struct text_pos pos;
5300 int force_p;
5301 {
5302 int original_pos = IT_CHARPOS (*it);
5303
5304 reseat_1 (it, pos, 0);
5305
5306 /* Determine where to check text properties. Avoid doing it
5307 where possible because text property lookup is very expensive. */
5308 if (force_p
5309 || CHARPOS (pos) > it->stop_charpos
5310 || CHARPOS (pos) < original_pos)
5311 handle_stop (it);
5312
5313 CHECK_IT (it);
5314 }
5315
5316
5317 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5318 IT->stop_pos to POS, also. */
5319
5320 static void
5321 reseat_1 (it, pos, set_stop_p)
5322 struct it *it;
5323 struct text_pos pos;
5324 int set_stop_p;
5325 {
5326 /* Don't call this function when scanning a C string. */
5327 xassert (it->s == NULL);
5328
5329 /* POS must be a reasonable value. */
5330 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5331
5332 it->current.pos = it->position = pos;
5333 it->end_charpos = ZV;
5334 it->dpvec = NULL;
5335 it->current.dpvec_index = -1;
5336 it->current.overlay_string_index = -1;
5337 IT_STRING_CHARPOS (*it) = -1;
5338 IT_STRING_BYTEPOS (*it) = -1;
5339 it->string = Qnil;
5340 it->method = GET_FROM_BUFFER;
5341 it->object = it->w->buffer;
5342 it->area = TEXT_AREA;
5343 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5344 it->sp = 0;
5345 it->string_from_display_prop_p = 0;
5346 it->face_before_selective_p = 0;
5347
5348 if (set_stop_p)
5349 it->stop_charpos = CHARPOS (pos);
5350 }
5351
5352
5353 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5354 If S is non-null, it is a C string to iterate over. Otherwise,
5355 STRING gives a Lisp string to iterate over.
5356
5357 If PRECISION > 0, don't return more then PRECISION number of
5358 characters from the string.
5359
5360 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5361 characters have been returned. FIELD_WIDTH < 0 means an infinite
5362 field width.
5363
5364 MULTIBYTE = 0 means disable processing of multibyte characters,
5365 MULTIBYTE > 0 means enable it,
5366 MULTIBYTE < 0 means use IT->multibyte_p.
5367
5368 IT must be initialized via a prior call to init_iterator before
5369 calling this function. */
5370
5371 static void
5372 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5373 struct it *it;
5374 unsigned char *s;
5375 Lisp_Object string;
5376 int charpos;
5377 int precision, field_width, multibyte;
5378 {
5379 /* No region in strings. */
5380 it->region_beg_charpos = it->region_end_charpos = -1;
5381
5382 /* No text property checks performed by default, but see below. */
5383 it->stop_charpos = -1;
5384
5385 /* Set iterator position and end position. */
5386 bzero (&it->current, sizeof it->current);
5387 it->current.overlay_string_index = -1;
5388 it->current.dpvec_index = -1;
5389 xassert (charpos >= 0);
5390
5391 /* If STRING is specified, use its multibyteness, otherwise use the
5392 setting of MULTIBYTE, if specified. */
5393 if (multibyte >= 0)
5394 it->multibyte_p = multibyte > 0;
5395
5396 if (s == NULL)
5397 {
5398 xassert (STRINGP (string));
5399 it->string = string;
5400 it->s = NULL;
5401 it->end_charpos = it->string_nchars = SCHARS (string);
5402 it->method = GET_FROM_STRING;
5403 it->current.string_pos = string_pos (charpos, string);
5404 }
5405 else
5406 {
5407 it->s = s;
5408 it->string = Qnil;
5409
5410 /* Note that we use IT->current.pos, not it->current.string_pos,
5411 for displaying C strings. */
5412 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5413 if (it->multibyte_p)
5414 {
5415 it->current.pos = c_string_pos (charpos, s, 1);
5416 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5417 }
5418 else
5419 {
5420 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5421 it->end_charpos = it->string_nchars = strlen (s);
5422 }
5423
5424 it->method = GET_FROM_C_STRING;
5425 }
5426
5427 /* PRECISION > 0 means don't return more than PRECISION characters
5428 from the string. */
5429 if (precision > 0 && it->end_charpos - charpos > precision)
5430 it->end_charpos = it->string_nchars = charpos + precision;
5431
5432 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5433 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5434 FIELD_WIDTH < 0 means infinite field width. This is useful for
5435 padding with `-' at the end of a mode line. */
5436 if (field_width < 0)
5437 field_width = INFINITY;
5438 if (field_width > it->end_charpos - charpos)
5439 it->end_charpos = charpos + field_width;
5440
5441 /* Use the standard display table for displaying strings. */
5442 if (DISP_TABLE_P (Vstandard_display_table))
5443 it->dp = XCHAR_TABLE (Vstandard_display_table);
5444
5445 it->stop_charpos = charpos;
5446 CHECK_IT (it);
5447 }
5448
5449
5450 \f
5451 /***********************************************************************
5452 Iteration
5453 ***********************************************************************/
5454
5455 /* Map enum it_method value to corresponding next_element_from_* function. */
5456
5457 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5458 {
5459 next_element_from_buffer,
5460 next_element_from_display_vector,
5461 next_element_from_composition,
5462 next_element_from_string,
5463 next_element_from_c_string,
5464 next_element_from_image,
5465 next_element_from_stretch
5466 };
5467
5468
5469 /* Load IT's display element fields with information about the next
5470 display element from the current position of IT. Value is zero if
5471 end of buffer (or C string) is reached. */
5472
5473 static struct frame *last_escape_glyph_frame = NULL;
5474 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5475 static int last_escape_glyph_merged_face_id = 0;
5476
5477 int
5478 get_next_display_element (it)
5479 struct it *it;
5480 {
5481 /* Non-zero means that we found a display element. Zero means that
5482 we hit the end of what we iterate over. Performance note: the
5483 function pointer `method' used here turns out to be faster than
5484 using a sequence of if-statements. */
5485 int success_p;
5486
5487 get_next:
5488 success_p = (*get_next_element[it->method]) (it);
5489
5490 if (it->what == IT_CHARACTER)
5491 {
5492 /* Map via display table or translate control characters.
5493 IT->c, IT->len etc. have been set to the next character by
5494 the function call above. If we have a display table, and it
5495 contains an entry for IT->c, translate it. Don't do this if
5496 IT->c itself comes from a display table, otherwise we could
5497 end up in an infinite recursion. (An alternative could be to
5498 count the recursion depth of this function and signal an
5499 error when a certain maximum depth is reached.) Is it worth
5500 it? */
5501 if (success_p && it->dpvec == NULL)
5502 {
5503 Lisp_Object dv;
5504
5505 if (it->dp
5506 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5507 VECTORP (dv)))
5508 {
5509 struct Lisp_Vector *v = XVECTOR (dv);
5510
5511 /* Return the first character from the display table
5512 entry, if not empty. If empty, don't display the
5513 current character. */
5514 if (v->size)
5515 {
5516 it->dpvec_char_len = it->len;
5517 it->dpvec = v->contents;
5518 it->dpend = v->contents + v->size;
5519 it->current.dpvec_index = 0;
5520 it->dpvec_face_id = -1;
5521 it->saved_face_id = it->face_id;
5522 it->method = GET_FROM_DISPLAY_VECTOR;
5523 it->ellipsis_p = 0;
5524 }
5525 else
5526 {
5527 set_iterator_to_next (it, 0);
5528 }
5529 goto get_next;
5530 }
5531
5532 /* Translate control characters into `\003' or `^C' form.
5533 Control characters coming from a display table entry are
5534 currently not translated because we use IT->dpvec to hold
5535 the translation. This could easily be changed but I
5536 don't believe that it is worth doing.
5537
5538 If it->multibyte_p is nonzero, eight-bit characters and
5539 non-printable multibyte characters are also translated to
5540 octal form.
5541
5542 If it->multibyte_p is zero, eight-bit characters that
5543 don't have corresponding multibyte char code are also
5544 translated to octal form. */
5545 else if ((it->c < ' '
5546 && (it->area != TEXT_AREA
5547 /* In mode line, treat \n like other crl chars. */
5548 || (it->c != '\t'
5549 && it->glyph_row && it->glyph_row->mode_line_p)
5550 || (it->c != '\n' && it->c != '\t')))
5551 || (it->multibyte_p
5552 ? ((it->c >= 127
5553 && it->len == 1)
5554 || !CHAR_PRINTABLE_P (it->c)
5555 || (!NILP (Vnobreak_char_display)
5556 && (it->c == 0x8a0 || it->c == 0x8ad
5557 || it->c == 0x920 || it->c == 0x92d
5558 || it->c == 0xe20 || it->c == 0xe2d
5559 || it->c == 0xf20 || it->c == 0xf2d)))
5560 : (it->c >= 127
5561 && (!unibyte_display_via_language_environment
5562 || it->c == unibyte_char_to_multibyte (it->c)))))
5563 {
5564 /* IT->c is a control character which must be displayed
5565 either as '\003' or as `^C' where the '\\' and '^'
5566 can be defined in the display table. Fill
5567 IT->ctl_chars with glyphs for what we have to
5568 display. Then, set IT->dpvec to these glyphs. */
5569 GLYPH g;
5570 int ctl_len;
5571 int face_id, lface_id = 0 ;
5572 GLYPH escape_glyph;
5573
5574 /* Handle control characters with ^. */
5575
5576 if (it->c < 128 && it->ctl_arrow_p)
5577 {
5578 g = '^'; /* default glyph for Control */
5579 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5580 if (it->dp
5581 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5582 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5583 {
5584 g = XINT (DISP_CTRL_GLYPH (it->dp));
5585 lface_id = FAST_GLYPH_FACE (g);
5586 }
5587 if (lface_id)
5588 {
5589 g = FAST_GLYPH_CHAR (g);
5590 face_id = merge_faces (it->f, Qt, lface_id,
5591 it->face_id);
5592 }
5593 else if (it->f == last_escape_glyph_frame
5594 && it->face_id == last_escape_glyph_face_id)
5595 {
5596 face_id = last_escape_glyph_merged_face_id;
5597 }
5598 else
5599 {
5600 /* Merge the escape-glyph face into the current face. */
5601 face_id = merge_faces (it->f, Qescape_glyph, 0,
5602 it->face_id);
5603 last_escape_glyph_frame = it->f;
5604 last_escape_glyph_face_id = it->face_id;
5605 last_escape_glyph_merged_face_id = face_id;
5606 }
5607
5608 XSETINT (it->ctl_chars[0], g);
5609 g = it->c ^ 0100;
5610 XSETINT (it->ctl_chars[1], g);
5611 ctl_len = 2;
5612 goto display_control;
5613 }
5614
5615 /* Handle non-break space in the mode where it only gets
5616 highlighting. */
5617
5618 if (EQ (Vnobreak_char_display, Qt)
5619 && (it->c == 0x8a0 || it->c == 0x920
5620 || it->c == 0xe20 || it->c == 0xf20))
5621 {
5622 /* Merge the no-break-space face into the current face. */
5623 face_id = merge_faces (it->f, Qnobreak_space, 0,
5624 it->face_id);
5625
5626 g = it->c = ' ';
5627 XSETINT (it->ctl_chars[0], g);
5628 ctl_len = 1;
5629 goto display_control;
5630 }
5631
5632 /* Handle sequences that start with the "escape glyph". */
5633
5634 /* the default escape glyph is \. */
5635 escape_glyph = '\\';
5636
5637 if (it->dp
5638 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5639 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5640 {
5641 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5642 lface_id = FAST_GLYPH_FACE (escape_glyph);
5643 }
5644 if (lface_id)
5645 {
5646 /* The display table specified a face.
5647 Merge it into face_id and also into escape_glyph. */
5648 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5649 face_id = merge_faces (it->f, Qt, lface_id,
5650 it->face_id);
5651 }
5652 else if (it->f == last_escape_glyph_frame
5653 && it->face_id == last_escape_glyph_face_id)
5654 {
5655 face_id = last_escape_glyph_merged_face_id;
5656 }
5657 else
5658 {
5659 /* Merge the escape-glyph face into the current face. */
5660 face_id = merge_faces (it->f, Qescape_glyph, 0,
5661 it->face_id);
5662 last_escape_glyph_frame = it->f;
5663 last_escape_glyph_face_id = it->face_id;
5664 last_escape_glyph_merged_face_id = face_id;
5665 }
5666
5667 /* Handle soft hyphens in the mode where they only get
5668 highlighting. */
5669
5670 if (EQ (Vnobreak_char_display, Qt)
5671 && (it->c == 0x8ad || it->c == 0x92d
5672 || it->c == 0xe2d || it->c == 0xf2d))
5673 {
5674 g = it->c = '-';
5675 XSETINT (it->ctl_chars[0], g);
5676 ctl_len = 1;
5677 goto display_control;
5678 }
5679
5680 /* Handle non-break space and soft hyphen
5681 with the escape glyph. */
5682
5683 if (it->c == 0x8a0 || it->c == 0x8ad
5684 || it->c == 0x920 || it->c == 0x92d
5685 || it->c == 0xe20 || it->c == 0xe2d
5686 || it->c == 0xf20 || it->c == 0xf2d)
5687 {
5688 XSETINT (it->ctl_chars[0], escape_glyph);
5689 g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-');
5690 XSETINT (it->ctl_chars[1], g);
5691 ctl_len = 2;
5692 goto display_control;
5693 }
5694
5695 {
5696 unsigned char str[MAX_MULTIBYTE_LENGTH];
5697 int len;
5698 int i;
5699
5700 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5701 if (SINGLE_BYTE_CHAR_P (it->c))
5702 str[0] = it->c, len = 1;
5703 else
5704 {
5705 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5706 if (len < 0)
5707 {
5708 /* It's an invalid character, which shouldn't
5709 happen actually, but due to bugs it may
5710 happen. Let's print the char as is, there's
5711 not much meaningful we can do with it. */
5712 str[0] = it->c;
5713 str[1] = it->c >> 8;
5714 str[2] = it->c >> 16;
5715 str[3] = it->c >> 24;
5716 len = 4;
5717 }
5718 }
5719
5720 for (i = 0; i < len; i++)
5721 {
5722 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5723 /* Insert three more glyphs into IT->ctl_chars for
5724 the octal display of the character. */
5725 g = ((str[i] >> 6) & 7) + '0';
5726 XSETINT (it->ctl_chars[i * 4 + 1], g);
5727 g = ((str[i] >> 3) & 7) + '0';
5728 XSETINT (it->ctl_chars[i * 4 + 2], g);
5729 g = (str[i] & 7) + '0';
5730 XSETINT (it->ctl_chars[i * 4 + 3], g);
5731 }
5732 ctl_len = len * 4;
5733 }
5734
5735 display_control:
5736 /* Set up IT->dpvec and return first character from it. */
5737 it->dpvec_char_len = it->len;
5738 it->dpvec = it->ctl_chars;
5739 it->dpend = it->dpvec + ctl_len;
5740 it->current.dpvec_index = 0;
5741 it->dpvec_face_id = face_id;
5742 it->saved_face_id = it->face_id;
5743 it->method = GET_FROM_DISPLAY_VECTOR;
5744 it->ellipsis_p = 0;
5745 goto get_next;
5746 }
5747 }
5748
5749 /* Adjust face id for a multibyte character. There are no
5750 multibyte character in unibyte text. */
5751 if (it->multibyte_p
5752 && success_p
5753 && FRAME_WINDOW_P (it->f))
5754 {
5755 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5756 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5757 }
5758 }
5759
5760 /* Is this character the last one of a run of characters with
5761 box? If yes, set IT->end_of_box_run_p to 1. */
5762 if (it->face_box_p
5763 && it->s == NULL)
5764 {
5765 int face_id;
5766 struct face *face;
5767
5768 it->end_of_box_run_p
5769 = ((face_id = face_after_it_pos (it),
5770 face_id != it->face_id)
5771 && (face = FACE_FROM_ID (it->f, face_id),
5772 face->box == FACE_NO_BOX));
5773 }
5774
5775 /* Value is 0 if end of buffer or string reached. */
5776 return success_p;
5777 }
5778
5779
5780 /* Move IT to the next display element.
5781
5782 RESEAT_P non-zero means if called on a newline in buffer text,
5783 skip to the next visible line start.
5784
5785 Functions get_next_display_element and set_iterator_to_next are
5786 separate because I find this arrangement easier to handle than a
5787 get_next_display_element function that also increments IT's
5788 position. The way it is we can first look at an iterator's current
5789 display element, decide whether it fits on a line, and if it does,
5790 increment the iterator position. The other way around we probably
5791 would either need a flag indicating whether the iterator has to be
5792 incremented the next time, or we would have to implement a
5793 decrement position function which would not be easy to write. */
5794
5795 void
5796 set_iterator_to_next (it, reseat_p)
5797 struct it *it;
5798 int reseat_p;
5799 {
5800 /* Reset flags indicating start and end of a sequence of characters
5801 with box. Reset them at the start of this function because
5802 moving the iterator to a new position might set them. */
5803 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5804
5805 switch (it->method)
5806 {
5807 case GET_FROM_BUFFER:
5808 /* The current display element of IT is a character from
5809 current_buffer. Advance in the buffer, and maybe skip over
5810 invisible lines that are so because of selective display. */
5811 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5812 reseat_at_next_visible_line_start (it, 0);
5813 else
5814 {
5815 xassert (it->len != 0);
5816 IT_BYTEPOS (*it) += it->len;
5817 IT_CHARPOS (*it) += 1;
5818 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5819 }
5820 break;
5821
5822 case GET_FROM_COMPOSITION:
5823 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5824 xassert (it->sp > 0);
5825 pop_it (it);
5826 if (it->method == GET_FROM_STRING)
5827 {
5828 IT_STRING_BYTEPOS (*it) += it->len;
5829 IT_STRING_CHARPOS (*it) += it->cmp_len;
5830 goto consider_string_end;
5831 }
5832 else if (it->method == GET_FROM_BUFFER)
5833 {
5834 IT_BYTEPOS (*it) += it->len;
5835 IT_CHARPOS (*it) += it->cmp_len;
5836 }
5837 break;
5838
5839 case GET_FROM_C_STRING:
5840 /* Current display element of IT is from a C string. */
5841 IT_BYTEPOS (*it) += it->len;
5842 IT_CHARPOS (*it) += 1;
5843 break;
5844
5845 case GET_FROM_DISPLAY_VECTOR:
5846 /* Current display element of IT is from a display table entry.
5847 Advance in the display table definition. Reset it to null if
5848 end reached, and continue with characters from buffers/
5849 strings. */
5850 ++it->current.dpvec_index;
5851
5852 /* Restore face of the iterator to what they were before the
5853 display vector entry (these entries may contain faces). */
5854 it->face_id = it->saved_face_id;
5855
5856 if (it->dpvec + it->current.dpvec_index == it->dpend)
5857 {
5858 int recheck_faces = it->ellipsis_p;
5859
5860 if (it->s)
5861 it->method = GET_FROM_C_STRING;
5862 else if (STRINGP (it->string))
5863 it->method = GET_FROM_STRING;
5864 else
5865 {
5866 it->method = GET_FROM_BUFFER;
5867 it->object = it->w->buffer;
5868 }
5869
5870 it->dpvec = NULL;
5871 it->current.dpvec_index = -1;
5872
5873 /* Skip over characters which were displayed via IT->dpvec. */
5874 if (it->dpvec_char_len < 0)
5875 reseat_at_next_visible_line_start (it, 1);
5876 else if (it->dpvec_char_len > 0)
5877 {
5878 if (it->method == GET_FROM_STRING
5879 && it->n_overlay_strings > 0)
5880 it->ignore_overlay_strings_at_pos_p = 1;
5881 it->len = it->dpvec_char_len;
5882 set_iterator_to_next (it, reseat_p);
5883 }
5884
5885 /* Maybe recheck faces after display vector */
5886 if (recheck_faces)
5887 it->stop_charpos = IT_CHARPOS (*it);
5888 }
5889 break;
5890
5891 case GET_FROM_STRING:
5892 /* Current display element is a character from a Lisp string. */
5893 xassert (it->s == NULL && STRINGP (it->string));
5894 IT_STRING_BYTEPOS (*it) += it->len;
5895 IT_STRING_CHARPOS (*it) += 1;
5896
5897 consider_string_end:
5898
5899 if (it->current.overlay_string_index >= 0)
5900 {
5901 /* IT->string is an overlay string. Advance to the
5902 next, if there is one. */
5903 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5904 next_overlay_string (it);
5905 }
5906 else
5907 {
5908 /* IT->string is not an overlay string. If we reached
5909 its end, and there is something on IT->stack, proceed
5910 with what is on the stack. This can be either another
5911 string, this time an overlay string, or a buffer. */
5912 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5913 && it->sp > 0)
5914 {
5915 pop_it (it);
5916 if (it->method == GET_FROM_STRING)
5917 goto consider_string_end;
5918 }
5919 }
5920 break;
5921
5922 case GET_FROM_IMAGE:
5923 case GET_FROM_STRETCH:
5924 /* The position etc with which we have to proceed are on
5925 the stack. The position may be at the end of a string,
5926 if the `display' property takes up the whole string. */
5927 xassert (it->sp > 0);
5928 pop_it (it);
5929 if (it->method == GET_FROM_STRING)
5930 goto consider_string_end;
5931 break;
5932
5933 default:
5934 /* There are no other methods defined, so this should be a bug. */
5935 abort ();
5936 }
5937
5938 xassert (it->method != GET_FROM_STRING
5939 || (STRINGP (it->string)
5940 && IT_STRING_CHARPOS (*it) >= 0));
5941 }
5942
5943 /* Load IT's display element fields with information about the next
5944 display element which comes from a display table entry or from the
5945 result of translating a control character to one of the forms `^C'
5946 or `\003'.
5947
5948 IT->dpvec holds the glyphs to return as characters.
5949 IT->saved_face_id holds the face id before the display vector--
5950 it is restored into IT->face_idin set_iterator_to_next. */
5951
5952 static int
5953 next_element_from_display_vector (it)
5954 struct it *it;
5955 {
5956 /* Precondition. */
5957 xassert (it->dpvec && it->current.dpvec_index >= 0);
5958
5959 it->face_id = it->saved_face_id;
5960
5961 if (INTEGERP (*it->dpvec)
5962 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5963 {
5964 GLYPH g;
5965
5966 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5967 it->c = FAST_GLYPH_CHAR (g);
5968 it->len = CHAR_BYTES (it->c);
5969
5970 /* The entry may contain a face id to use. Such a face id is
5971 the id of a Lisp face, not a realized face. A face id of
5972 zero means no face is specified. */
5973 if (it->dpvec_face_id >= 0)
5974 it->face_id = it->dpvec_face_id;
5975 else
5976 {
5977 int lface_id = FAST_GLYPH_FACE (g);
5978 if (lface_id > 0)
5979 it->face_id = merge_faces (it->f, Qt, lface_id,
5980 it->saved_face_id);
5981 }
5982 }
5983 else
5984 /* Display table entry is invalid. Return a space. */
5985 it->c = ' ', it->len = 1;
5986
5987 /* Don't change position and object of the iterator here. They are
5988 still the values of the character that had this display table
5989 entry or was translated, and that's what we want. */
5990 it->what = IT_CHARACTER;
5991 return 1;
5992 }
5993
5994
5995 /* Load IT with the next display element from Lisp string IT->string.
5996 IT->current.string_pos is the current position within the string.
5997 If IT->current.overlay_string_index >= 0, the Lisp string is an
5998 overlay string. */
5999
6000 static int
6001 next_element_from_string (it)
6002 struct it *it;
6003 {
6004 struct text_pos position;
6005
6006 xassert (STRINGP (it->string));
6007 xassert (IT_STRING_CHARPOS (*it) >= 0);
6008 position = it->current.string_pos;
6009
6010 /* Time to check for invisible text? */
6011 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6012 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6013 {
6014 handle_stop (it);
6015
6016 /* Since a handler may have changed IT->method, we must
6017 recurse here. */
6018 return get_next_display_element (it);
6019 }
6020
6021 if (it->current.overlay_string_index >= 0)
6022 {
6023 /* Get the next character from an overlay string. In overlay
6024 strings, There is no field width or padding with spaces to
6025 do. */
6026 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6027 {
6028 it->what = IT_EOB;
6029 return 0;
6030 }
6031 else if (STRING_MULTIBYTE (it->string))
6032 {
6033 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6034 const unsigned char *s = (SDATA (it->string)
6035 + IT_STRING_BYTEPOS (*it));
6036 it->c = string_char_and_length (s, remaining, &it->len);
6037 }
6038 else
6039 {
6040 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6041 it->len = 1;
6042 }
6043 }
6044 else
6045 {
6046 /* Get the next character from a Lisp string that is not an
6047 overlay string. Such strings come from the mode line, for
6048 example. We may have to pad with spaces, or truncate the
6049 string. See also next_element_from_c_string. */
6050 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6051 {
6052 it->what = IT_EOB;
6053 return 0;
6054 }
6055 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6056 {
6057 /* Pad with spaces. */
6058 it->c = ' ', it->len = 1;
6059 CHARPOS (position) = BYTEPOS (position) = -1;
6060 }
6061 else if (STRING_MULTIBYTE (it->string))
6062 {
6063 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6064 const unsigned char *s = (SDATA (it->string)
6065 + IT_STRING_BYTEPOS (*it));
6066 it->c = string_char_and_length (s, maxlen, &it->len);
6067 }
6068 else
6069 {
6070 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6071 it->len = 1;
6072 }
6073 }
6074
6075 /* Record what we have and where it came from. */
6076 it->what = IT_CHARACTER;
6077 it->object = it->string;
6078 it->position = position;
6079 return 1;
6080 }
6081
6082
6083 /* Load IT with next display element from C string IT->s.
6084 IT->string_nchars is the maximum number of characters to return
6085 from the string. IT->end_charpos may be greater than
6086 IT->string_nchars when this function is called, in which case we
6087 may have to return padding spaces. Value is zero if end of string
6088 reached, including padding spaces. */
6089
6090 static int
6091 next_element_from_c_string (it)
6092 struct it *it;
6093 {
6094 int success_p = 1;
6095
6096 xassert (it->s);
6097 it->what = IT_CHARACTER;
6098 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6099 it->object = Qnil;
6100
6101 /* IT's position can be greater IT->string_nchars in case a field
6102 width or precision has been specified when the iterator was
6103 initialized. */
6104 if (IT_CHARPOS (*it) >= it->end_charpos)
6105 {
6106 /* End of the game. */
6107 it->what = IT_EOB;
6108 success_p = 0;
6109 }
6110 else if (IT_CHARPOS (*it) >= it->string_nchars)
6111 {
6112 /* Pad with spaces. */
6113 it->c = ' ', it->len = 1;
6114 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6115 }
6116 else if (it->multibyte_p)
6117 {
6118 /* Implementation note: The calls to strlen apparently aren't a
6119 performance problem because there is no noticeable performance
6120 difference between Emacs running in unibyte or multibyte mode. */
6121 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6122 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
6123 maxlen, &it->len);
6124 }
6125 else
6126 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6127
6128 return success_p;
6129 }
6130
6131
6132 /* Set up IT to return characters from an ellipsis, if appropriate.
6133 The definition of the ellipsis glyphs may come from a display table
6134 entry. This function Fills IT with the first glyph from the
6135 ellipsis if an ellipsis is to be displayed. */
6136
6137 static int
6138 next_element_from_ellipsis (it)
6139 struct it *it;
6140 {
6141 if (it->selective_display_ellipsis_p)
6142 setup_for_ellipsis (it, it->len);
6143 else
6144 {
6145 /* The face at the current position may be different from the
6146 face we find after the invisible text. Remember what it
6147 was in IT->saved_face_id, and signal that it's there by
6148 setting face_before_selective_p. */
6149 it->saved_face_id = it->face_id;
6150 it->method = GET_FROM_BUFFER;
6151 it->object = it->w->buffer;
6152 reseat_at_next_visible_line_start (it, 1);
6153 it->face_before_selective_p = 1;
6154 }
6155
6156 return get_next_display_element (it);
6157 }
6158
6159
6160 /* Deliver an image display element. The iterator IT is already
6161 filled with image information (done in handle_display_prop). Value
6162 is always 1. */
6163
6164
6165 static int
6166 next_element_from_image (it)
6167 struct it *it;
6168 {
6169 it->what = IT_IMAGE;
6170 return 1;
6171 }
6172
6173
6174 /* Fill iterator IT with next display element from a stretch glyph
6175 property. IT->object is the value of the text property. Value is
6176 always 1. */
6177
6178 static int
6179 next_element_from_stretch (it)
6180 struct it *it;
6181 {
6182 it->what = IT_STRETCH;
6183 return 1;
6184 }
6185
6186
6187 /* Load IT with the next display element from current_buffer. Value
6188 is zero if end of buffer reached. IT->stop_charpos is the next
6189 position at which to stop and check for text properties or buffer
6190 end. */
6191
6192 static int
6193 next_element_from_buffer (it)
6194 struct it *it;
6195 {
6196 int success_p = 1;
6197
6198 /* Check this assumption, otherwise, we would never enter the
6199 if-statement, below. */
6200 xassert (IT_CHARPOS (*it) >= BEGV
6201 && IT_CHARPOS (*it) <= it->stop_charpos);
6202
6203 if (IT_CHARPOS (*it) >= it->stop_charpos)
6204 {
6205 if (IT_CHARPOS (*it) >= it->end_charpos)
6206 {
6207 int overlay_strings_follow_p;
6208
6209 /* End of the game, except when overlay strings follow that
6210 haven't been returned yet. */
6211 if (it->overlay_strings_at_end_processed_p)
6212 overlay_strings_follow_p = 0;
6213 else
6214 {
6215 it->overlay_strings_at_end_processed_p = 1;
6216 overlay_strings_follow_p = get_overlay_strings (it, 0);
6217 }
6218
6219 if (overlay_strings_follow_p)
6220 success_p = get_next_display_element (it);
6221 else
6222 {
6223 it->what = IT_EOB;
6224 it->position = it->current.pos;
6225 success_p = 0;
6226 }
6227 }
6228 else
6229 {
6230 handle_stop (it);
6231 return get_next_display_element (it);
6232 }
6233 }
6234 else
6235 {
6236 /* No face changes, overlays etc. in sight, so just return a
6237 character from current_buffer. */
6238 unsigned char *p;
6239
6240 /* Maybe run the redisplay end trigger hook. Performance note:
6241 This doesn't seem to cost measurable time. */
6242 if (it->redisplay_end_trigger_charpos
6243 && it->glyph_row
6244 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6245 run_redisplay_end_trigger_hook (it);
6246
6247 /* Get the next character, maybe multibyte. */
6248 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6249 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6250 {
6251 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
6252 - IT_BYTEPOS (*it));
6253 it->c = string_char_and_length (p, maxlen, &it->len);
6254 }
6255 else
6256 it->c = *p, it->len = 1;
6257
6258 /* Record what we have and where it came from. */
6259 it->what = IT_CHARACTER;
6260 it->object = it->w->buffer;
6261 it->position = it->current.pos;
6262
6263 /* Normally we return the character found above, except when we
6264 really want to return an ellipsis for selective display. */
6265 if (it->selective)
6266 {
6267 if (it->c == '\n')
6268 {
6269 /* A value of selective > 0 means hide lines indented more
6270 than that number of columns. */
6271 if (it->selective > 0
6272 && IT_CHARPOS (*it) + 1 < ZV
6273 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6274 IT_BYTEPOS (*it) + 1,
6275 (double) it->selective)) /* iftc */
6276 {
6277 success_p = next_element_from_ellipsis (it);
6278 it->dpvec_char_len = -1;
6279 }
6280 }
6281 else if (it->c == '\r' && it->selective == -1)
6282 {
6283 /* A value of selective == -1 means that everything from the
6284 CR to the end of the line is invisible, with maybe an
6285 ellipsis displayed for it. */
6286 success_p = next_element_from_ellipsis (it);
6287 it->dpvec_char_len = -1;
6288 }
6289 }
6290 }
6291
6292 /* Value is zero if end of buffer reached. */
6293 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6294 return success_p;
6295 }
6296
6297
6298 /* Run the redisplay end trigger hook for IT. */
6299
6300 static void
6301 run_redisplay_end_trigger_hook (it)
6302 struct it *it;
6303 {
6304 Lisp_Object args[3];
6305
6306 /* IT->glyph_row should be non-null, i.e. we should be actually
6307 displaying something, or otherwise we should not run the hook. */
6308 xassert (it->glyph_row);
6309
6310 /* Set up hook arguments. */
6311 args[0] = Qredisplay_end_trigger_functions;
6312 args[1] = it->window;
6313 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6314 it->redisplay_end_trigger_charpos = 0;
6315
6316 /* Since we are *trying* to run these functions, don't try to run
6317 them again, even if they get an error. */
6318 it->w->redisplay_end_trigger = Qnil;
6319 Frun_hook_with_args (3, args);
6320
6321 /* Notice if it changed the face of the character we are on. */
6322 handle_face_prop (it);
6323 }
6324
6325
6326 /* Deliver a composition display element. The iterator IT is already
6327 filled with composition information (done in
6328 handle_composition_prop). Value is always 1. */
6329
6330 static int
6331 next_element_from_composition (it)
6332 struct it *it;
6333 {
6334 it->what = IT_COMPOSITION;
6335 it->position = (STRINGP (it->string)
6336 ? it->current.string_pos
6337 : it->current.pos);
6338 if (STRINGP (it->string))
6339 it->object = it->string;
6340 else
6341 it->object = it->w->buffer;
6342 return 1;
6343 }
6344
6345
6346 \f
6347 /***********************************************************************
6348 Moving an iterator without producing glyphs
6349 ***********************************************************************/
6350
6351 /* Check if iterator is at a position corresponding to a valid buffer
6352 position after some move_it_ call. */
6353
6354 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6355 ((it)->method == GET_FROM_STRING \
6356 ? IT_STRING_CHARPOS (*it) == 0 \
6357 : 1)
6358
6359
6360 /* Move iterator IT to a specified buffer or X position within one
6361 line on the display without producing glyphs.
6362
6363 OP should be a bit mask including some or all of these bits:
6364 MOVE_TO_X: Stop on reaching x-position TO_X.
6365 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
6366 Regardless of OP's value, stop in reaching the end of the display line.
6367
6368 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6369 This means, in particular, that TO_X includes window's horizontal
6370 scroll amount.
6371
6372 The return value has several possible values that
6373 say what condition caused the scan to stop:
6374
6375 MOVE_POS_MATCH_OR_ZV
6376 - when TO_POS or ZV was reached.
6377
6378 MOVE_X_REACHED
6379 -when TO_X was reached before TO_POS or ZV were reached.
6380
6381 MOVE_LINE_CONTINUED
6382 - when we reached the end of the display area and the line must
6383 be continued.
6384
6385 MOVE_LINE_TRUNCATED
6386 - when we reached the end of the display area and the line is
6387 truncated.
6388
6389 MOVE_NEWLINE_OR_CR
6390 - when we stopped at a line end, i.e. a newline or a CR and selective
6391 display is on. */
6392
6393 static enum move_it_result
6394 move_it_in_display_line_to (it, to_charpos, to_x, op)
6395 struct it *it;
6396 int to_charpos, to_x, op;
6397 {
6398 enum move_it_result result = MOVE_UNDEFINED;
6399 struct glyph_row *saved_glyph_row;
6400
6401 /* Don't produce glyphs in produce_glyphs. */
6402 saved_glyph_row = it->glyph_row;
6403 it->glyph_row = NULL;
6404
6405 #define BUFFER_POS_REACHED_P() \
6406 ((op & MOVE_TO_POS) != 0 \
6407 && BUFFERP (it->object) \
6408 && IT_CHARPOS (*it) >= to_charpos \
6409 && (it->method == GET_FROM_BUFFER \
6410 || (it->method == GET_FROM_DISPLAY_VECTOR \
6411 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6412
6413
6414 while (1)
6415 {
6416 int x, i, ascent = 0, descent = 0;
6417
6418 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
6419 if ((op & MOVE_TO_POS) != 0
6420 && BUFFERP (it->object)
6421 && it->method == GET_FROM_BUFFER
6422 && IT_CHARPOS (*it) > to_charpos)
6423 {
6424 result = MOVE_POS_MATCH_OR_ZV;
6425 break;
6426 }
6427
6428 /* Stop when ZV reached.
6429 We used to stop here when TO_CHARPOS reached as well, but that is
6430 too soon if this glyph does not fit on this line. So we handle it
6431 explicitly below. */
6432 if (!get_next_display_element (it)
6433 || (it->truncate_lines_p
6434 && BUFFER_POS_REACHED_P ()))
6435 {
6436 result = MOVE_POS_MATCH_OR_ZV;
6437 break;
6438 }
6439
6440 /* The call to produce_glyphs will get the metrics of the
6441 display element IT is loaded with. We record in x the
6442 x-position before this display element in case it does not
6443 fit on the line. */
6444 x = it->current_x;
6445
6446 /* Remember the line height so far in case the next element doesn't
6447 fit on the line. */
6448 if (!it->truncate_lines_p)
6449 {
6450 ascent = it->max_ascent;
6451 descent = it->max_descent;
6452 }
6453
6454 PRODUCE_GLYPHS (it);
6455
6456 if (it->area != TEXT_AREA)
6457 {
6458 set_iterator_to_next (it, 1);
6459 continue;
6460 }
6461
6462 /* The number of glyphs we get back in IT->nglyphs will normally
6463 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
6464 character on a terminal frame, or (iii) a line end. For the
6465 second case, IT->nglyphs - 1 padding glyphs will be present
6466 (on X frames, there is only one glyph produced for a
6467 composite character.
6468
6469 The behavior implemented below means, for continuation lines,
6470 that as many spaces of a TAB as fit on the current line are
6471 displayed there. For terminal frames, as many glyphs of a
6472 multi-glyph character are displayed in the current line, too.
6473 This is what the old redisplay code did, and we keep it that
6474 way. Under X, the whole shape of a complex character must
6475 fit on the line or it will be completely displayed in the
6476 next line.
6477
6478 Note that both for tabs and padding glyphs, all glyphs have
6479 the same width. */
6480 if (it->nglyphs)
6481 {
6482 /* More than one glyph or glyph doesn't fit on line. All
6483 glyphs have the same width. */
6484 int single_glyph_width = it->pixel_width / it->nglyphs;
6485 int new_x;
6486 int x_before_this_char = x;
6487 int hpos_before_this_char = it->hpos;
6488
6489 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6490 {
6491 new_x = x + single_glyph_width;
6492
6493 /* We want to leave anything reaching TO_X to the caller. */
6494 if ((op & MOVE_TO_X) && new_x > to_x)
6495 {
6496 if (BUFFER_POS_REACHED_P ())
6497 goto buffer_pos_reached;
6498 it->current_x = x;
6499 result = MOVE_X_REACHED;
6500 break;
6501 }
6502 else if (/* Lines are continued. */
6503 !it->truncate_lines_p
6504 && (/* And glyph doesn't fit on the line. */
6505 new_x > it->last_visible_x
6506 /* Or it fits exactly and we're on a window
6507 system frame. */
6508 || (new_x == it->last_visible_x
6509 && FRAME_WINDOW_P (it->f))))
6510 {
6511 if (/* IT->hpos == 0 means the very first glyph
6512 doesn't fit on the line, e.g. a wide image. */
6513 it->hpos == 0
6514 || (new_x == it->last_visible_x
6515 && FRAME_WINDOW_P (it->f)))
6516 {
6517 ++it->hpos;
6518 it->current_x = new_x;
6519
6520 /* The character's last glyph just barely fits
6521 in this row. */
6522 if (i == it->nglyphs - 1)
6523 {
6524 /* If this is the destination position,
6525 return a position *before* it in this row,
6526 now that we know it fits in this row. */
6527 if (BUFFER_POS_REACHED_P ())
6528 {
6529 it->hpos = hpos_before_this_char;
6530 it->current_x = x_before_this_char;
6531 result = MOVE_POS_MATCH_OR_ZV;
6532 break;
6533 }
6534
6535 set_iterator_to_next (it, 1);
6536 #ifdef HAVE_WINDOW_SYSTEM
6537 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6538 {
6539 if (!get_next_display_element (it))
6540 {
6541 result = MOVE_POS_MATCH_OR_ZV;
6542 break;
6543 }
6544 if (BUFFER_POS_REACHED_P ())
6545 {
6546 if (ITERATOR_AT_END_OF_LINE_P (it))
6547 result = MOVE_POS_MATCH_OR_ZV;
6548 else
6549 result = MOVE_LINE_CONTINUED;
6550 break;
6551 }
6552 if (ITERATOR_AT_END_OF_LINE_P (it))
6553 {
6554 result = MOVE_NEWLINE_OR_CR;
6555 break;
6556 }
6557 }
6558 #endif /* HAVE_WINDOW_SYSTEM */
6559 }
6560 }
6561 else
6562 {
6563 it->current_x = x;
6564 it->max_ascent = ascent;
6565 it->max_descent = descent;
6566 }
6567
6568 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6569 IT_CHARPOS (*it)));
6570 result = MOVE_LINE_CONTINUED;
6571 break;
6572 }
6573 else if (BUFFER_POS_REACHED_P ())
6574 goto buffer_pos_reached;
6575 else if (new_x > it->first_visible_x)
6576 {
6577 /* Glyph is visible. Increment number of glyphs that
6578 would be displayed. */
6579 ++it->hpos;
6580 }
6581 else
6582 {
6583 /* Glyph is completely off the left margin of the display
6584 area. Nothing to do. */
6585 }
6586 }
6587
6588 if (result != MOVE_UNDEFINED)
6589 break;
6590 }
6591 else if (BUFFER_POS_REACHED_P ())
6592 {
6593 buffer_pos_reached:
6594 it->current_x = x;
6595 it->max_ascent = ascent;
6596 it->max_descent = descent;
6597 result = MOVE_POS_MATCH_OR_ZV;
6598 break;
6599 }
6600 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6601 {
6602 /* Stop when TO_X specified and reached. This check is
6603 necessary here because of lines consisting of a line end,
6604 only. The line end will not produce any glyphs and we
6605 would never get MOVE_X_REACHED. */
6606 xassert (it->nglyphs == 0);
6607 result = MOVE_X_REACHED;
6608 break;
6609 }
6610
6611 /* Is this a line end? If yes, we're done. */
6612 if (ITERATOR_AT_END_OF_LINE_P (it))
6613 {
6614 result = MOVE_NEWLINE_OR_CR;
6615 break;
6616 }
6617
6618 /* The current display element has been consumed. Advance
6619 to the next. */
6620 set_iterator_to_next (it, 1);
6621
6622 /* Stop if lines are truncated and IT's current x-position is
6623 past the right edge of the window now. */
6624 if (it->truncate_lines_p
6625 && it->current_x >= it->last_visible_x)
6626 {
6627 #ifdef HAVE_WINDOW_SYSTEM
6628 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6629 {
6630 if (!get_next_display_element (it)
6631 || BUFFER_POS_REACHED_P ())
6632 {
6633 result = MOVE_POS_MATCH_OR_ZV;
6634 break;
6635 }
6636 if (ITERATOR_AT_END_OF_LINE_P (it))
6637 {
6638 result = MOVE_NEWLINE_OR_CR;
6639 break;
6640 }
6641 }
6642 #endif /* HAVE_WINDOW_SYSTEM */
6643 result = MOVE_LINE_TRUNCATED;
6644 break;
6645 }
6646 }
6647
6648 #undef BUFFER_POS_REACHED_P
6649
6650 /* Restore the iterator settings altered at the beginning of this
6651 function. */
6652 it->glyph_row = saved_glyph_row;
6653 return result;
6654 }
6655
6656
6657 /* Move IT forward until it satisfies one or more of the criteria in
6658 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6659
6660 OP is a bit-mask that specifies where to stop, and in particular,
6661 which of those four position arguments makes a difference. See the
6662 description of enum move_operation_enum.
6663
6664 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6665 screen line, this function will set IT to the next position >
6666 TO_CHARPOS. */
6667
6668 void
6669 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6670 struct it *it;
6671 int to_charpos, to_x, to_y, to_vpos;
6672 int op;
6673 {
6674 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6675 int line_height;
6676 int reached = 0;
6677
6678 for (;;)
6679 {
6680 if (op & MOVE_TO_VPOS)
6681 {
6682 /* If no TO_CHARPOS and no TO_X specified, stop at the
6683 start of the line TO_VPOS. */
6684 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6685 {
6686 if (it->vpos == to_vpos)
6687 {
6688 reached = 1;
6689 break;
6690 }
6691 else
6692 skip = move_it_in_display_line_to (it, -1, -1, 0);
6693 }
6694 else
6695 {
6696 /* TO_VPOS >= 0 means stop at TO_X in the line at
6697 TO_VPOS, or at TO_POS, whichever comes first. */
6698 if (it->vpos == to_vpos)
6699 {
6700 reached = 2;
6701 break;
6702 }
6703
6704 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6705
6706 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6707 {
6708 reached = 3;
6709 break;
6710 }
6711 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6712 {
6713 /* We have reached TO_X but not in the line we want. */
6714 skip = move_it_in_display_line_to (it, to_charpos,
6715 -1, MOVE_TO_POS);
6716 if (skip == MOVE_POS_MATCH_OR_ZV)
6717 {
6718 reached = 4;
6719 break;
6720 }
6721 }
6722 }
6723 }
6724 else if (op & MOVE_TO_Y)
6725 {
6726 struct it it_backup;
6727
6728 /* TO_Y specified means stop at TO_X in the line containing
6729 TO_Y---or at TO_CHARPOS if this is reached first. The
6730 problem is that we can't really tell whether the line
6731 contains TO_Y before we have completely scanned it, and
6732 this may skip past TO_X. What we do is to first scan to
6733 TO_X.
6734
6735 If TO_X is not specified, use a TO_X of zero. The reason
6736 is to make the outcome of this function more predictable.
6737 If we didn't use TO_X == 0, we would stop at the end of
6738 the line which is probably not what a caller would expect
6739 to happen. */
6740 skip = move_it_in_display_line_to (it, to_charpos,
6741 ((op & MOVE_TO_X)
6742 ? to_x : 0),
6743 (MOVE_TO_X
6744 | (op & MOVE_TO_POS)));
6745
6746 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6747 if (skip == MOVE_POS_MATCH_OR_ZV)
6748 {
6749 reached = 5;
6750 break;
6751 }
6752
6753 /* If TO_X was reached, we would like to know whether TO_Y
6754 is in the line. This can only be said if we know the
6755 total line height which requires us to scan the rest of
6756 the line. */
6757 if (skip == MOVE_X_REACHED)
6758 {
6759 it_backup = *it;
6760 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6761 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6762 op & MOVE_TO_POS);
6763 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6764 }
6765
6766 /* Now, decide whether TO_Y is in this line. */
6767 line_height = it->max_ascent + it->max_descent;
6768 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6769
6770 if (to_y >= it->current_y
6771 && to_y < it->current_y + line_height)
6772 {
6773 if (skip == MOVE_X_REACHED)
6774 /* If TO_Y is in this line and TO_X was reached above,
6775 we scanned too far. We have to restore IT's settings
6776 to the ones before skipping. */
6777 *it = it_backup;
6778 reached = 6;
6779 }
6780 else if (skip == MOVE_X_REACHED)
6781 {
6782 skip = skip2;
6783 if (skip == MOVE_POS_MATCH_OR_ZV)
6784 reached = 7;
6785 }
6786
6787 if (reached)
6788 break;
6789 }
6790 else if (BUFFERP (it->object)
6791 && it->method == GET_FROM_BUFFER
6792 && IT_CHARPOS (*it) >= to_charpos)
6793 skip = MOVE_POS_MATCH_OR_ZV;
6794 else
6795 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6796
6797 switch (skip)
6798 {
6799 case MOVE_POS_MATCH_OR_ZV:
6800 reached = 8;
6801 goto out;
6802
6803 case MOVE_NEWLINE_OR_CR:
6804 set_iterator_to_next (it, 1);
6805 it->continuation_lines_width = 0;
6806 break;
6807
6808 case MOVE_LINE_TRUNCATED:
6809 it->continuation_lines_width = 0;
6810 reseat_at_next_visible_line_start (it, 0);
6811 if ((op & MOVE_TO_POS) != 0
6812 && IT_CHARPOS (*it) > to_charpos)
6813 {
6814 reached = 9;
6815 goto out;
6816 }
6817 break;
6818
6819 case MOVE_LINE_CONTINUED:
6820 /* For continued lines ending in a tab, some of the glyphs
6821 associated with the tab are displayed on the current
6822 line. Since it->current_x does not include these glyphs,
6823 we use it->last_visible_x instead. */
6824 it->continuation_lines_width +=
6825 (it->c == '\t') ? it->last_visible_x : it->current_x;
6826 break;
6827
6828 default:
6829 abort ();
6830 }
6831
6832 /* Reset/increment for the next run. */
6833 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6834 it->current_x = it->hpos = 0;
6835 it->current_y += it->max_ascent + it->max_descent;
6836 ++it->vpos;
6837 last_height = it->max_ascent + it->max_descent;
6838 last_max_ascent = it->max_ascent;
6839 it->max_ascent = it->max_descent = 0;
6840 }
6841
6842 out:
6843
6844 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6845 }
6846
6847
6848 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6849
6850 If DY > 0, move IT backward at least that many pixels. DY = 0
6851 means move IT backward to the preceding line start or BEGV. This
6852 function may move over more than DY pixels if IT->current_y - DY
6853 ends up in the middle of a line; in this case IT->current_y will be
6854 set to the top of the line moved to. */
6855
6856 void
6857 move_it_vertically_backward (it, dy)
6858 struct it *it;
6859 int dy;
6860 {
6861 int nlines, h;
6862 struct it it2, it3;
6863 int start_pos;
6864
6865 move_further_back:
6866 xassert (dy >= 0);
6867
6868 start_pos = IT_CHARPOS (*it);
6869
6870 /* Estimate how many newlines we must move back. */
6871 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6872
6873 /* Set the iterator's position that many lines back. */
6874 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6875 back_to_previous_visible_line_start (it);
6876
6877 /* Reseat the iterator here. When moving backward, we don't want
6878 reseat to skip forward over invisible text, set up the iterator
6879 to deliver from overlay strings at the new position etc. So,
6880 use reseat_1 here. */
6881 reseat_1 (it, it->current.pos, 1);
6882
6883 /* We are now surely at a line start. */
6884 it->current_x = it->hpos = 0;
6885 it->continuation_lines_width = 0;
6886
6887 /* Move forward and see what y-distance we moved. First move to the
6888 start of the next line so that we get its height. We need this
6889 height to be able to tell whether we reached the specified
6890 y-distance. */
6891 it2 = *it;
6892 it2.max_ascent = it2.max_descent = 0;
6893 do
6894 {
6895 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6896 MOVE_TO_POS | MOVE_TO_VPOS);
6897 }
6898 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
6899 xassert (IT_CHARPOS (*it) >= BEGV);
6900 it3 = it2;
6901
6902 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6903 xassert (IT_CHARPOS (*it) >= BEGV);
6904 /* H is the actual vertical distance from the position in *IT
6905 and the starting position. */
6906 h = it2.current_y - it->current_y;
6907 /* NLINES is the distance in number of lines. */
6908 nlines = it2.vpos - it->vpos;
6909
6910 /* Correct IT's y and vpos position
6911 so that they are relative to the starting point. */
6912 it->vpos -= nlines;
6913 it->current_y -= h;
6914
6915 if (dy == 0)
6916 {
6917 /* DY == 0 means move to the start of the screen line. The
6918 value of nlines is > 0 if continuation lines were involved. */
6919 if (nlines > 0)
6920 move_it_by_lines (it, nlines, 1);
6921 #if 0
6922 /* I think this assert is bogus if buffer contains
6923 invisible text or images. KFS. */
6924 xassert (IT_CHARPOS (*it) <= start_pos);
6925 #endif
6926 }
6927 else
6928 {
6929 /* The y-position we try to reach, relative to *IT.
6930 Note that H has been subtracted in front of the if-statement. */
6931 int target_y = it->current_y + h - dy;
6932 int y0 = it3.current_y;
6933 int y1 = line_bottom_y (&it3);
6934 int line_height = y1 - y0;
6935
6936 /* If we did not reach target_y, try to move further backward if
6937 we can. If we moved too far backward, try to move forward. */
6938 if (target_y < it->current_y
6939 /* This is heuristic. In a window that's 3 lines high, with
6940 a line height of 13 pixels each, recentering with point
6941 on the bottom line will try to move -39/2 = 19 pixels
6942 backward. Try to avoid moving into the first line. */
6943 && (it->current_y - target_y
6944 > min (window_box_height (it->w), line_height * 2 / 3))
6945 && IT_CHARPOS (*it) > BEGV)
6946 {
6947 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6948 target_y - it->current_y));
6949 dy = it->current_y - target_y;
6950 goto move_further_back;
6951 }
6952 else if (target_y >= it->current_y + line_height
6953 && IT_CHARPOS (*it) < ZV)
6954 {
6955 /* Should move forward by at least one line, maybe more.
6956
6957 Note: Calling move_it_by_lines can be expensive on
6958 terminal frames, where compute_motion is used (via
6959 vmotion) to do the job, when there are very long lines
6960 and truncate-lines is nil. That's the reason for
6961 treating terminal frames specially here. */
6962
6963 if (!FRAME_WINDOW_P (it->f))
6964 move_it_vertically (it, target_y - (it->current_y + line_height));
6965 else
6966 {
6967 do
6968 {
6969 move_it_by_lines (it, 1, 1);
6970 }
6971 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6972 }
6973
6974 #if 0
6975 /* I think this assert is bogus if buffer contains
6976 invisible text or images. KFS. */
6977 xassert (IT_CHARPOS (*it) >= BEGV);
6978 #endif
6979 }
6980 }
6981 }
6982
6983
6984 /* Move IT by a specified amount of pixel lines DY. DY negative means
6985 move backwards. DY = 0 means move to start of screen line. At the
6986 end, IT will be on the start of a screen line. */
6987
6988 void
6989 move_it_vertically (it, dy)
6990 struct it *it;
6991 int dy;
6992 {
6993 if (dy <= 0)
6994 move_it_vertically_backward (it, -dy);
6995 else
6996 {
6997 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6998 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6999 MOVE_TO_POS | MOVE_TO_Y);
7000 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7001
7002 /* If buffer ends in ZV without a newline, move to the start of
7003 the line to satisfy the post-condition. */
7004 if (IT_CHARPOS (*it) == ZV
7005 && ZV > BEGV
7006 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7007 move_it_by_lines (it, 0, 0);
7008 }
7009 }
7010
7011
7012 /* Move iterator IT past the end of the text line it is in. */
7013
7014 void
7015 move_it_past_eol (it)
7016 struct it *it;
7017 {
7018 enum move_it_result rc;
7019
7020 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7021 if (rc == MOVE_NEWLINE_OR_CR)
7022 set_iterator_to_next (it, 0);
7023 }
7024
7025
7026 #if 0 /* Currently not used. */
7027
7028 /* Return non-zero if some text between buffer positions START_CHARPOS
7029 and END_CHARPOS is invisible. IT->window is the window for text
7030 property lookup. */
7031
7032 static int
7033 invisible_text_between_p (it, start_charpos, end_charpos)
7034 struct it *it;
7035 int start_charpos, end_charpos;
7036 {
7037 Lisp_Object prop, limit;
7038 int invisible_found_p;
7039
7040 xassert (it != NULL && start_charpos <= end_charpos);
7041
7042 /* Is text at START invisible? */
7043 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
7044 it->window);
7045 if (TEXT_PROP_MEANS_INVISIBLE (prop))
7046 invisible_found_p = 1;
7047 else
7048 {
7049 limit = Fnext_single_char_property_change (make_number (start_charpos),
7050 Qinvisible, Qnil,
7051 make_number (end_charpos));
7052 invisible_found_p = XFASTINT (limit) < end_charpos;
7053 }
7054
7055 return invisible_found_p;
7056 }
7057
7058 #endif /* 0 */
7059
7060
7061 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7062 negative means move up. DVPOS == 0 means move to the start of the
7063 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7064 NEED_Y_P is zero, IT->current_y will be left unchanged.
7065
7066 Further optimization ideas: If we would know that IT->f doesn't use
7067 a face with proportional font, we could be faster for
7068 truncate-lines nil. */
7069
7070 void
7071 move_it_by_lines (it, dvpos, need_y_p)
7072 struct it *it;
7073 int dvpos, need_y_p;
7074 {
7075 struct position pos;
7076
7077 /* The commented-out optimization uses vmotion on terminals. This
7078 gives bad results, because elements like it->what, on which
7079 callers such as pos_visible_p rely, aren't updated. */
7080 /* if (!FRAME_WINDOW_P (it->f))
7081 {
7082 struct text_pos textpos;
7083
7084 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7085 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7086 reseat (it, textpos, 1);
7087 it->vpos += pos.vpos;
7088 it->current_y += pos.vpos;
7089 }
7090 else */
7091
7092 if (dvpos == 0)
7093 {
7094 /* DVPOS == 0 means move to the start of the screen line. */
7095 move_it_vertically_backward (it, 0);
7096 xassert (it->current_x == 0 && it->hpos == 0);
7097 /* Let next call to line_bottom_y calculate real line height */
7098 last_height = 0;
7099 }
7100 else if (dvpos > 0)
7101 {
7102 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7103 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7104 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7105 }
7106 else
7107 {
7108 struct it it2;
7109 int start_charpos, i;
7110
7111 /* Start at the beginning of the screen line containing IT's
7112 position. This may actually move vertically backwards,
7113 in case of overlays, so adjust dvpos accordingly. */
7114 dvpos += it->vpos;
7115 move_it_vertically_backward (it, 0);
7116 dvpos -= it->vpos;
7117
7118 /* Go back -DVPOS visible lines and reseat the iterator there. */
7119 start_charpos = IT_CHARPOS (*it);
7120 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7121 back_to_previous_visible_line_start (it);
7122 reseat (it, it->current.pos, 1);
7123
7124 /* Move further back if we end up in a string or an image. */
7125 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7126 {
7127 /* First try to move to start of display line. */
7128 dvpos += it->vpos;
7129 move_it_vertically_backward (it, 0);
7130 dvpos -= it->vpos;
7131 if (IT_POS_VALID_AFTER_MOVE_P (it))
7132 break;
7133 /* If start of line is still in string or image,
7134 move further back. */
7135 back_to_previous_visible_line_start (it);
7136 reseat (it, it->current.pos, 1);
7137 dvpos--;
7138 }
7139
7140 it->current_x = it->hpos = 0;
7141
7142 /* Above call may have moved too far if continuation lines
7143 are involved. Scan forward and see if it did. */
7144 it2 = *it;
7145 it2.vpos = it2.current_y = 0;
7146 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7147 it->vpos -= it2.vpos;
7148 it->current_y -= it2.current_y;
7149 it->current_x = it->hpos = 0;
7150
7151 /* If we moved too far back, move IT some lines forward. */
7152 if (it2.vpos > -dvpos)
7153 {
7154 int delta = it2.vpos + dvpos;
7155 it2 = *it;
7156 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7157 /* Move back again if we got too far ahead. */
7158 if (IT_CHARPOS (*it) >= start_charpos)
7159 *it = it2;
7160 }
7161 }
7162 }
7163
7164 /* Return 1 if IT points into the middle of a display vector. */
7165
7166 int
7167 in_display_vector_p (it)
7168 struct it *it;
7169 {
7170 return (it->method == GET_FROM_DISPLAY_VECTOR
7171 && it->current.dpvec_index > 0
7172 && it->dpvec + it->current.dpvec_index != it->dpend);
7173 }
7174
7175 \f
7176 /***********************************************************************
7177 Messages
7178 ***********************************************************************/
7179
7180
7181 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7182 to *Messages*. */
7183
7184 void
7185 add_to_log (format, arg1, arg2)
7186 char *format;
7187 Lisp_Object arg1, arg2;
7188 {
7189 Lisp_Object args[3];
7190 Lisp_Object msg, fmt;
7191 char *buffer;
7192 int len;
7193 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7194 USE_SAFE_ALLOCA;
7195
7196 /* Do nothing if called asynchronously. Inserting text into
7197 a buffer may call after-change-functions and alike and
7198 that would means running Lisp asynchronously. */
7199 if (handling_signal)
7200 return;
7201
7202 fmt = msg = Qnil;
7203 GCPRO4 (fmt, msg, arg1, arg2);
7204
7205 args[0] = fmt = build_string (format);
7206 args[1] = arg1;
7207 args[2] = arg2;
7208 msg = Fformat (3, args);
7209
7210 len = SBYTES (msg) + 1;
7211 SAFE_ALLOCA (buffer, char *, len);
7212 bcopy (SDATA (msg), buffer, len);
7213
7214 message_dolog (buffer, len - 1, 1, 0);
7215 SAFE_FREE ();
7216
7217 UNGCPRO;
7218 }
7219
7220
7221 /* Output a newline in the *Messages* buffer if "needs" one. */
7222
7223 void
7224 message_log_maybe_newline ()
7225 {
7226 if (message_log_need_newline)
7227 message_dolog ("", 0, 1, 0);
7228 }
7229
7230
7231 /* Add a string M of length NBYTES to the message log, optionally
7232 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7233 nonzero, means interpret the contents of M as multibyte. This
7234 function calls low-level routines in order to bypass text property
7235 hooks, etc. which might not be safe to run.
7236
7237 This may GC (insert may run before/after change hooks),
7238 so the buffer M must NOT point to a Lisp string. */
7239
7240 void
7241 message_dolog (m, nbytes, nlflag, multibyte)
7242 const char *m;
7243 int nbytes, nlflag, multibyte;
7244 {
7245 if (!NILP (Vmemory_full))
7246 return;
7247
7248 if (!NILP (Vmessage_log_max))
7249 {
7250 struct buffer *oldbuf;
7251 Lisp_Object oldpoint, oldbegv, oldzv;
7252 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7253 int point_at_end = 0;
7254 int zv_at_end = 0;
7255 Lisp_Object old_deactivate_mark, tem;
7256 struct gcpro gcpro1;
7257
7258 old_deactivate_mark = Vdeactivate_mark;
7259 oldbuf = current_buffer;
7260 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7261 current_buffer->undo_list = Qt;
7262
7263 oldpoint = message_dolog_marker1;
7264 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7265 oldbegv = message_dolog_marker2;
7266 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7267 oldzv = message_dolog_marker3;
7268 set_marker_restricted (oldzv, make_number (ZV), Qnil);
7269 GCPRO1 (old_deactivate_mark);
7270
7271 if (PT == Z)
7272 point_at_end = 1;
7273 if (ZV == Z)
7274 zv_at_end = 1;
7275
7276 BEGV = BEG;
7277 BEGV_BYTE = BEG_BYTE;
7278 ZV = Z;
7279 ZV_BYTE = Z_BYTE;
7280 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7281
7282 /* Insert the string--maybe converting multibyte to single byte
7283 or vice versa, so that all the text fits the buffer. */
7284 if (multibyte
7285 && NILP (current_buffer->enable_multibyte_characters))
7286 {
7287 int i, c, char_bytes;
7288 unsigned char work[1];
7289
7290 /* Convert a multibyte string to single-byte
7291 for the *Message* buffer. */
7292 for (i = 0; i < nbytes; i += char_bytes)
7293 {
7294 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
7295 work[0] = (SINGLE_BYTE_CHAR_P (c)
7296 ? c
7297 : multibyte_char_to_unibyte (c, Qnil));
7298 insert_1_both (work, 1, 1, 1, 0, 0);
7299 }
7300 }
7301 else if (! multibyte
7302 && ! NILP (current_buffer->enable_multibyte_characters))
7303 {
7304 int i, c, char_bytes;
7305 unsigned char *msg = (unsigned char *) m;
7306 unsigned char str[MAX_MULTIBYTE_LENGTH];
7307 /* Convert a single-byte string to multibyte
7308 for the *Message* buffer. */
7309 for (i = 0; i < nbytes; i++)
7310 {
7311 c = unibyte_char_to_multibyte (msg[i]);
7312 char_bytes = CHAR_STRING (c, str);
7313 insert_1_both (str, 1, char_bytes, 1, 0, 0);
7314 }
7315 }
7316 else if (nbytes)
7317 insert_1 (m, nbytes, 1, 0, 0);
7318
7319 if (nlflag)
7320 {
7321 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
7322 insert_1 ("\n", 1, 1, 0, 0);
7323
7324 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
7325 this_bol = PT;
7326 this_bol_byte = PT_BYTE;
7327
7328 /* See if this line duplicates the previous one.
7329 If so, combine duplicates. */
7330 if (this_bol > BEG)
7331 {
7332 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
7333 prev_bol = PT;
7334 prev_bol_byte = PT_BYTE;
7335
7336 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
7337 this_bol, this_bol_byte);
7338 if (dup)
7339 {
7340 del_range_both (prev_bol, prev_bol_byte,
7341 this_bol, this_bol_byte, 0);
7342 if (dup > 1)
7343 {
7344 char dupstr[40];
7345 int duplen;
7346
7347 /* If you change this format, don't forget to also
7348 change message_log_check_duplicate. */
7349 sprintf (dupstr, " [%d times]", dup);
7350 duplen = strlen (dupstr);
7351 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
7352 insert_1 (dupstr, duplen, 1, 0, 1);
7353 }
7354 }
7355 }
7356
7357 /* If we have more than the desired maximum number of lines
7358 in the *Messages* buffer now, delete the oldest ones.
7359 This is safe because we don't have undo in this buffer. */
7360
7361 if (NATNUMP (Vmessage_log_max))
7362 {
7363 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
7364 -XFASTINT (Vmessage_log_max) - 1, 0);
7365 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
7366 }
7367 }
7368 BEGV = XMARKER (oldbegv)->charpos;
7369 BEGV_BYTE = marker_byte_position (oldbegv);
7370
7371 if (zv_at_end)
7372 {
7373 ZV = Z;
7374 ZV_BYTE = Z_BYTE;
7375 }
7376 else
7377 {
7378 ZV = XMARKER (oldzv)->charpos;
7379 ZV_BYTE = marker_byte_position (oldzv);
7380 }
7381
7382 if (point_at_end)
7383 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7384 else
7385 /* We can't do Fgoto_char (oldpoint) because it will run some
7386 Lisp code. */
7387 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
7388 XMARKER (oldpoint)->bytepos);
7389
7390 UNGCPRO;
7391 unchain_marker (XMARKER (oldpoint));
7392 unchain_marker (XMARKER (oldbegv));
7393 unchain_marker (XMARKER (oldzv));
7394
7395 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
7396 set_buffer_internal (oldbuf);
7397 if (NILP (tem))
7398 windows_or_buffers_changed = old_windows_or_buffers_changed;
7399 message_log_need_newline = !nlflag;
7400 Vdeactivate_mark = old_deactivate_mark;
7401 }
7402 }
7403
7404
7405 /* We are at the end of the buffer after just having inserted a newline.
7406 (Note: We depend on the fact we won't be crossing the gap.)
7407 Check to see if the most recent message looks a lot like the previous one.
7408 Return 0 if different, 1 if the new one should just replace it, or a
7409 value N > 1 if we should also append " [N times]". */
7410
7411 static int
7412 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
7413 int prev_bol, this_bol;
7414 int prev_bol_byte, this_bol_byte;
7415 {
7416 int i;
7417 int len = Z_BYTE - 1 - this_bol_byte;
7418 int seen_dots = 0;
7419 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
7420 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
7421
7422 for (i = 0; i < len; i++)
7423 {
7424 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
7425 seen_dots = 1;
7426 if (p1[i] != p2[i])
7427 return seen_dots;
7428 }
7429 p1 += len;
7430 if (*p1 == '\n')
7431 return 2;
7432 if (*p1++ == ' ' && *p1++ == '[')
7433 {
7434 int n = 0;
7435 while (*p1 >= '0' && *p1 <= '9')
7436 n = n * 10 + *p1++ - '0';
7437 if (strncmp (p1, " times]\n", 8) == 0)
7438 return n+1;
7439 }
7440 return 0;
7441 }
7442 \f
7443
7444 /* Display an echo area message M with a specified length of NBYTES
7445 bytes. The string may include null characters. If M is 0, clear
7446 out any existing message, and let the mini-buffer text show
7447 through.
7448
7449 This may GC, so the buffer M must NOT point to a Lisp string. */
7450
7451 void
7452 message2 (m, nbytes, multibyte)
7453 const char *m;
7454 int nbytes;
7455 int multibyte;
7456 {
7457 /* First flush out any partial line written with print. */
7458 message_log_maybe_newline ();
7459 if (m)
7460 message_dolog (m, nbytes, 1, multibyte);
7461 message2_nolog (m, nbytes, multibyte);
7462 }
7463
7464
7465 /* The non-logging counterpart of message2. */
7466
7467 void
7468 message2_nolog (m, nbytes, multibyte)
7469 const char *m;
7470 int nbytes, multibyte;
7471 {
7472 struct frame *sf = SELECTED_FRAME ();
7473 message_enable_multibyte = multibyte;
7474
7475 if (noninteractive)
7476 {
7477 if (noninteractive_need_newline)
7478 putc ('\n', stderr);
7479 noninteractive_need_newline = 0;
7480 if (m)
7481 fwrite (m, nbytes, 1, stderr);
7482 if (cursor_in_echo_area == 0)
7483 fprintf (stderr, "\n");
7484 fflush (stderr);
7485 }
7486 /* A null message buffer means that the frame hasn't really been
7487 initialized yet. Error messages get reported properly by
7488 cmd_error, so this must be just an informative message; toss it. */
7489 else if (INTERACTIVE
7490 && sf->glyphs_initialized_p
7491 && FRAME_MESSAGE_BUF (sf))
7492 {
7493 Lisp_Object mini_window;
7494 struct frame *f;
7495
7496 /* Get the frame containing the mini-buffer
7497 that the selected frame is using. */
7498 mini_window = FRAME_MINIBUF_WINDOW (sf);
7499 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7500
7501 FRAME_SAMPLE_VISIBILITY (f);
7502 if (FRAME_VISIBLE_P (sf)
7503 && ! FRAME_VISIBLE_P (f))
7504 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
7505
7506 if (m)
7507 {
7508 set_message (m, Qnil, nbytes, multibyte);
7509 if (minibuffer_auto_raise)
7510 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7511 }
7512 else
7513 clear_message (1, 1);
7514
7515 do_pending_window_change (0);
7516 echo_area_display (1);
7517 do_pending_window_change (0);
7518 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7519 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7520 }
7521 }
7522
7523
7524 /* Display an echo area message M with a specified length of NBYTES
7525 bytes. The string may include null characters. If M is not a
7526 string, clear out any existing message, and let the mini-buffer
7527 text show through.
7528
7529 This function cancels echoing. */
7530
7531 void
7532 message3 (m, nbytes, multibyte)
7533 Lisp_Object m;
7534 int nbytes;
7535 int multibyte;
7536 {
7537 struct gcpro gcpro1;
7538
7539 GCPRO1 (m);
7540 clear_message (1,1);
7541 cancel_echoing ();
7542
7543 /* First flush out any partial line written with print. */
7544 message_log_maybe_newline ();
7545 if (STRINGP (m))
7546 {
7547 char *buffer;
7548 USE_SAFE_ALLOCA;
7549
7550 SAFE_ALLOCA (buffer, char *, nbytes);
7551 bcopy (SDATA (m), buffer, nbytes);
7552 message_dolog (buffer, nbytes, 1, multibyte);
7553 SAFE_FREE ();
7554 }
7555 message3_nolog (m, nbytes, multibyte);
7556
7557 UNGCPRO;
7558 }
7559
7560
7561 /* The non-logging version of message3.
7562 This does not cancel echoing, because it is used for echoing.
7563 Perhaps we need to make a separate function for echoing
7564 and make this cancel echoing. */
7565
7566 void
7567 message3_nolog (m, nbytes, multibyte)
7568 Lisp_Object m;
7569 int nbytes, multibyte;
7570 {
7571 struct frame *sf = SELECTED_FRAME ();
7572 message_enable_multibyte = multibyte;
7573
7574 if (noninteractive)
7575 {
7576 if (noninteractive_need_newline)
7577 putc ('\n', stderr);
7578 noninteractive_need_newline = 0;
7579 if (STRINGP (m))
7580 fwrite (SDATA (m), nbytes, 1, stderr);
7581 if (cursor_in_echo_area == 0)
7582 fprintf (stderr, "\n");
7583 fflush (stderr);
7584 }
7585 /* A null message buffer means that the frame hasn't really been
7586 initialized yet. Error messages get reported properly by
7587 cmd_error, so this must be just an informative message; toss it. */
7588 else if (INTERACTIVE
7589 && sf->glyphs_initialized_p
7590 && FRAME_MESSAGE_BUF (sf))
7591 {
7592 Lisp_Object mini_window;
7593 Lisp_Object frame;
7594 struct frame *f;
7595
7596 /* Get the frame containing the mini-buffer
7597 that the selected frame is using. */
7598 mini_window = FRAME_MINIBUF_WINDOW (sf);
7599 frame = XWINDOW (mini_window)->frame;
7600 f = XFRAME (frame);
7601
7602 FRAME_SAMPLE_VISIBILITY (f);
7603 if (FRAME_VISIBLE_P (sf)
7604 && !FRAME_VISIBLE_P (f))
7605 Fmake_frame_visible (frame);
7606
7607 if (STRINGP (m) && SCHARS (m) > 0)
7608 {
7609 set_message (NULL, m, nbytes, multibyte);
7610 if (minibuffer_auto_raise)
7611 Fraise_frame (frame);
7612 /* Assume we are not echoing.
7613 (If we are, echo_now will override this.) */
7614 echo_message_buffer = Qnil;
7615 }
7616 else
7617 clear_message (1, 1);
7618
7619 do_pending_window_change (0);
7620 echo_area_display (1);
7621 do_pending_window_change (0);
7622 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7623 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7624 }
7625 }
7626
7627
7628 /* Display a null-terminated echo area message M. If M is 0, clear
7629 out any existing message, and let the mini-buffer text show through.
7630
7631 The buffer M must continue to exist until after the echo area gets
7632 cleared or some other message gets displayed there. Do not pass
7633 text that is stored in a Lisp string. Do not pass text in a buffer
7634 that was alloca'd. */
7635
7636 void
7637 message1 (m)
7638 char *m;
7639 {
7640 message2 (m, (m ? strlen (m) : 0), 0);
7641 }
7642
7643
7644 /* The non-logging counterpart of message1. */
7645
7646 void
7647 message1_nolog (m)
7648 char *m;
7649 {
7650 message2_nolog (m, (m ? strlen (m) : 0), 0);
7651 }
7652
7653 /* Display a message M which contains a single %s
7654 which gets replaced with STRING. */
7655
7656 void
7657 message_with_string (m, string, log)
7658 char *m;
7659 Lisp_Object string;
7660 int log;
7661 {
7662 CHECK_STRING (string);
7663
7664 if (noninteractive)
7665 {
7666 if (m)
7667 {
7668 if (noninteractive_need_newline)
7669 putc ('\n', stderr);
7670 noninteractive_need_newline = 0;
7671 fprintf (stderr, m, SDATA (string));
7672 if (cursor_in_echo_area == 0)
7673 fprintf (stderr, "\n");
7674 fflush (stderr);
7675 }
7676 }
7677 else if (INTERACTIVE)
7678 {
7679 /* The frame whose minibuffer we're going to display the message on.
7680 It may be larger than the selected frame, so we need
7681 to use its buffer, not the selected frame's buffer. */
7682 Lisp_Object mini_window;
7683 struct frame *f, *sf = SELECTED_FRAME ();
7684
7685 /* Get the frame containing the minibuffer
7686 that the selected frame is using. */
7687 mini_window = FRAME_MINIBUF_WINDOW (sf);
7688 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7689
7690 /* A null message buffer means that the frame hasn't really been
7691 initialized yet. Error messages get reported properly by
7692 cmd_error, so this must be just an informative message; toss it. */
7693 if (FRAME_MESSAGE_BUF (f))
7694 {
7695 Lisp_Object args[2], message;
7696 struct gcpro gcpro1, gcpro2;
7697
7698 args[0] = build_string (m);
7699 args[1] = message = string;
7700 GCPRO2 (args[0], message);
7701 gcpro1.nvars = 2;
7702
7703 message = Fformat (2, args);
7704
7705 if (log)
7706 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7707 else
7708 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7709
7710 UNGCPRO;
7711
7712 /* Print should start at the beginning of the message
7713 buffer next time. */
7714 message_buf_print = 0;
7715 }
7716 }
7717 }
7718
7719
7720 /* Dump an informative message to the minibuf. If M is 0, clear out
7721 any existing message, and let the mini-buffer text show through. */
7722
7723 /* VARARGS 1 */
7724 void
7725 message (m, a1, a2, a3)
7726 char *m;
7727 EMACS_INT a1, a2, a3;
7728 {
7729 if (noninteractive)
7730 {
7731 if (m)
7732 {
7733 if (noninteractive_need_newline)
7734 putc ('\n', stderr);
7735 noninteractive_need_newline = 0;
7736 fprintf (stderr, m, a1, a2, a3);
7737 if (cursor_in_echo_area == 0)
7738 fprintf (stderr, "\n");
7739 fflush (stderr);
7740 }
7741 }
7742 else if (INTERACTIVE)
7743 {
7744 /* The frame whose mini-buffer we're going to display the message
7745 on. It may be larger than the selected frame, so we need to
7746 use its buffer, not the selected frame's buffer. */
7747 Lisp_Object mini_window;
7748 struct frame *f, *sf = SELECTED_FRAME ();
7749
7750 /* Get the frame containing the mini-buffer
7751 that the selected frame is using. */
7752 mini_window = FRAME_MINIBUF_WINDOW (sf);
7753 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7754
7755 /* A null message buffer means that the frame hasn't really been
7756 initialized yet. Error messages get reported properly by
7757 cmd_error, so this must be just an informative message; toss
7758 it. */
7759 if (FRAME_MESSAGE_BUF (f))
7760 {
7761 if (m)
7762 {
7763 int len;
7764 #ifdef NO_ARG_ARRAY
7765 char *a[3];
7766 a[0] = (char *) a1;
7767 a[1] = (char *) a2;
7768 a[2] = (char *) a3;
7769
7770 len = doprnt (FRAME_MESSAGE_BUF (f),
7771 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7772 #else
7773 len = doprnt (FRAME_MESSAGE_BUF (f),
7774 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7775 (char **) &a1);
7776 #endif /* NO_ARG_ARRAY */
7777
7778 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7779 }
7780 else
7781 message1 (0);
7782
7783 /* Print should start at the beginning of the message
7784 buffer next time. */
7785 message_buf_print = 0;
7786 }
7787 }
7788 }
7789
7790
7791 /* The non-logging version of message. */
7792
7793 void
7794 message_nolog (m, a1, a2, a3)
7795 char *m;
7796 EMACS_INT a1, a2, a3;
7797 {
7798 Lisp_Object old_log_max;
7799 old_log_max = Vmessage_log_max;
7800 Vmessage_log_max = Qnil;
7801 message (m, a1, a2, a3);
7802 Vmessage_log_max = old_log_max;
7803 }
7804
7805
7806 /* Display the current message in the current mini-buffer. This is
7807 only called from error handlers in process.c, and is not time
7808 critical. */
7809
7810 void
7811 update_echo_area ()
7812 {
7813 if (!NILP (echo_area_buffer[0]))
7814 {
7815 Lisp_Object string;
7816 string = Fcurrent_message ();
7817 message3 (string, SBYTES (string),
7818 !NILP (current_buffer->enable_multibyte_characters));
7819 }
7820 }
7821
7822
7823 /* Make sure echo area buffers in `echo_buffers' are live.
7824 If they aren't, make new ones. */
7825
7826 static void
7827 ensure_echo_area_buffers ()
7828 {
7829 int i;
7830
7831 for (i = 0; i < 2; ++i)
7832 if (!BUFFERP (echo_buffer[i])
7833 || NILP (XBUFFER (echo_buffer[i])->name))
7834 {
7835 char name[30];
7836 Lisp_Object old_buffer;
7837 int j;
7838
7839 old_buffer = echo_buffer[i];
7840 sprintf (name, " *Echo Area %d*", i);
7841 echo_buffer[i] = Fget_buffer_create (build_string (name));
7842 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7843
7844 for (j = 0; j < 2; ++j)
7845 if (EQ (old_buffer, echo_area_buffer[j]))
7846 echo_area_buffer[j] = echo_buffer[i];
7847 }
7848 }
7849
7850
7851 /* Call FN with args A1..A4 with either the current or last displayed
7852 echo_area_buffer as current buffer.
7853
7854 WHICH zero means use the current message buffer
7855 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7856 from echo_buffer[] and clear it.
7857
7858 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7859 suitable buffer from echo_buffer[] and clear it.
7860
7861 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
7862 that the current message becomes the last displayed one, make
7863 choose a suitable buffer for echo_area_buffer[0], and clear it.
7864
7865 Value is what FN returns. */
7866
7867 static int
7868 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7869 struct window *w;
7870 int which;
7871 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7872 EMACS_INT a1;
7873 Lisp_Object a2;
7874 EMACS_INT a3, a4;
7875 {
7876 Lisp_Object buffer;
7877 int this_one, the_other, clear_buffer_p, rc;
7878 int count = SPECPDL_INDEX ();
7879
7880 /* If buffers aren't live, make new ones. */
7881 ensure_echo_area_buffers ();
7882
7883 clear_buffer_p = 0;
7884
7885 if (which == 0)
7886 this_one = 0, the_other = 1;
7887 else if (which > 0)
7888 this_one = 1, the_other = 0;
7889 else
7890 {
7891 this_one = 0, the_other = 1;
7892 clear_buffer_p = 1;
7893
7894 /* We need a fresh one in case the current echo buffer equals
7895 the one containing the last displayed echo area message. */
7896 if (!NILP (echo_area_buffer[this_one])
7897 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7898 echo_area_buffer[this_one] = Qnil;
7899 }
7900
7901 /* Choose a suitable buffer from echo_buffer[] is we don't
7902 have one. */
7903 if (NILP (echo_area_buffer[this_one]))
7904 {
7905 echo_area_buffer[this_one]
7906 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7907 ? echo_buffer[the_other]
7908 : echo_buffer[this_one]);
7909 clear_buffer_p = 1;
7910 }
7911
7912 buffer = echo_area_buffer[this_one];
7913
7914 /* Don't get confused by reusing the buffer used for echoing
7915 for a different purpose. */
7916 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7917 cancel_echoing ();
7918
7919 record_unwind_protect (unwind_with_echo_area_buffer,
7920 with_echo_area_buffer_unwind_data (w));
7921
7922 /* Make the echo area buffer current. Note that for display
7923 purposes, it is not necessary that the displayed window's buffer
7924 == current_buffer, except for text property lookup. So, let's
7925 only set that buffer temporarily here without doing a full
7926 Fset_window_buffer. We must also change w->pointm, though,
7927 because otherwise an assertions in unshow_buffer fails, and Emacs
7928 aborts. */
7929 set_buffer_internal_1 (XBUFFER (buffer));
7930 if (w)
7931 {
7932 w->buffer = buffer;
7933 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7934 }
7935
7936 current_buffer->undo_list = Qt;
7937 current_buffer->read_only = Qnil;
7938 specbind (Qinhibit_read_only, Qt);
7939 specbind (Qinhibit_modification_hooks, Qt);
7940
7941 if (clear_buffer_p && Z > BEG)
7942 del_range (BEG, Z);
7943
7944 xassert (BEGV >= BEG);
7945 xassert (ZV <= Z && ZV >= BEGV);
7946
7947 rc = fn (a1, a2, a3, a4);
7948
7949 xassert (BEGV >= BEG);
7950 xassert (ZV <= Z && ZV >= BEGV);
7951
7952 unbind_to (count, Qnil);
7953 return rc;
7954 }
7955
7956
7957 /* Save state that should be preserved around the call to the function
7958 FN called in with_echo_area_buffer. */
7959
7960 static Lisp_Object
7961 with_echo_area_buffer_unwind_data (w)
7962 struct window *w;
7963 {
7964 int i = 0;
7965 Lisp_Object vector;
7966
7967 /* Reduce consing by keeping one vector in
7968 Vwith_echo_area_save_vector. */
7969 vector = Vwith_echo_area_save_vector;
7970 Vwith_echo_area_save_vector = Qnil;
7971
7972 if (NILP (vector))
7973 vector = Fmake_vector (make_number (7), Qnil);
7974
7975 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7976 AREF (vector, i) = Vdeactivate_mark, ++i;
7977 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7978
7979 if (w)
7980 {
7981 XSETWINDOW (AREF (vector, i), w); ++i;
7982 AREF (vector, i) = w->buffer; ++i;
7983 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7984 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7985 }
7986 else
7987 {
7988 int end = i + 4;
7989 for (; i < end; ++i)
7990 AREF (vector, i) = Qnil;
7991 }
7992
7993 xassert (i == ASIZE (vector));
7994 return vector;
7995 }
7996
7997
7998 /* Restore global state from VECTOR which was created by
7999 with_echo_area_buffer_unwind_data. */
8000
8001 static Lisp_Object
8002 unwind_with_echo_area_buffer (vector)
8003 Lisp_Object vector;
8004 {
8005 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8006 Vdeactivate_mark = AREF (vector, 1);
8007 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8008
8009 if (WINDOWP (AREF (vector, 3)))
8010 {
8011 struct window *w;
8012 Lisp_Object buffer, charpos, bytepos;
8013
8014 w = XWINDOW (AREF (vector, 3));
8015 buffer = AREF (vector, 4);
8016 charpos = AREF (vector, 5);
8017 bytepos = AREF (vector, 6);
8018
8019 w->buffer = buffer;
8020 set_marker_both (w->pointm, buffer,
8021 XFASTINT (charpos), XFASTINT (bytepos));
8022 }
8023
8024 Vwith_echo_area_save_vector = vector;
8025 return Qnil;
8026 }
8027
8028
8029 /* Set up the echo area for use by print functions. MULTIBYTE_P
8030 non-zero means we will print multibyte. */
8031
8032 void
8033 setup_echo_area_for_printing (multibyte_p)
8034 int multibyte_p;
8035 {
8036 /* If we can't find an echo area any more, exit. */
8037 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8038 Fkill_emacs (Qnil);
8039
8040 ensure_echo_area_buffers ();
8041
8042 if (!message_buf_print)
8043 {
8044 /* A message has been output since the last time we printed.
8045 Choose a fresh echo area buffer. */
8046 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8047 echo_area_buffer[0] = echo_buffer[1];
8048 else
8049 echo_area_buffer[0] = echo_buffer[0];
8050
8051 /* Switch to that buffer and clear it. */
8052 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8053 current_buffer->truncate_lines = Qnil;
8054
8055 if (Z > BEG)
8056 {
8057 int count = SPECPDL_INDEX ();
8058 specbind (Qinhibit_read_only, Qt);
8059 /* Note that undo recording is always disabled. */
8060 del_range (BEG, Z);
8061 unbind_to (count, Qnil);
8062 }
8063 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8064
8065 /* Set up the buffer for the multibyteness we need. */
8066 if (multibyte_p
8067 != !NILP (current_buffer->enable_multibyte_characters))
8068 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8069
8070 /* Raise the frame containing the echo area. */
8071 if (minibuffer_auto_raise)
8072 {
8073 struct frame *sf = SELECTED_FRAME ();
8074 Lisp_Object mini_window;
8075 mini_window = FRAME_MINIBUF_WINDOW (sf);
8076 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8077 }
8078
8079 message_log_maybe_newline ();
8080 message_buf_print = 1;
8081 }
8082 else
8083 {
8084 if (NILP (echo_area_buffer[0]))
8085 {
8086 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8087 echo_area_buffer[0] = echo_buffer[1];
8088 else
8089 echo_area_buffer[0] = echo_buffer[0];
8090 }
8091
8092 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8093 {
8094 /* Someone switched buffers between print requests. */
8095 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8096 current_buffer->truncate_lines = Qnil;
8097 }
8098 }
8099 }
8100
8101
8102 /* Display an echo area message in window W. Value is non-zero if W's
8103 height is changed. If display_last_displayed_message_p is
8104 non-zero, display the message that was last displayed, otherwise
8105 display the current message. */
8106
8107 static int
8108 display_echo_area (w)
8109 struct window *w;
8110 {
8111 int i, no_message_p, window_height_changed_p, count;
8112
8113 /* Temporarily disable garbage collections while displaying the echo
8114 area. This is done because a GC can print a message itself.
8115 That message would modify the echo area buffer's contents while a
8116 redisplay of the buffer is going on, and seriously confuse
8117 redisplay. */
8118 count = inhibit_garbage_collection ();
8119
8120 /* If there is no message, we must call display_echo_area_1
8121 nevertheless because it resizes the window. But we will have to
8122 reset the echo_area_buffer in question to nil at the end because
8123 with_echo_area_buffer will sets it to an empty buffer. */
8124 i = display_last_displayed_message_p ? 1 : 0;
8125 no_message_p = NILP (echo_area_buffer[i]);
8126
8127 window_height_changed_p
8128 = with_echo_area_buffer (w, display_last_displayed_message_p,
8129 display_echo_area_1,
8130 (EMACS_INT) w, Qnil, 0, 0);
8131
8132 if (no_message_p)
8133 echo_area_buffer[i] = Qnil;
8134
8135 unbind_to (count, Qnil);
8136 return window_height_changed_p;
8137 }
8138
8139
8140 /* Helper for display_echo_area. Display the current buffer which
8141 contains the current echo area message in window W, a mini-window,
8142 a pointer to which is passed in A1. A2..A4 are currently not used.
8143 Change the height of W so that all of the message is displayed.
8144 Value is non-zero if height of W was changed. */
8145
8146 static int
8147 display_echo_area_1 (a1, a2, a3, a4)
8148 EMACS_INT a1;
8149 Lisp_Object a2;
8150 EMACS_INT a3, a4;
8151 {
8152 struct window *w = (struct window *) a1;
8153 Lisp_Object window;
8154 struct text_pos start;
8155 int window_height_changed_p = 0;
8156
8157 /* Do this before displaying, so that we have a large enough glyph
8158 matrix for the display. If we can't get enough space for the
8159 whole text, display the last N lines. That works by setting w->start. */
8160 window_height_changed_p = resize_mini_window (w, 0);
8161
8162 /* Use the starting position chosen by resize_mini_window. */
8163 SET_TEXT_POS_FROM_MARKER (start, w->start);
8164
8165 /* Display. */
8166 clear_glyph_matrix (w->desired_matrix);
8167 XSETWINDOW (window, w);
8168 try_window (window, start, 0);
8169
8170 return window_height_changed_p;
8171 }
8172
8173
8174 /* Resize the echo area window to exactly the size needed for the
8175 currently displayed message, if there is one. If a mini-buffer
8176 is active, don't shrink it. */
8177
8178 void
8179 resize_echo_area_exactly ()
8180 {
8181 if (BUFFERP (echo_area_buffer[0])
8182 && WINDOWP (echo_area_window))
8183 {
8184 struct window *w = XWINDOW (echo_area_window);
8185 int resized_p;
8186 Lisp_Object resize_exactly;
8187
8188 if (minibuf_level == 0)
8189 resize_exactly = Qt;
8190 else
8191 resize_exactly = Qnil;
8192
8193 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8194 (EMACS_INT) w, resize_exactly, 0, 0);
8195 if (resized_p)
8196 {
8197 ++windows_or_buffers_changed;
8198 ++update_mode_lines;
8199 redisplay_internal (0);
8200 }
8201 }
8202 }
8203
8204
8205 /* Callback function for with_echo_area_buffer, when used from
8206 resize_echo_area_exactly. A1 contains a pointer to the window to
8207 resize, EXACTLY non-nil means resize the mini-window exactly to the
8208 size of the text displayed. A3 and A4 are not used. Value is what
8209 resize_mini_window returns. */
8210
8211 static int
8212 resize_mini_window_1 (a1, exactly, a3, a4)
8213 EMACS_INT a1;
8214 Lisp_Object exactly;
8215 EMACS_INT a3, a4;
8216 {
8217 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8218 }
8219
8220
8221 /* Resize mini-window W to fit the size of its contents. EXACT:P
8222 means size the window exactly to the size needed. Otherwise, it's
8223 only enlarged until W's buffer is empty.
8224
8225 Set W->start to the right place to begin display. If the whole
8226 contents fit, start at the beginning. Otherwise, start so as
8227 to make the end of the contents appear. This is particularly
8228 important for y-or-n-p, but seems desirable generally.
8229
8230 Value is non-zero if the window height has been changed. */
8231
8232 int
8233 resize_mini_window (w, exact_p)
8234 struct window *w;
8235 int exact_p;
8236 {
8237 struct frame *f = XFRAME (w->frame);
8238 int window_height_changed_p = 0;
8239
8240 xassert (MINI_WINDOW_P (w));
8241
8242 /* By default, start display at the beginning. */
8243 set_marker_both (w->start, w->buffer,
8244 BUF_BEGV (XBUFFER (w->buffer)),
8245 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8246
8247 /* Don't resize windows while redisplaying a window; it would
8248 confuse redisplay functions when the size of the window they are
8249 displaying changes from under them. Such a resizing can happen,
8250 for instance, when which-func prints a long message while
8251 we are running fontification-functions. We're running these
8252 functions with safe_call which binds inhibit-redisplay to t. */
8253 if (!NILP (Vinhibit_redisplay))
8254 return 0;
8255
8256 /* Nil means don't try to resize. */
8257 if (NILP (Vresize_mini_windows)
8258 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8259 return 0;
8260
8261 if (!FRAME_MINIBUF_ONLY_P (f))
8262 {
8263 struct it it;
8264 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8265 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8266 int height, max_height;
8267 int unit = FRAME_LINE_HEIGHT (f);
8268 struct text_pos start;
8269 struct buffer *old_current_buffer = NULL;
8270
8271 if (current_buffer != XBUFFER (w->buffer))
8272 {
8273 old_current_buffer = current_buffer;
8274 set_buffer_internal (XBUFFER (w->buffer));
8275 }
8276
8277 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8278
8279 /* Compute the max. number of lines specified by the user. */
8280 if (FLOATP (Vmax_mini_window_height))
8281 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8282 else if (INTEGERP (Vmax_mini_window_height))
8283 max_height = XINT (Vmax_mini_window_height);
8284 else
8285 max_height = total_height / 4;
8286
8287 /* Correct that max. height if it's bogus. */
8288 max_height = max (1, max_height);
8289 max_height = min (total_height, max_height);
8290
8291 /* Find out the height of the text in the window. */
8292 if (it.truncate_lines_p)
8293 height = 1;
8294 else
8295 {
8296 last_height = 0;
8297 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
8298 if (it.max_ascent == 0 && it.max_descent == 0)
8299 height = it.current_y + last_height;
8300 else
8301 height = it.current_y + it.max_ascent + it.max_descent;
8302 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
8303 height = (height + unit - 1) / unit;
8304 }
8305
8306 /* Compute a suitable window start. */
8307 if (height > max_height)
8308 {
8309 height = max_height;
8310 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
8311 move_it_vertically_backward (&it, (height - 1) * unit);
8312 start = it.current.pos;
8313 }
8314 else
8315 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
8316 SET_MARKER_FROM_TEXT_POS (w->start, start);
8317
8318 if (EQ (Vresize_mini_windows, Qgrow_only))
8319 {
8320 /* Let it grow only, until we display an empty message, in which
8321 case the window shrinks again. */
8322 if (height > WINDOW_TOTAL_LINES (w))
8323 {
8324 int old_height = WINDOW_TOTAL_LINES (w);
8325 freeze_window_starts (f, 1);
8326 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8327 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8328 }
8329 else if (height < WINDOW_TOTAL_LINES (w)
8330 && (exact_p || BEGV == ZV))
8331 {
8332 int old_height = WINDOW_TOTAL_LINES (w);
8333 freeze_window_starts (f, 0);
8334 shrink_mini_window (w);
8335 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8336 }
8337 }
8338 else
8339 {
8340 /* Always resize to exact size needed. */
8341 if (height > WINDOW_TOTAL_LINES (w))
8342 {
8343 int old_height = WINDOW_TOTAL_LINES (w);
8344 freeze_window_starts (f, 1);
8345 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8346 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8347 }
8348 else if (height < WINDOW_TOTAL_LINES (w))
8349 {
8350 int old_height = WINDOW_TOTAL_LINES (w);
8351 freeze_window_starts (f, 0);
8352 shrink_mini_window (w);
8353
8354 if (height)
8355 {
8356 freeze_window_starts (f, 1);
8357 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8358 }
8359
8360 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8361 }
8362 }
8363
8364 if (old_current_buffer)
8365 set_buffer_internal (old_current_buffer);
8366 }
8367
8368 return window_height_changed_p;
8369 }
8370
8371
8372 /* Value is the current message, a string, or nil if there is no
8373 current message. */
8374
8375 Lisp_Object
8376 current_message ()
8377 {
8378 Lisp_Object msg;
8379
8380 if (NILP (echo_area_buffer[0]))
8381 msg = Qnil;
8382 else
8383 {
8384 with_echo_area_buffer (0, 0, current_message_1,
8385 (EMACS_INT) &msg, Qnil, 0, 0);
8386 if (NILP (msg))
8387 echo_area_buffer[0] = Qnil;
8388 }
8389
8390 return msg;
8391 }
8392
8393
8394 static int
8395 current_message_1 (a1, a2, a3, a4)
8396 EMACS_INT a1;
8397 Lisp_Object a2;
8398 EMACS_INT a3, a4;
8399 {
8400 Lisp_Object *msg = (Lisp_Object *) a1;
8401
8402 if (Z > BEG)
8403 *msg = make_buffer_string (BEG, Z, 1);
8404 else
8405 *msg = Qnil;
8406 return 0;
8407 }
8408
8409
8410 /* Push the current message on Vmessage_stack for later restauration
8411 by restore_message. Value is non-zero if the current message isn't
8412 empty. This is a relatively infrequent operation, so it's not
8413 worth optimizing. */
8414
8415 int
8416 push_message ()
8417 {
8418 Lisp_Object msg;
8419 msg = current_message ();
8420 Vmessage_stack = Fcons (msg, Vmessage_stack);
8421 return STRINGP (msg);
8422 }
8423
8424
8425 /* Restore message display from the top of Vmessage_stack. */
8426
8427 void
8428 restore_message ()
8429 {
8430 Lisp_Object msg;
8431
8432 xassert (CONSP (Vmessage_stack));
8433 msg = XCAR (Vmessage_stack);
8434 if (STRINGP (msg))
8435 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8436 else
8437 message3_nolog (msg, 0, 0);
8438 }
8439
8440
8441 /* Handler for record_unwind_protect calling pop_message. */
8442
8443 Lisp_Object
8444 pop_message_unwind (dummy)
8445 Lisp_Object dummy;
8446 {
8447 pop_message ();
8448 return Qnil;
8449 }
8450
8451 /* Pop the top-most entry off Vmessage_stack. */
8452
8453 void
8454 pop_message ()
8455 {
8456 xassert (CONSP (Vmessage_stack));
8457 Vmessage_stack = XCDR (Vmessage_stack);
8458 }
8459
8460
8461 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
8462 exits. If the stack is not empty, we have a missing pop_message
8463 somewhere. */
8464
8465 void
8466 check_message_stack ()
8467 {
8468 if (!NILP (Vmessage_stack))
8469 abort ();
8470 }
8471
8472
8473 /* Truncate to NCHARS what will be displayed in the echo area the next
8474 time we display it---but don't redisplay it now. */
8475
8476 void
8477 truncate_echo_area (nchars)
8478 int nchars;
8479 {
8480 if (nchars == 0)
8481 echo_area_buffer[0] = Qnil;
8482 /* A null message buffer means that the frame hasn't really been
8483 initialized yet. Error messages get reported properly by
8484 cmd_error, so this must be just an informative message; toss it. */
8485 else if (!noninteractive
8486 && INTERACTIVE
8487 && !NILP (echo_area_buffer[0]))
8488 {
8489 struct frame *sf = SELECTED_FRAME ();
8490 if (FRAME_MESSAGE_BUF (sf))
8491 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
8492 }
8493 }
8494
8495
8496 /* Helper function for truncate_echo_area. Truncate the current
8497 message to at most NCHARS characters. */
8498
8499 static int
8500 truncate_message_1 (nchars, a2, a3, a4)
8501 EMACS_INT nchars;
8502 Lisp_Object a2;
8503 EMACS_INT a3, a4;
8504 {
8505 if (BEG + nchars < Z)
8506 del_range (BEG + nchars, Z);
8507 if (Z == BEG)
8508 echo_area_buffer[0] = Qnil;
8509 return 0;
8510 }
8511
8512
8513 /* Set the current message to a substring of S or STRING.
8514
8515 If STRING is a Lisp string, set the message to the first NBYTES
8516 bytes from STRING. NBYTES zero means use the whole string. If
8517 STRING is multibyte, the message will be displayed multibyte.
8518
8519 If S is not null, set the message to the first LEN bytes of S. LEN
8520 zero means use the whole string. MULTIBYTE_P non-zero means S is
8521 multibyte. Display the message multibyte in that case.
8522
8523 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
8524 to t before calling set_message_1 (which calls insert).
8525 */
8526
8527 void
8528 set_message (s, string, nbytes, multibyte_p)
8529 const char *s;
8530 Lisp_Object string;
8531 int nbytes, multibyte_p;
8532 {
8533 message_enable_multibyte
8534 = ((s && multibyte_p)
8535 || (STRINGP (string) && STRING_MULTIBYTE (string)));
8536
8537 with_echo_area_buffer (0, -1, set_message_1,
8538 (EMACS_INT) s, string, nbytes, multibyte_p);
8539 message_buf_print = 0;
8540 help_echo_showing_p = 0;
8541 }
8542
8543
8544 /* Helper function for set_message. Arguments have the same meaning
8545 as there, with A1 corresponding to S and A2 corresponding to STRING
8546 This function is called with the echo area buffer being
8547 current. */
8548
8549 static int
8550 set_message_1 (a1, a2, nbytes, multibyte_p)
8551 EMACS_INT a1;
8552 Lisp_Object a2;
8553 EMACS_INT nbytes, multibyte_p;
8554 {
8555 const char *s = (const char *) a1;
8556 Lisp_Object string = a2;
8557
8558 /* Change multibyteness of the echo buffer appropriately. */
8559 if (message_enable_multibyte
8560 != !NILP (current_buffer->enable_multibyte_characters))
8561 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
8562
8563 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
8564
8565 /* Insert new message at BEG. */
8566 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8567
8568 if (STRINGP (string))
8569 {
8570 int nchars;
8571
8572 if (nbytes == 0)
8573 nbytes = SBYTES (string);
8574 nchars = string_byte_to_char (string, nbytes);
8575
8576 /* This function takes care of single/multibyte conversion. We
8577 just have to ensure that the echo area buffer has the right
8578 setting of enable_multibyte_characters. */
8579 insert_from_string (string, 0, 0, nchars, nbytes, 1);
8580 }
8581 else if (s)
8582 {
8583 if (nbytes == 0)
8584 nbytes = strlen (s);
8585
8586 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
8587 {
8588 /* Convert from multi-byte to single-byte. */
8589 int i, c, n;
8590 unsigned char work[1];
8591
8592 /* Convert a multibyte string to single-byte. */
8593 for (i = 0; i < nbytes; i += n)
8594 {
8595 c = string_char_and_length (s + i, nbytes - i, &n);
8596 work[0] = (SINGLE_BYTE_CHAR_P (c)
8597 ? c
8598 : multibyte_char_to_unibyte (c, Qnil));
8599 insert_1_both (work, 1, 1, 1, 0, 0);
8600 }
8601 }
8602 else if (!multibyte_p
8603 && !NILP (current_buffer->enable_multibyte_characters))
8604 {
8605 /* Convert from single-byte to multi-byte. */
8606 int i, c, n;
8607 const unsigned char *msg = (const unsigned char *) s;
8608 unsigned char str[MAX_MULTIBYTE_LENGTH];
8609
8610 /* Convert a single-byte string to multibyte. */
8611 for (i = 0; i < nbytes; i++)
8612 {
8613 c = unibyte_char_to_multibyte (msg[i]);
8614 n = CHAR_STRING (c, str);
8615 insert_1_both (str, 1, n, 1, 0, 0);
8616 }
8617 }
8618 else
8619 insert_1 (s, nbytes, 1, 0, 0);
8620 }
8621
8622 return 0;
8623 }
8624
8625
8626 /* Clear messages. CURRENT_P non-zero means clear the current
8627 message. LAST_DISPLAYED_P non-zero means clear the message
8628 last displayed. */
8629
8630 void
8631 clear_message (current_p, last_displayed_p)
8632 int current_p, last_displayed_p;
8633 {
8634 if (current_p)
8635 {
8636 echo_area_buffer[0] = Qnil;
8637 message_cleared_p = 1;
8638 }
8639
8640 if (last_displayed_p)
8641 echo_area_buffer[1] = Qnil;
8642
8643 message_buf_print = 0;
8644 }
8645
8646 /* Clear garbaged frames.
8647
8648 This function is used where the old redisplay called
8649 redraw_garbaged_frames which in turn called redraw_frame which in
8650 turn called clear_frame. The call to clear_frame was a source of
8651 flickering. I believe a clear_frame is not necessary. It should
8652 suffice in the new redisplay to invalidate all current matrices,
8653 and ensure a complete redisplay of all windows. */
8654
8655 static void
8656 clear_garbaged_frames ()
8657 {
8658 if (frame_garbaged)
8659 {
8660 Lisp_Object tail, frame;
8661 int changed_count = 0;
8662
8663 FOR_EACH_FRAME (tail, frame)
8664 {
8665 struct frame *f = XFRAME (frame);
8666
8667 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8668 {
8669 if (f->resized_p)
8670 {
8671 Fredraw_frame (frame);
8672 f->force_flush_display_p = 1;
8673 }
8674 clear_current_matrices (f);
8675 changed_count++;
8676 f->garbaged = 0;
8677 f->resized_p = 0;
8678 }
8679 }
8680
8681 frame_garbaged = 0;
8682 if (changed_count)
8683 ++windows_or_buffers_changed;
8684 }
8685 }
8686
8687
8688 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8689 is non-zero update selected_frame. Value is non-zero if the
8690 mini-windows height has been changed. */
8691
8692 static int
8693 echo_area_display (update_frame_p)
8694 int update_frame_p;
8695 {
8696 Lisp_Object mini_window;
8697 struct window *w;
8698 struct frame *f;
8699 int window_height_changed_p = 0;
8700 struct frame *sf = SELECTED_FRAME ();
8701
8702 mini_window = FRAME_MINIBUF_WINDOW (sf);
8703 w = XWINDOW (mini_window);
8704 f = XFRAME (WINDOW_FRAME (w));
8705
8706 /* Don't display if frame is invisible or not yet initialized. */
8707 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8708 return 0;
8709
8710 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8711 #ifndef MAC_OS8
8712 #ifdef HAVE_WINDOW_SYSTEM
8713 /* When Emacs starts, selected_frame may be the initial terminal
8714 frame. If we let this through, a message would be displayed on
8715 the terminal. */
8716 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
8717 return 0;
8718 #endif /* HAVE_WINDOW_SYSTEM */
8719 #endif
8720
8721 /* Redraw garbaged frames. */
8722 if (frame_garbaged)
8723 clear_garbaged_frames ();
8724
8725 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8726 {
8727 echo_area_window = mini_window;
8728 window_height_changed_p = display_echo_area (w);
8729 w->must_be_updated_p = 1;
8730
8731 /* Update the display, unless called from redisplay_internal.
8732 Also don't update the screen during redisplay itself. The
8733 update will happen at the end of redisplay, and an update
8734 here could cause confusion. */
8735 if (update_frame_p && !redisplaying_p)
8736 {
8737 int n = 0;
8738
8739 /* If the display update has been interrupted by pending
8740 input, update mode lines in the frame. Due to the
8741 pending input, it might have been that redisplay hasn't
8742 been called, so that mode lines above the echo area are
8743 garbaged. This looks odd, so we prevent it here. */
8744 if (!display_completed)
8745 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8746
8747 if (window_height_changed_p
8748 /* Don't do this if Emacs is shutting down. Redisplay
8749 needs to run hooks. */
8750 && !NILP (Vrun_hooks))
8751 {
8752 /* Must update other windows. Likewise as in other
8753 cases, don't let this update be interrupted by
8754 pending input. */
8755 int count = SPECPDL_INDEX ();
8756 specbind (Qredisplay_dont_pause, Qt);
8757 windows_or_buffers_changed = 1;
8758 redisplay_internal (0);
8759 unbind_to (count, Qnil);
8760 }
8761 else if (FRAME_WINDOW_P (f) && n == 0)
8762 {
8763 /* Window configuration is the same as before.
8764 Can do with a display update of the echo area,
8765 unless we displayed some mode lines. */
8766 update_single_window (w, 1);
8767 FRAME_RIF (f)->flush_display (f);
8768 }
8769 else
8770 update_frame (f, 1, 1);
8771
8772 /* If cursor is in the echo area, make sure that the next
8773 redisplay displays the minibuffer, so that the cursor will
8774 be replaced with what the minibuffer wants. */
8775 if (cursor_in_echo_area)
8776 ++windows_or_buffers_changed;
8777 }
8778 }
8779 else if (!EQ (mini_window, selected_window))
8780 windows_or_buffers_changed++;
8781
8782 /* Last displayed message is now the current message. */
8783 echo_area_buffer[1] = echo_area_buffer[0];
8784 /* Inform read_char that we're not echoing. */
8785 echo_message_buffer = Qnil;
8786
8787 /* Prevent redisplay optimization in redisplay_internal by resetting
8788 this_line_start_pos. This is done because the mini-buffer now
8789 displays the message instead of its buffer text. */
8790 if (EQ (mini_window, selected_window))
8791 CHARPOS (this_line_start_pos) = 0;
8792
8793 return window_height_changed_p;
8794 }
8795
8796
8797 \f
8798 /***********************************************************************
8799 Mode Lines and Frame Titles
8800 ***********************************************************************/
8801
8802 /* A buffer for constructing non-propertized mode-line strings and
8803 frame titles in it; allocated from the heap in init_xdisp and
8804 resized as needed in store_mode_line_noprop_char. */
8805
8806 static char *mode_line_noprop_buf;
8807
8808 /* The buffer's end, and a current output position in it. */
8809
8810 static char *mode_line_noprop_buf_end;
8811 static char *mode_line_noprop_ptr;
8812
8813 #define MODE_LINE_NOPROP_LEN(start) \
8814 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
8815
8816 static enum {
8817 MODE_LINE_DISPLAY = 0,
8818 MODE_LINE_TITLE,
8819 MODE_LINE_NOPROP,
8820 MODE_LINE_STRING
8821 } mode_line_target;
8822
8823 /* Alist that caches the results of :propertize.
8824 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
8825 static Lisp_Object mode_line_proptrans_alist;
8826
8827 /* List of strings making up the mode-line. */
8828 static Lisp_Object mode_line_string_list;
8829
8830 /* Base face property when building propertized mode line string. */
8831 static Lisp_Object mode_line_string_face;
8832 static Lisp_Object mode_line_string_face_prop;
8833
8834
8835 /* Unwind data for mode line strings */
8836
8837 static Lisp_Object Vmode_line_unwind_vector;
8838
8839 static Lisp_Object
8840 format_mode_line_unwind_data (obuf, save_proptrans)
8841 struct buffer *obuf;
8842 {
8843 Lisp_Object vector;
8844
8845 /* Reduce consing by keeping one vector in
8846 Vwith_echo_area_save_vector. */
8847 vector = Vmode_line_unwind_vector;
8848 Vmode_line_unwind_vector = Qnil;
8849
8850 if (NILP (vector))
8851 vector = Fmake_vector (make_number (7), Qnil);
8852
8853 AREF (vector, 0) = make_number (mode_line_target);
8854 AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
8855 AREF (vector, 2) = mode_line_string_list;
8856 AREF (vector, 3) = (save_proptrans ? mode_line_proptrans_alist : Qt);
8857 AREF (vector, 4) = mode_line_string_face;
8858 AREF (vector, 5) = mode_line_string_face_prop;
8859
8860 if (obuf)
8861 XSETBUFFER (AREF (vector, 6), obuf);
8862 else
8863 AREF (vector, 6) = Qnil;
8864
8865 return vector;
8866 }
8867
8868 static Lisp_Object
8869 unwind_format_mode_line (vector)
8870 Lisp_Object vector;
8871 {
8872 mode_line_target = XINT (AREF (vector, 0));
8873 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
8874 mode_line_string_list = AREF (vector, 2);
8875 if (! EQ (AREF (vector, 3), Qt))
8876 mode_line_proptrans_alist = AREF (vector, 3);
8877 mode_line_string_face = AREF (vector, 4);
8878 mode_line_string_face_prop = AREF (vector, 5);
8879
8880 if (!NILP (AREF (vector, 6)))
8881 {
8882 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
8883 AREF (vector, 6) = Qnil;
8884 }
8885
8886 Vmode_line_unwind_vector = vector;
8887 return Qnil;
8888 }
8889
8890
8891 /* Store a single character C for the frame title in mode_line_noprop_buf.
8892 Re-allocate mode_line_noprop_buf if necessary. */
8893
8894 static void
8895 #ifdef PROTOTYPES
8896 store_mode_line_noprop_char (char c)
8897 #else
8898 store_mode_line_noprop_char (c)
8899 char c;
8900 #endif
8901 {
8902 /* If output position has reached the end of the allocated buffer,
8903 double the buffer's size. */
8904 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
8905 {
8906 int len = MODE_LINE_NOPROP_LEN (0);
8907 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
8908 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
8909 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
8910 mode_line_noprop_ptr = mode_line_noprop_buf + len;
8911 }
8912
8913 *mode_line_noprop_ptr++ = c;
8914 }
8915
8916
8917 /* Store part of a frame title in mode_line_noprop_buf, beginning at
8918 mode_line_noprop_ptr. STR is the string to store. Do not copy
8919 characters that yield more columns than PRECISION; PRECISION <= 0
8920 means copy the whole string. Pad with spaces until FIELD_WIDTH
8921 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8922 pad. Called from display_mode_element when it is used to build a
8923 frame title. */
8924
8925 static int
8926 store_mode_line_noprop (str, field_width, precision)
8927 const unsigned char *str;
8928 int field_width, precision;
8929 {
8930 int n = 0;
8931 int dummy, nbytes;
8932
8933 /* Copy at most PRECISION chars from STR. */
8934 nbytes = strlen (str);
8935 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8936 while (nbytes--)
8937 store_mode_line_noprop_char (*str++);
8938
8939 /* Fill up with spaces until FIELD_WIDTH reached. */
8940 while (field_width > 0
8941 && n < field_width)
8942 {
8943 store_mode_line_noprop_char (' ');
8944 ++n;
8945 }
8946
8947 return n;
8948 }
8949
8950 /***********************************************************************
8951 Frame Titles
8952 ***********************************************************************/
8953
8954 #ifdef HAVE_WINDOW_SYSTEM
8955
8956 /* Set the title of FRAME, if it has changed. The title format is
8957 Vicon_title_format if FRAME is iconified, otherwise it is
8958 frame_title_format. */
8959
8960 static void
8961 x_consider_frame_title (frame)
8962 Lisp_Object frame;
8963 {
8964 struct frame *f = XFRAME (frame);
8965
8966 if (FRAME_WINDOW_P (f)
8967 || FRAME_MINIBUF_ONLY_P (f)
8968 || f->explicit_name)
8969 {
8970 /* Do we have more than one visible frame on this X display? */
8971 Lisp_Object tail;
8972 Lisp_Object fmt;
8973 int title_start;
8974 char *title;
8975 int len;
8976 struct it it;
8977 int count = SPECPDL_INDEX ();
8978
8979 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8980 {
8981 Lisp_Object other_frame = XCAR (tail);
8982 struct frame *tf = XFRAME (other_frame);
8983
8984 if (tf != f
8985 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8986 && !FRAME_MINIBUF_ONLY_P (tf)
8987 && !EQ (other_frame, tip_frame)
8988 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8989 break;
8990 }
8991
8992 /* Set global variable indicating that multiple frames exist. */
8993 multiple_frames = CONSP (tail);
8994
8995 /* Switch to the buffer of selected window of the frame. Set up
8996 mode_line_target so that display_mode_element will output into
8997 mode_line_noprop_buf; then display the title. */
8998 record_unwind_protect (unwind_format_mode_line,
8999 format_mode_line_unwind_data (current_buffer, 0));
9000
9001 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9002 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9003
9004 mode_line_target = MODE_LINE_TITLE;
9005 title_start = MODE_LINE_NOPROP_LEN (0);
9006 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9007 NULL, DEFAULT_FACE_ID);
9008 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9009 len = MODE_LINE_NOPROP_LEN (title_start);
9010 title = mode_line_noprop_buf + title_start;
9011 unbind_to (count, Qnil);
9012
9013 /* Set the title only if it's changed. This avoids consing in
9014 the common case where it hasn't. (If it turns out that we've
9015 already wasted too much time by walking through the list with
9016 display_mode_element, then we might need to optimize at a
9017 higher level than this.) */
9018 if (! STRINGP (f->name)
9019 || SBYTES (f->name) != len
9020 || bcmp (title, SDATA (f->name), len) != 0)
9021 x_implicitly_set_name (f, make_string (title, len), Qnil);
9022 }
9023 }
9024
9025 #endif /* not HAVE_WINDOW_SYSTEM */
9026
9027
9028
9029 \f
9030 /***********************************************************************
9031 Menu Bars
9032 ***********************************************************************/
9033
9034
9035 /* Prepare for redisplay by updating menu-bar item lists when
9036 appropriate. This can call eval. */
9037
9038 void
9039 prepare_menu_bars ()
9040 {
9041 int all_windows;
9042 struct gcpro gcpro1, gcpro2;
9043 struct frame *f;
9044 Lisp_Object tooltip_frame;
9045
9046 #ifdef HAVE_WINDOW_SYSTEM
9047 tooltip_frame = tip_frame;
9048 #else
9049 tooltip_frame = Qnil;
9050 #endif
9051
9052 /* Update all frame titles based on their buffer names, etc. We do
9053 this before the menu bars so that the buffer-menu will show the
9054 up-to-date frame titles. */
9055 #ifdef HAVE_WINDOW_SYSTEM
9056 if (windows_or_buffers_changed || update_mode_lines)
9057 {
9058 Lisp_Object tail, frame;
9059
9060 FOR_EACH_FRAME (tail, frame)
9061 {
9062 f = XFRAME (frame);
9063 if (!EQ (frame, tooltip_frame)
9064 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9065 x_consider_frame_title (frame);
9066 }
9067 }
9068 #endif /* HAVE_WINDOW_SYSTEM */
9069
9070 /* Update the menu bar item lists, if appropriate. This has to be
9071 done before any actual redisplay or generation of display lines. */
9072 all_windows = (update_mode_lines
9073 || buffer_shared > 1
9074 || windows_or_buffers_changed);
9075 if (all_windows)
9076 {
9077 Lisp_Object tail, frame;
9078 int count = SPECPDL_INDEX ();
9079 /* 1 means that update_menu_bar has run its hooks
9080 so any further calls to update_menu_bar shouldn't do so again. */
9081 int menu_bar_hooks_run = 0;
9082
9083 record_unwind_save_match_data ();
9084
9085 FOR_EACH_FRAME (tail, frame)
9086 {
9087 f = XFRAME (frame);
9088
9089 /* Ignore tooltip frame. */
9090 if (EQ (frame, tooltip_frame))
9091 continue;
9092
9093 /* If a window on this frame changed size, report that to
9094 the user and clear the size-change flag. */
9095 if (FRAME_WINDOW_SIZES_CHANGED (f))
9096 {
9097 Lisp_Object functions;
9098
9099 /* Clear flag first in case we get an error below. */
9100 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9101 functions = Vwindow_size_change_functions;
9102 GCPRO2 (tail, functions);
9103
9104 while (CONSP (functions))
9105 {
9106 call1 (XCAR (functions), frame);
9107 functions = XCDR (functions);
9108 }
9109 UNGCPRO;
9110 }
9111
9112 GCPRO1 (tail);
9113 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9114 #ifdef HAVE_WINDOW_SYSTEM
9115 update_tool_bar (f, 0);
9116 #ifdef MAC_OS
9117 mac_update_title_bar (f, 0);
9118 #endif
9119 #endif
9120 UNGCPRO;
9121 }
9122
9123 unbind_to (count, Qnil);
9124 }
9125 else
9126 {
9127 struct frame *sf = SELECTED_FRAME ();
9128 update_menu_bar (sf, 1, 0);
9129 #ifdef HAVE_WINDOW_SYSTEM
9130 update_tool_bar (sf, 1);
9131 #ifdef MAC_OS
9132 mac_update_title_bar (sf, 1);
9133 #endif
9134 #endif
9135 }
9136
9137 /* Motif needs this. See comment in xmenu.c. Turn it off when
9138 pending_menu_activation is not defined. */
9139 #ifdef USE_X_TOOLKIT
9140 pending_menu_activation = 0;
9141 #endif
9142 }
9143
9144
9145 /* Update the menu bar item list for frame F. This has to be done
9146 before we start to fill in any display lines, because it can call
9147 eval.
9148
9149 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9150
9151 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9152 already ran the menu bar hooks for this redisplay, so there
9153 is no need to run them again. The return value is the
9154 updated value of this flag, to pass to the next call. */
9155
9156 static int
9157 update_menu_bar (f, save_match_data, hooks_run)
9158 struct frame *f;
9159 int save_match_data;
9160 int hooks_run;
9161 {
9162 Lisp_Object window;
9163 register struct window *w;
9164
9165 /* If called recursively during a menu update, do nothing. This can
9166 happen when, for instance, an activate-menubar-hook causes a
9167 redisplay. */
9168 if (inhibit_menubar_update)
9169 return hooks_run;
9170
9171 window = FRAME_SELECTED_WINDOW (f);
9172 w = XWINDOW (window);
9173
9174 #if 0 /* The if statement below this if statement used to include the
9175 condition !NILP (w->update_mode_line), rather than using
9176 update_mode_lines directly, and this if statement may have
9177 been added to make that condition work. Now the if
9178 statement below matches its comment, this isn't needed. */
9179 if (update_mode_lines)
9180 w->update_mode_line = Qt;
9181 #endif
9182
9183 if (FRAME_WINDOW_P (f)
9184 ?
9185 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9186 || defined (USE_GTK)
9187 FRAME_EXTERNAL_MENU_BAR (f)
9188 #else
9189 FRAME_MENU_BAR_LINES (f) > 0
9190 #endif
9191 : FRAME_MENU_BAR_LINES (f) > 0)
9192 {
9193 /* If the user has switched buffers or windows, we need to
9194 recompute to reflect the new bindings. But we'll
9195 recompute when update_mode_lines is set too; that means
9196 that people can use force-mode-line-update to request
9197 that the menu bar be recomputed. The adverse effect on
9198 the rest of the redisplay algorithm is about the same as
9199 windows_or_buffers_changed anyway. */
9200 if (windows_or_buffers_changed
9201 /* This used to test w->update_mode_line, but we believe
9202 there is no need to recompute the menu in that case. */
9203 || update_mode_lines
9204 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9205 < BUF_MODIFF (XBUFFER (w->buffer)))
9206 != !NILP (w->last_had_star))
9207 || ((!NILP (Vtransient_mark_mode)
9208 && !NILP (XBUFFER (w->buffer)->mark_active))
9209 != !NILP (w->region_showing)))
9210 {
9211 struct buffer *prev = current_buffer;
9212 int count = SPECPDL_INDEX ();
9213
9214 specbind (Qinhibit_menubar_update, Qt);
9215
9216 set_buffer_internal_1 (XBUFFER (w->buffer));
9217 if (save_match_data)
9218 record_unwind_save_match_data ();
9219 if (NILP (Voverriding_local_map_menu_flag))
9220 {
9221 specbind (Qoverriding_terminal_local_map, Qnil);
9222 specbind (Qoverriding_local_map, Qnil);
9223 }
9224
9225 if (!hooks_run)
9226 {
9227 /* Run the Lucid hook. */
9228 safe_run_hooks (Qactivate_menubar_hook);
9229
9230 /* If it has changed current-menubar from previous value,
9231 really recompute the menu-bar from the value. */
9232 if (! NILP (Vlucid_menu_bar_dirty_flag))
9233 call0 (Qrecompute_lucid_menubar);
9234
9235 safe_run_hooks (Qmenu_bar_update_hook);
9236
9237 hooks_run = 1;
9238 }
9239
9240 XSETFRAME (Vmenu_updating_frame, f);
9241 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9242
9243 /* Redisplay the menu bar in case we changed it. */
9244 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9245 || defined (USE_GTK)
9246 if (FRAME_WINDOW_P (f))
9247 {
9248 #ifdef MAC_OS
9249 /* All frames on Mac OS share the same menubar. So only
9250 the selected frame should be allowed to set it. */
9251 if (f == SELECTED_FRAME ())
9252 #endif
9253 set_frame_menubar (f, 0, 0);
9254 }
9255 else
9256 /* On a terminal screen, the menu bar is an ordinary screen
9257 line, and this makes it get updated. */
9258 w->update_mode_line = Qt;
9259 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9260 /* In the non-toolkit version, the menu bar is an ordinary screen
9261 line, and this makes it get updated. */
9262 w->update_mode_line = Qt;
9263 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9264
9265 unbind_to (count, Qnil);
9266 set_buffer_internal_1 (prev);
9267 }
9268 }
9269
9270 return hooks_run;
9271 }
9272
9273
9274 \f
9275 /***********************************************************************
9276 Output Cursor
9277 ***********************************************************************/
9278
9279 #ifdef HAVE_WINDOW_SYSTEM
9280
9281 /* EXPORT:
9282 Nominal cursor position -- where to draw output.
9283 HPOS and VPOS are window relative glyph matrix coordinates.
9284 X and Y are window relative pixel coordinates. */
9285
9286 struct cursor_pos output_cursor;
9287
9288
9289 /* EXPORT:
9290 Set the global variable output_cursor to CURSOR. All cursor
9291 positions are relative to updated_window. */
9292
9293 void
9294 set_output_cursor (cursor)
9295 struct cursor_pos *cursor;
9296 {
9297 output_cursor.hpos = cursor->hpos;
9298 output_cursor.vpos = cursor->vpos;
9299 output_cursor.x = cursor->x;
9300 output_cursor.y = cursor->y;
9301 }
9302
9303
9304 /* EXPORT for RIF:
9305 Set a nominal cursor position.
9306
9307 HPOS and VPOS are column/row positions in a window glyph matrix. X
9308 and Y are window text area relative pixel positions.
9309
9310 If this is done during an update, updated_window will contain the
9311 window that is being updated and the position is the future output
9312 cursor position for that window. If updated_window is null, use
9313 selected_window and display the cursor at the given position. */
9314
9315 void
9316 x_cursor_to (vpos, hpos, y, x)
9317 int vpos, hpos, y, x;
9318 {
9319 struct window *w;
9320
9321 /* If updated_window is not set, work on selected_window. */
9322 if (updated_window)
9323 w = updated_window;
9324 else
9325 w = XWINDOW (selected_window);
9326
9327 /* Set the output cursor. */
9328 output_cursor.hpos = hpos;
9329 output_cursor.vpos = vpos;
9330 output_cursor.x = x;
9331 output_cursor.y = y;
9332
9333 /* If not called as part of an update, really display the cursor.
9334 This will also set the cursor position of W. */
9335 if (updated_window == NULL)
9336 {
9337 BLOCK_INPUT;
9338 display_and_set_cursor (w, 1, hpos, vpos, x, y);
9339 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
9340 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
9341 UNBLOCK_INPUT;
9342 }
9343 }
9344
9345 #endif /* HAVE_WINDOW_SYSTEM */
9346
9347 \f
9348 /***********************************************************************
9349 Tool-bars
9350 ***********************************************************************/
9351
9352 #ifdef HAVE_WINDOW_SYSTEM
9353
9354 /* Where the mouse was last time we reported a mouse event. */
9355
9356 FRAME_PTR last_mouse_frame;
9357
9358 /* Tool-bar item index of the item on which a mouse button was pressed
9359 or -1. */
9360
9361 int last_tool_bar_item;
9362
9363
9364 /* Update the tool-bar item list for frame F. This has to be done
9365 before we start to fill in any display lines. Called from
9366 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9367 and restore it here. */
9368
9369 static void
9370 update_tool_bar (f, save_match_data)
9371 struct frame *f;
9372 int save_match_data;
9373 {
9374 #if defined (USE_GTK) || USE_MAC_TOOLBAR
9375 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
9376 #else
9377 int do_update = WINDOWP (f->tool_bar_window)
9378 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
9379 #endif
9380
9381 if (do_update)
9382 {
9383 Lisp_Object window;
9384 struct window *w;
9385
9386 window = FRAME_SELECTED_WINDOW (f);
9387 w = XWINDOW (window);
9388
9389 /* If the user has switched buffers or windows, we need to
9390 recompute to reflect the new bindings. But we'll
9391 recompute when update_mode_lines is set too; that means
9392 that people can use force-mode-line-update to request
9393 that the menu bar be recomputed. The adverse effect on
9394 the rest of the redisplay algorithm is about the same as
9395 windows_or_buffers_changed anyway. */
9396 if (windows_or_buffers_changed
9397 || !NILP (w->update_mode_line)
9398 || update_mode_lines
9399 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9400 < BUF_MODIFF (XBUFFER (w->buffer)))
9401 != !NILP (w->last_had_star))
9402 || ((!NILP (Vtransient_mark_mode)
9403 && !NILP (XBUFFER (w->buffer)->mark_active))
9404 != !NILP (w->region_showing)))
9405 {
9406 struct buffer *prev = current_buffer;
9407 int count = SPECPDL_INDEX ();
9408 Lisp_Object new_tool_bar;
9409 int new_n_tool_bar;
9410 struct gcpro gcpro1;
9411
9412 /* Set current_buffer to the buffer of the selected
9413 window of the frame, so that we get the right local
9414 keymaps. */
9415 set_buffer_internal_1 (XBUFFER (w->buffer));
9416
9417 /* Save match data, if we must. */
9418 if (save_match_data)
9419 record_unwind_save_match_data ();
9420
9421 /* Make sure that we don't accidentally use bogus keymaps. */
9422 if (NILP (Voverriding_local_map_menu_flag))
9423 {
9424 specbind (Qoverriding_terminal_local_map, Qnil);
9425 specbind (Qoverriding_local_map, Qnil);
9426 }
9427
9428 GCPRO1 (new_tool_bar);
9429
9430 /* Build desired tool-bar items from keymaps. */
9431 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
9432 &new_n_tool_bar);
9433
9434 /* Redisplay the tool-bar if we changed it. */
9435 if (new_n_tool_bar != f->n_tool_bar_items
9436 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
9437 {
9438 /* Redisplay that happens asynchronously due to an expose event
9439 may access f->tool_bar_items. Make sure we update both
9440 variables within BLOCK_INPUT so no such event interrupts. */
9441 BLOCK_INPUT;
9442 f->tool_bar_items = new_tool_bar;
9443 f->n_tool_bar_items = new_n_tool_bar;
9444 w->update_mode_line = Qt;
9445 UNBLOCK_INPUT;
9446 }
9447
9448 UNGCPRO;
9449
9450 unbind_to (count, Qnil);
9451 set_buffer_internal_1 (prev);
9452 }
9453 }
9454 }
9455
9456
9457 /* Set F->desired_tool_bar_string to a Lisp string representing frame
9458 F's desired tool-bar contents. F->tool_bar_items must have
9459 been set up previously by calling prepare_menu_bars. */
9460
9461 static void
9462 build_desired_tool_bar_string (f)
9463 struct frame *f;
9464 {
9465 int i, size, size_needed;
9466 struct gcpro gcpro1, gcpro2, gcpro3;
9467 Lisp_Object image, plist, props;
9468
9469 image = plist = props = Qnil;
9470 GCPRO3 (image, plist, props);
9471
9472 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
9473 Otherwise, make a new string. */
9474
9475 /* The size of the string we might be able to reuse. */
9476 size = (STRINGP (f->desired_tool_bar_string)
9477 ? SCHARS (f->desired_tool_bar_string)
9478 : 0);
9479
9480 /* We need one space in the string for each image. */
9481 size_needed = f->n_tool_bar_items;
9482
9483 /* Reuse f->desired_tool_bar_string, if possible. */
9484 if (size < size_needed || NILP (f->desired_tool_bar_string))
9485 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
9486 make_number (' '));
9487 else
9488 {
9489 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
9490 Fremove_text_properties (make_number (0), make_number (size),
9491 props, f->desired_tool_bar_string);
9492 }
9493
9494 /* Put a `display' property on the string for the images to display,
9495 put a `menu_item' property on tool-bar items with a value that
9496 is the index of the item in F's tool-bar item vector. */
9497 for (i = 0; i < f->n_tool_bar_items; ++i)
9498 {
9499 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
9500
9501 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
9502 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
9503 int hmargin, vmargin, relief, idx, end;
9504 extern Lisp_Object QCrelief, QCmargin, QCconversion;
9505
9506 /* If image is a vector, choose the image according to the
9507 button state. */
9508 image = PROP (TOOL_BAR_ITEM_IMAGES);
9509 if (VECTORP (image))
9510 {
9511 if (enabled_p)
9512 idx = (selected_p
9513 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
9514 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
9515 else
9516 idx = (selected_p
9517 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
9518 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
9519
9520 xassert (ASIZE (image) >= idx);
9521 image = AREF (image, idx);
9522 }
9523 else
9524 idx = -1;
9525
9526 /* Ignore invalid image specifications. */
9527 if (!valid_image_p (image))
9528 continue;
9529
9530 /* Display the tool-bar button pressed, or depressed. */
9531 plist = Fcopy_sequence (XCDR (image));
9532
9533 /* Compute margin and relief to draw. */
9534 relief = (tool_bar_button_relief >= 0
9535 ? tool_bar_button_relief
9536 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
9537 hmargin = vmargin = relief;
9538
9539 if (INTEGERP (Vtool_bar_button_margin)
9540 && XINT (Vtool_bar_button_margin) > 0)
9541 {
9542 hmargin += XFASTINT (Vtool_bar_button_margin);
9543 vmargin += XFASTINT (Vtool_bar_button_margin);
9544 }
9545 else if (CONSP (Vtool_bar_button_margin))
9546 {
9547 if (INTEGERP (XCAR (Vtool_bar_button_margin))
9548 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
9549 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
9550
9551 if (INTEGERP (XCDR (Vtool_bar_button_margin))
9552 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
9553 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
9554 }
9555
9556 if (auto_raise_tool_bar_buttons_p)
9557 {
9558 /* Add a `:relief' property to the image spec if the item is
9559 selected. */
9560 if (selected_p)
9561 {
9562 plist = Fplist_put (plist, QCrelief, make_number (-relief));
9563 hmargin -= relief;
9564 vmargin -= relief;
9565 }
9566 }
9567 else
9568 {
9569 /* If image is selected, display it pressed, i.e. with a
9570 negative relief. If it's not selected, display it with a
9571 raised relief. */
9572 plist = Fplist_put (plist, QCrelief,
9573 (selected_p
9574 ? make_number (-relief)
9575 : make_number (relief)));
9576 hmargin -= relief;
9577 vmargin -= relief;
9578 }
9579
9580 /* Put a margin around the image. */
9581 if (hmargin || vmargin)
9582 {
9583 if (hmargin == vmargin)
9584 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
9585 else
9586 plist = Fplist_put (plist, QCmargin,
9587 Fcons (make_number (hmargin),
9588 make_number (vmargin)));
9589 }
9590
9591 /* If button is not enabled, and we don't have special images
9592 for the disabled state, make the image appear disabled by
9593 applying an appropriate algorithm to it. */
9594 if (!enabled_p && idx < 0)
9595 plist = Fplist_put (plist, QCconversion, Qdisabled);
9596
9597 /* Put a `display' text property on the string for the image to
9598 display. Put a `menu-item' property on the string that gives
9599 the start of this item's properties in the tool-bar items
9600 vector. */
9601 image = Fcons (Qimage, plist);
9602 props = list4 (Qdisplay, image,
9603 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
9604
9605 /* Let the last image hide all remaining spaces in the tool bar
9606 string. The string can be longer than needed when we reuse a
9607 previous string. */
9608 if (i + 1 == f->n_tool_bar_items)
9609 end = SCHARS (f->desired_tool_bar_string);
9610 else
9611 end = i + 1;
9612 Fadd_text_properties (make_number (i), make_number (end),
9613 props, f->desired_tool_bar_string);
9614 #undef PROP
9615 }
9616
9617 UNGCPRO;
9618 }
9619
9620
9621 /* Display one line of the tool-bar of frame IT->f.
9622
9623 HEIGHT specifies the desired height of the tool-bar line.
9624 If the actual height of the glyph row is less than HEIGHT, the
9625 row's height is increased to HEIGHT, and the icons are centered
9626 vertically in the new height.
9627
9628 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
9629 count a final empty row in case the tool-bar width exactly matches
9630 the window width.
9631 */
9632
9633 static void
9634 display_tool_bar_line (it, height)
9635 struct it *it;
9636 int height;
9637 {
9638 struct glyph_row *row = it->glyph_row;
9639 int max_x = it->last_visible_x;
9640 struct glyph *last;
9641
9642 prepare_desired_row (row);
9643 row->y = it->current_y;
9644
9645 /* Note that this isn't made use of if the face hasn't a box,
9646 so there's no need to check the face here. */
9647 it->start_of_box_run_p = 1;
9648
9649 while (it->current_x < max_x)
9650 {
9651 int x, n_glyphs_before, i, nglyphs;
9652 struct it it_before;
9653
9654 /* Get the next display element. */
9655 if (!get_next_display_element (it))
9656 {
9657 /* Don't count empty row if we are counting needed tool-bar lines. */
9658 if (height < 0 && !it->hpos)
9659 return;
9660 break;
9661 }
9662
9663 /* Produce glyphs. */
9664 n_glyphs_before = row->used[TEXT_AREA];
9665 it_before = *it;
9666
9667 PRODUCE_GLYPHS (it);
9668
9669 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
9670 i = 0;
9671 x = it_before.current_x;
9672 while (i < nglyphs)
9673 {
9674 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
9675
9676 if (x + glyph->pixel_width > max_x)
9677 {
9678 /* Glyph doesn't fit on line. Backtrack. */
9679 row->used[TEXT_AREA] = n_glyphs_before;
9680 *it = it_before;
9681 /* If this is the only glyph on this line, it will never fit on the
9682 toolbar, so skip it. But ensure there is at least one glyph,
9683 so we don't accidentally disable the tool-bar. */
9684 if (n_glyphs_before == 0
9685 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
9686 break;
9687 goto out;
9688 }
9689
9690 ++it->hpos;
9691 x += glyph->pixel_width;
9692 ++i;
9693 }
9694
9695 /* Stop at line ends. */
9696 if (ITERATOR_AT_END_OF_LINE_P (it))
9697 break;
9698
9699 set_iterator_to_next (it, 1);
9700 }
9701
9702 out:;
9703
9704 row->displays_text_p = row->used[TEXT_AREA] != 0;
9705
9706 /* Use default face for the border below the tool bar.
9707
9708 FIXME: When auto-resize-tool-bars is grow-only, there is
9709 no additional border below the possibly empty tool-bar lines.
9710 So to make the extra empty lines look "normal", we have to
9711 use the tool-bar face for the border too. */
9712 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
9713 it->face_id = DEFAULT_FACE_ID;
9714
9715 extend_face_to_end_of_line (it);
9716 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
9717 last->right_box_line_p = 1;
9718 if (last == row->glyphs[TEXT_AREA])
9719 last->left_box_line_p = 1;
9720
9721 /* Make line the desired height and center it vertically. */
9722 if ((height -= it->max_ascent + it->max_descent) > 0)
9723 {
9724 /* Don't add more than one line height. */
9725 height %= FRAME_LINE_HEIGHT (it->f);
9726 it->max_ascent += height / 2;
9727 it->max_descent += (height + 1) / 2;
9728 }
9729
9730 compute_line_metrics (it);
9731
9732 /* If line is empty, make it occupy the rest of the tool-bar. */
9733 if (!row->displays_text_p)
9734 {
9735 row->height = row->phys_height = it->last_visible_y - row->y;
9736 row->visible_height = row->height;
9737 row->ascent = row->phys_ascent = 0;
9738 row->extra_line_spacing = 0;
9739 }
9740
9741 row->full_width_p = 1;
9742 row->continued_p = 0;
9743 row->truncated_on_left_p = 0;
9744 row->truncated_on_right_p = 0;
9745
9746 it->current_x = it->hpos = 0;
9747 it->current_y += row->height;
9748 ++it->vpos;
9749 ++it->glyph_row;
9750 }
9751
9752
9753 /* Max tool-bar height. */
9754
9755 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
9756 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
9757
9758 /* Value is the number of screen lines needed to make all tool-bar
9759 items of frame F visible. The number of actual rows needed is
9760 returned in *N_ROWS if non-NULL. */
9761
9762 static int
9763 tool_bar_lines_needed (f, n_rows)
9764 struct frame *f;
9765 int *n_rows;
9766 {
9767 struct window *w = XWINDOW (f->tool_bar_window);
9768 struct it it;
9769 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
9770 the desired matrix, so use (unused) mode-line row as temporary row to
9771 avoid destroying the first tool-bar row. */
9772 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
9773
9774 /* Initialize an iterator for iteration over
9775 F->desired_tool_bar_string in the tool-bar window of frame F. */
9776 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
9777 it.first_visible_x = 0;
9778 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9779 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9780
9781 while (!ITERATOR_AT_END_P (&it))
9782 {
9783 clear_glyph_row (temp_row);
9784 it.glyph_row = temp_row;
9785 display_tool_bar_line (&it, -1);
9786 }
9787 clear_glyph_row (temp_row);
9788
9789 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
9790 if (n_rows)
9791 *n_rows = it.vpos > 0 ? it.vpos : -1;
9792
9793 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
9794 }
9795
9796
9797 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
9798 0, 1, 0,
9799 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
9800 (frame)
9801 Lisp_Object frame;
9802 {
9803 struct frame *f;
9804 struct window *w;
9805 int nlines = 0;
9806
9807 if (NILP (frame))
9808 frame = selected_frame;
9809 else
9810 CHECK_FRAME (frame);
9811 f = XFRAME (frame);
9812
9813 if (WINDOWP (f->tool_bar_window)
9814 || (w = XWINDOW (f->tool_bar_window),
9815 WINDOW_TOTAL_LINES (w) > 0))
9816 {
9817 update_tool_bar (f, 1);
9818 if (f->n_tool_bar_items)
9819 {
9820 build_desired_tool_bar_string (f);
9821 nlines = tool_bar_lines_needed (f, NULL);
9822 }
9823 }
9824
9825 return make_number (nlines);
9826 }
9827
9828
9829 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9830 height should be changed. */
9831
9832 static int
9833 redisplay_tool_bar (f)
9834 struct frame *f;
9835 {
9836 struct window *w;
9837 struct it it;
9838 struct glyph_row *row;
9839
9840 #if defined (USE_GTK) || USE_MAC_TOOLBAR
9841 if (FRAME_EXTERNAL_TOOL_BAR (f))
9842 update_frame_tool_bar (f);
9843 return 0;
9844 #endif
9845
9846 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9847 do anything. This means you must start with tool-bar-lines
9848 non-zero to get the auto-sizing effect. Or in other words, you
9849 can turn off tool-bars by specifying tool-bar-lines zero. */
9850 if (!WINDOWP (f->tool_bar_window)
9851 || (w = XWINDOW (f->tool_bar_window),
9852 WINDOW_TOTAL_LINES (w) == 0))
9853 return 0;
9854
9855 /* Set up an iterator for the tool-bar window. */
9856 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9857 it.first_visible_x = 0;
9858 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9859 row = it.glyph_row;
9860
9861 /* Build a string that represents the contents of the tool-bar. */
9862 build_desired_tool_bar_string (f);
9863 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9864
9865 if (f->n_tool_bar_rows == 0)
9866 {
9867 int nlines;
9868
9869 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
9870 nlines != WINDOW_TOTAL_LINES (w)))
9871 {
9872 extern Lisp_Object Qtool_bar_lines;
9873 Lisp_Object frame;
9874 int old_height = WINDOW_TOTAL_LINES (w);
9875
9876 XSETFRAME (frame, f);
9877 Fmodify_frame_parameters (frame,
9878 Fcons (Fcons (Qtool_bar_lines,
9879 make_number (nlines)),
9880 Qnil));
9881 if (WINDOW_TOTAL_LINES (w) != old_height)
9882 {
9883 clear_glyph_matrix (w->desired_matrix);
9884 fonts_changed_p = 1;
9885 return 1;
9886 }
9887 }
9888 }
9889
9890 /* Display as many lines as needed to display all tool-bar items. */
9891
9892 if (f->n_tool_bar_rows > 0)
9893 {
9894 int border, rows, height, extra;
9895
9896 if (INTEGERP (Vtool_bar_border))
9897 border = XINT (Vtool_bar_border);
9898 else if (EQ (Vtool_bar_border, Qinternal_border_width))
9899 border = FRAME_INTERNAL_BORDER_WIDTH (f);
9900 else if (EQ (Vtool_bar_border, Qborder_width))
9901 border = f->border_width;
9902 else
9903 border = 0;
9904 if (border < 0)
9905 border = 0;
9906
9907 rows = f->n_tool_bar_rows;
9908 height = max (1, (it.last_visible_y - border) / rows);
9909 extra = it.last_visible_y - border - height * rows;
9910
9911 while (it.current_y < it.last_visible_y)
9912 {
9913 int h = 0;
9914 if (extra > 0 && rows-- > 0)
9915 {
9916 h = (extra + rows - 1) / rows;
9917 extra -= h;
9918 }
9919 display_tool_bar_line (&it, height + h);
9920 }
9921 }
9922 else
9923 {
9924 while (it.current_y < it.last_visible_y)
9925 display_tool_bar_line (&it, 0);
9926 }
9927
9928 /* It doesn't make much sense to try scrolling in the tool-bar
9929 window, so don't do it. */
9930 w->desired_matrix->no_scrolling_p = 1;
9931 w->must_be_updated_p = 1;
9932
9933 if (!NILP (Vauto_resize_tool_bars))
9934 {
9935 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
9936 int change_height_p = 0;
9937
9938 /* If we couldn't display everything, change the tool-bar's
9939 height if there is room for more. */
9940 if (IT_STRING_CHARPOS (it) < it.end_charpos
9941 && it.current_y < max_tool_bar_height)
9942 change_height_p = 1;
9943
9944 row = it.glyph_row - 1;
9945
9946 /* If there are blank lines at the end, except for a partially
9947 visible blank line at the end that is smaller than
9948 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9949 if (!row->displays_text_p
9950 && row->height >= FRAME_LINE_HEIGHT (f))
9951 change_height_p = 1;
9952
9953 /* If row displays tool-bar items, but is partially visible,
9954 change the tool-bar's height. */
9955 if (row->displays_text_p
9956 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
9957 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
9958 change_height_p = 1;
9959
9960 /* Resize windows as needed by changing the `tool-bar-lines'
9961 frame parameter. */
9962 if (change_height_p)
9963 {
9964 extern Lisp_Object Qtool_bar_lines;
9965 Lisp_Object frame;
9966 int old_height = WINDOW_TOTAL_LINES (w);
9967 int nrows;
9968 int nlines = tool_bar_lines_needed (f, &nrows);
9969
9970 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
9971 && !f->minimize_tool_bar_window_p)
9972 ? (nlines > old_height)
9973 : (nlines != old_height));
9974 f->minimize_tool_bar_window_p = 0;
9975
9976 if (change_height_p)
9977 {
9978 XSETFRAME (frame, f);
9979 Fmodify_frame_parameters (frame,
9980 Fcons (Fcons (Qtool_bar_lines,
9981 make_number (nlines)),
9982 Qnil));
9983 if (WINDOW_TOTAL_LINES (w) != old_height)
9984 {
9985 clear_glyph_matrix (w->desired_matrix);
9986 f->n_tool_bar_rows = nrows;
9987 fonts_changed_p = 1;
9988 return 1;
9989 }
9990 }
9991 }
9992 }
9993
9994 f->minimize_tool_bar_window_p = 0;
9995 return 0;
9996 }
9997
9998
9999 /* Get information about the tool-bar item which is displayed in GLYPH
10000 on frame F. Return in *PROP_IDX the index where tool-bar item
10001 properties start in F->tool_bar_items. Value is zero if
10002 GLYPH doesn't display a tool-bar item. */
10003
10004 static int
10005 tool_bar_item_info (f, glyph, prop_idx)
10006 struct frame *f;
10007 struct glyph *glyph;
10008 int *prop_idx;
10009 {
10010 Lisp_Object prop;
10011 int success_p;
10012 int charpos;
10013
10014 /* This function can be called asynchronously, which means we must
10015 exclude any possibility that Fget_text_property signals an
10016 error. */
10017 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10018 charpos = max (0, charpos);
10019
10020 /* Get the text property `menu-item' at pos. The value of that
10021 property is the start index of this item's properties in
10022 F->tool_bar_items. */
10023 prop = Fget_text_property (make_number (charpos),
10024 Qmenu_item, f->current_tool_bar_string);
10025 if (INTEGERP (prop))
10026 {
10027 *prop_idx = XINT (prop);
10028 success_p = 1;
10029 }
10030 else
10031 success_p = 0;
10032
10033 return success_p;
10034 }
10035
10036 \f
10037 /* Get information about the tool-bar item at position X/Y on frame F.
10038 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10039 the current matrix of the tool-bar window of F, or NULL if not
10040 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10041 item in F->tool_bar_items. Value is
10042
10043 -1 if X/Y is not on a tool-bar item
10044 0 if X/Y is on the same item that was highlighted before.
10045 1 otherwise. */
10046
10047 static int
10048 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
10049 struct frame *f;
10050 int x, y;
10051 struct glyph **glyph;
10052 int *hpos, *vpos, *prop_idx;
10053 {
10054 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10055 struct window *w = XWINDOW (f->tool_bar_window);
10056 int area;
10057
10058 /* Find the glyph under X/Y. */
10059 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10060 if (*glyph == NULL)
10061 return -1;
10062
10063 /* Get the start of this tool-bar item's properties in
10064 f->tool_bar_items. */
10065 if (!tool_bar_item_info (f, *glyph, prop_idx))
10066 return -1;
10067
10068 /* Is mouse on the highlighted item? */
10069 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10070 && *vpos >= dpyinfo->mouse_face_beg_row
10071 && *vpos <= dpyinfo->mouse_face_end_row
10072 && (*vpos > dpyinfo->mouse_face_beg_row
10073 || *hpos >= dpyinfo->mouse_face_beg_col)
10074 && (*vpos < dpyinfo->mouse_face_end_row
10075 || *hpos < dpyinfo->mouse_face_end_col
10076 || dpyinfo->mouse_face_past_end))
10077 return 0;
10078
10079 return 1;
10080 }
10081
10082
10083 /* EXPORT:
10084 Handle mouse button event on the tool-bar of frame F, at
10085 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10086 0 for button release. MODIFIERS is event modifiers for button
10087 release. */
10088
10089 void
10090 handle_tool_bar_click (f, x, y, down_p, modifiers)
10091 struct frame *f;
10092 int x, y, down_p;
10093 unsigned int modifiers;
10094 {
10095 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10096 struct window *w = XWINDOW (f->tool_bar_window);
10097 int hpos, vpos, prop_idx;
10098 struct glyph *glyph;
10099 Lisp_Object enabled_p;
10100
10101 /* If not on the highlighted tool-bar item, return. */
10102 frame_to_window_pixel_xy (w, &x, &y);
10103 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10104 return;
10105
10106 /* If item is disabled, do nothing. */
10107 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10108 if (NILP (enabled_p))
10109 return;
10110
10111 if (down_p)
10112 {
10113 /* Show item in pressed state. */
10114 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10115 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10116 last_tool_bar_item = prop_idx;
10117 }
10118 else
10119 {
10120 Lisp_Object key, frame;
10121 struct input_event event;
10122 EVENT_INIT (event);
10123
10124 /* Show item in released state. */
10125 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10126 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10127
10128 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10129
10130 XSETFRAME (frame, f);
10131 event.kind = TOOL_BAR_EVENT;
10132 event.frame_or_window = frame;
10133 event.arg = frame;
10134 kbd_buffer_store_event (&event);
10135
10136 event.kind = TOOL_BAR_EVENT;
10137 event.frame_or_window = frame;
10138 event.arg = key;
10139 event.modifiers = modifiers;
10140 kbd_buffer_store_event (&event);
10141 last_tool_bar_item = -1;
10142 }
10143 }
10144
10145
10146 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10147 tool-bar window-relative coordinates X/Y. Called from
10148 note_mouse_highlight. */
10149
10150 static void
10151 note_tool_bar_highlight (f, x, y)
10152 struct frame *f;
10153 int x, y;
10154 {
10155 Lisp_Object window = f->tool_bar_window;
10156 struct window *w = XWINDOW (window);
10157 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10158 int hpos, vpos;
10159 struct glyph *glyph;
10160 struct glyph_row *row;
10161 int i;
10162 Lisp_Object enabled_p;
10163 int prop_idx;
10164 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10165 int mouse_down_p, rc;
10166
10167 /* Function note_mouse_highlight is called with negative x(y
10168 values when mouse moves outside of the frame. */
10169 if (x <= 0 || y <= 0)
10170 {
10171 clear_mouse_face (dpyinfo);
10172 return;
10173 }
10174
10175 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10176 if (rc < 0)
10177 {
10178 /* Not on tool-bar item. */
10179 clear_mouse_face (dpyinfo);
10180 return;
10181 }
10182 else if (rc == 0)
10183 /* On same tool-bar item as before. */
10184 goto set_help_echo;
10185
10186 clear_mouse_face (dpyinfo);
10187
10188 /* Mouse is down, but on different tool-bar item? */
10189 mouse_down_p = (dpyinfo->grabbed
10190 && f == last_mouse_frame
10191 && FRAME_LIVE_P (f));
10192 if (mouse_down_p
10193 && last_tool_bar_item != prop_idx)
10194 return;
10195
10196 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10197 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10198
10199 /* If tool-bar item is not enabled, don't highlight it. */
10200 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10201 if (!NILP (enabled_p))
10202 {
10203 /* Compute the x-position of the glyph. In front and past the
10204 image is a space. We include this in the highlighted area. */
10205 row = MATRIX_ROW (w->current_matrix, vpos);
10206 for (i = x = 0; i < hpos; ++i)
10207 x += row->glyphs[TEXT_AREA][i].pixel_width;
10208
10209 /* Record this as the current active region. */
10210 dpyinfo->mouse_face_beg_col = hpos;
10211 dpyinfo->mouse_face_beg_row = vpos;
10212 dpyinfo->mouse_face_beg_x = x;
10213 dpyinfo->mouse_face_beg_y = row->y;
10214 dpyinfo->mouse_face_past_end = 0;
10215
10216 dpyinfo->mouse_face_end_col = hpos + 1;
10217 dpyinfo->mouse_face_end_row = vpos;
10218 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10219 dpyinfo->mouse_face_end_y = row->y;
10220 dpyinfo->mouse_face_window = window;
10221 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10222
10223 /* Display it as active. */
10224 show_mouse_face (dpyinfo, draw);
10225 dpyinfo->mouse_face_image_state = draw;
10226 }
10227
10228 set_help_echo:
10229
10230 /* Set help_echo_string to a help string to display for this tool-bar item.
10231 XTread_socket does the rest. */
10232 help_echo_object = help_echo_window = Qnil;
10233 help_echo_pos = -1;
10234 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10235 if (NILP (help_echo_string))
10236 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10237 }
10238
10239 #endif /* HAVE_WINDOW_SYSTEM */
10240
10241
10242 \f
10243 /************************************************************************
10244 Horizontal scrolling
10245 ************************************************************************/
10246
10247 static int hscroll_window_tree P_ ((Lisp_Object));
10248 static int hscroll_windows P_ ((Lisp_Object));
10249
10250 /* For all leaf windows in the window tree rooted at WINDOW, set their
10251 hscroll value so that PT is (i) visible in the window, and (ii) so
10252 that it is not within a certain margin at the window's left and
10253 right border. Value is non-zero if any window's hscroll has been
10254 changed. */
10255
10256 static int
10257 hscroll_window_tree (window)
10258 Lisp_Object window;
10259 {
10260 int hscrolled_p = 0;
10261 int hscroll_relative_p = FLOATP (Vhscroll_step);
10262 int hscroll_step_abs = 0;
10263 double hscroll_step_rel = 0;
10264
10265 if (hscroll_relative_p)
10266 {
10267 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10268 if (hscroll_step_rel < 0)
10269 {
10270 hscroll_relative_p = 0;
10271 hscroll_step_abs = 0;
10272 }
10273 }
10274 else if (INTEGERP (Vhscroll_step))
10275 {
10276 hscroll_step_abs = XINT (Vhscroll_step);
10277 if (hscroll_step_abs < 0)
10278 hscroll_step_abs = 0;
10279 }
10280 else
10281 hscroll_step_abs = 0;
10282
10283 while (WINDOWP (window))
10284 {
10285 struct window *w = XWINDOW (window);
10286
10287 if (WINDOWP (w->hchild))
10288 hscrolled_p |= hscroll_window_tree (w->hchild);
10289 else if (WINDOWP (w->vchild))
10290 hscrolled_p |= hscroll_window_tree (w->vchild);
10291 else if (w->cursor.vpos >= 0)
10292 {
10293 int h_margin;
10294 int text_area_width;
10295 struct glyph_row *current_cursor_row
10296 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10297 struct glyph_row *desired_cursor_row
10298 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10299 struct glyph_row *cursor_row
10300 = (desired_cursor_row->enabled_p
10301 ? desired_cursor_row
10302 : current_cursor_row);
10303
10304 text_area_width = window_box_width (w, TEXT_AREA);
10305
10306 /* Scroll when cursor is inside this scroll margin. */
10307 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
10308
10309 if ((XFASTINT (w->hscroll)
10310 && w->cursor.x <= h_margin)
10311 || (cursor_row->enabled_p
10312 && cursor_row->truncated_on_right_p
10313 && (w->cursor.x >= text_area_width - h_margin)))
10314 {
10315 struct it it;
10316 int hscroll;
10317 struct buffer *saved_current_buffer;
10318 int pt;
10319 int wanted_x;
10320
10321 /* Find point in a display of infinite width. */
10322 saved_current_buffer = current_buffer;
10323 current_buffer = XBUFFER (w->buffer);
10324
10325 if (w == XWINDOW (selected_window))
10326 pt = BUF_PT (current_buffer);
10327 else
10328 {
10329 pt = marker_position (w->pointm);
10330 pt = max (BEGV, pt);
10331 pt = min (ZV, pt);
10332 }
10333
10334 /* Move iterator to pt starting at cursor_row->start in
10335 a line with infinite width. */
10336 init_to_row_start (&it, w, cursor_row);
10337 it.last_visible_x = INFINITY;
10338 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
10339 current_buffer = saved_current_buffer;
10340
10341 /* Position cursor in window. */
10342 if (!hscroll_relative_p && hscroll_step_abs == 0)
10343 hscroll = max (0, (it.current_x
10344 - (ITERATOR_AT_END_OF_LINE_P (&it)
10345 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
10346 : (text_area_width / 2))))
10347 / FRAME_COLUMN_WIDTH (it.f);
10348 else if (w->cursor.x >= text_area_width - h_margin)
10349 {
10350 if (hscroll_relative_p)
10351 wanted_x = text_area_width * (1 - hscroll_step_rel)
10352 - h_margin;
10353 else
10354 wanted_x = text_area_width
10355 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10356 - h_margin;
10357 hscroll
10358 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10359 }
10360 else
10361 {
10362 if (hscroll_relative_p)
10363 wanted_x = text_area_width * hscroll_step_rel
10364 + h_margin;
10365 else
10366 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10367 + h_margin;
10368 hscroll
10369 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10370 }
10371 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
10372
10373 /* Don't call Fset_window_hscroll if value hasn't
10374 changed because it will prevent redisplay
10375 optimizations. */
10376 if (XFASTINT (w->hscroll) != hscroll)
10377 {
10378 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
10379 w->hscroll = make_number (hscroll);
10380 hscrolled_p = 1;
10381 }
10382 }
10383 }
10384
10385 window = w->next;
10386 }
10387
10388 /* Value is non-zero if hscroll of any leaf window has been changed. */
10389 return hscrolled_p;
10390 }
10391
10392
10393 /* Set hscroll so that cursor is visible and not inside horizontal
10394 scroll margins for all windows in the tree rooted at WINDOW. See
10395 also hscroll_window_tree above. Value is non-zero if any window's
10396 hscroll has been changed. If it has, desired matrices on the frame
10397 of WINDOW are cleared. */
10398
10399 static int
10400 hscroll_windows (window)
10401 Lisp_Object window;
10402 {
10403 int hscrolled_p;
10404
10405 if (automatic_hscrolling_p)
10406 {
10407 hscrolled_p = hscroll_window_tree (window);
10408 if (hscrolled_p)
10409 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
10410 }
10411 else
10412 hscrolled_p = 0;
10413 return hscrolled_p;
10414 }
10415
10416
10417 \f
10418 /************************************************************************
10419 Redisplay
10420 ************************************************************************/
10421
10422 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
10423 to a non-zero value. This is sometimes handy to have in a debugger
10424 session. */
10425
10426 #if GLYPH_DEBUG
10427
10428 /* First and last unchanged row for try_window_id. */
10429
10430 int debug_first_unchanged_at_end_vpos;
10431 int debug_last_unchanged_at_beg_vpos;
10432
10433 /* Delta vpos and y. */
10434
10435 int debug_dvpos, debug_dy;
10436
10437 /* Delta in characters and bytes for try_window_id. */
10438
10439 int debug_delta, debug_delta_bytes;
10440
10441 /* Values of window_end_pos and window_end_vpos at the end of
10442 try_window_id. */
10443
10444 EMACS_INT debug_end_pos, debug_end_vpos;
10445
10446 /* Append a string to W->desired_matrix->method. FMT is a printf
10447 format string. A1...A9 are a supplement for a variable-length
10448 argument list. If trace_redisplay_p is non-zero also printf the
10449 resulting string to stderr. */
10450
10451 static void
10452 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
10453 struct window *w;
10454 char *fmt;
10455 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
10456 {
10457 char buffer[512];
10458 char *method = w->desired_matrix->method;
10459 int len = strlen (method);
10460 int size = sizeof w->desired_matrix->method;
10461 int remaining = size - len - 1;
10462
10463 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
10464 if (len && remaining)
10465 {
10466 method[len] = '|';
10467 --remaining, ++len;
10468 }
10469
10470 strncpy (method + len, buffer, remaining);
10471
10472 if (trace_redisplay_p)
10473 fprintf (stderr, "%p (%s): %s\n",
10474 w,
10475 ((BUFFERP (w->buffer)
10476 && STRINGP (XBUFFER (w->buffer)->name))
10477 ? (char *) SDATA (XBUFFER (w->buffer)->name)
10478 : "no buffer"),
10479 buffer);
10480 }
10481
10482 #endif /* GLYPH_DEBUG */
10483
10484
10485 /* Value is non-zero if all changes in window W, which displays
10486 current_buffer, are in the text between START and END. START is a
10487 buffer position, END is given as a distance from Z. Used in
10488 redisplay_internal for display optimization. */
10489
10490 static INLINE int
10491 text_outside_line_unchanged_p (w, start, end)
10492 struct window *w;
10493 int start, end;
10494 {
10495 int unchanged_p = 1;
10496
10497 /* If text or overlays have changed, see where. */
10498 if (XFASTINT (w->last_modified) < MODIFF
10499 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10500 {
10501 /* Gap in the line? */
10502 if (GPT < start || Z - GPT < end)
10503 unchanged_p = 0;
10504
10505 /* Changes start in front of the line, or end after it? */
10506 if (unchanged_p
10507 && (BEG_UNCHANGED < start - 1
10508 || END_UNCHANGED < end))
10509 unchanged_p = 0;
10510
10511 /* If selective display, can't optimize if changes start at the
10512 beginning of the line. */
10513 if (unchanged_p
10514 && INTEGERP (current_buffer->selective_display)
10515 && XINT (current_buffer->selective_display) > 0
10516 && (BEG_UNCHANGED < start || GPT <= start))
10517 unchanged_p = 0;
10518
10519 /* If there are overlays at the start or end of the line, these
10520 may have overlay strings with newlines in them. A change at
10521 START, for instance, may actually concern the display of such
10522 overlay strings as well, and they are displayed on different
10523 lines. So, quickly rule out this case. (For the future, it
10524 might be desirable to implement something more telling than
10525 just BEG/END_UNCHANGED.) */
10526 if (unchanged_p)
10527 {
10528 if (BEG + BEG_UNCHANGED == start
10529 && overlay_touches_p (start))
10530 unchanged_p = 0;
10531 if (END_UNCHANGED == end
10532 && overlay_touches_p (Z - end))
10533 unchanged_p = 0;
10534 }
10535 }
10536
10537 return unchanged_p;
10538 }
10539
10540
10541 /* Do a frame update, taking possible shortcuts into account. This is
10542 the main external entry point for redisplay.
10543
10544 If the last redisplay displayed an echo area message and that message
10545 is no longer requested, we clear the echo area or bring back the
10546 mini-buffer if that is in use. */
10547
10548 void
10549 redisplay ()
10550 {
10551 redisplay_internal (0);
10552 }
10553
10554
10555 static Lisp_Object
10556 overlay_arrow_string_or_property (var)
10557 Lisp_Object var;
10558 {
10559 Lisp_Object val;
10560
10561 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
10562 return val;
10563
10564 return Voverlay_arrow_string;
10565 }
10566
10567 /* Return 1 if there are any overlay-arrows in current_buffer. */
10568 static int
10569 overlay_arrow_in_current_buffer_p ()
10570 {
10571 Lisp_Object vlist;
10572
10573 for (vlist = Voverlay_arrow_variable_list;
10574 CONSP (vlist);
10575 vlist = XCDR (vlist))
10576 {
10577 Lisp_Object var = XCAR (vlist);
10578 Lisp_Object val;
10579
10580 if (!SYMBOLP (var))
10581 continue;
10582 val = find_symbol_value (var);
10583 if (MARKERP (val)
10584 && current_buffer == XMARKER (val)->buffer)
10585 return 1;
10586 }
10587 return 0;
10588 }
10589
10590
10591 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
10592 has changed. */
10593
10594 static int
10595 overlay_arrows_changed_p ()
10596 {
10597 Lisp_Object vlist;
10598
10599 for (vlist = Voverlay_arrow_variable_list;
10600 CONSP (vlist);
10601 vlist = XCDR (vlist))
10602 {
10603 Lisp_Object var = XCAR (vlist);
10604 Lisp_Object val, pstr;
10605
10606 if (!SYMBOLP (var))
10607 continue;
10608 val = find_symbol_value (var);
10609 if (!MARKERP (val))
10610 continue;
10611 if (! EQ (COERCE_MARKER (val),
10612 Fget (var, Qlast_arrow_position))
10613 || ! (pstr = overlay_arrow_string_or_property (var),
10614 EQ (pstr, Fget (var, Qlast_arrow_string))))
10615 return 1;
10616 }
10617 return 0;
10618 }
10619
10620 /* Mark overlay arrows to be updated on next redisplay. */
10621
10622 static void
10623 update_overlay_arrows (up_to_date)
10624 int up_to_date;
10625 {
10626 Lisp_Object vlist;
10627
10628 for (vlist = Voverlay_arrow_variable_list;
10629 CONSP (vlist);
10630 vlist = XCDR (vlist))
10631 {
10632 Lisp_Object var = XCAR (vlist);
10633
10634 if (!SYMBOLP (var))
10635 continue;
10636
10637 if (up_to_date > 0)
10638 {
10639 Lisp_Object val = find_symbol_value (var);
10640 Fput (var, Qlast_arrow_position,
10641 COERCE_MARKER (val));
10642 Fput (var, Qlast_arrow_string,
10643 overlay_arrow_string_or_property (var));
10644 }
10645 else if (up_to_date < 0
10646 || !NILP (Fget (var, Qlast_arrow_position)))
10647 {
10648 Fput (var, Qlast_arrow_position, Qt);
10649 Fput (var, Qlast_arrow_string, Qt);
10650 }
10651 }
10652 }
10653
10654
10655 /* Return overlay arrow string to display at row.
10656 Return integer (bitmap number) for arrow bitmap in left fringe.
10657 Return nil if no overlay arrow. */
10658
10659 static Lisp_Object
10660 overlay_arrow_at_row (it, row)
10661 struct it *it;
10662 struct glyph_row *row;
10663 {
10664 Lisp_Object vlist;
10665
10666 for (vlist = Voverlay_arrow_variable_list;
10667 CONSP (vlist);
10668 vlist = XCDR (vlist))
10669 {
10670 Lisp_Object var = XCAR (vlist);
10671 Lisp_Object val;
10672
10673 if (!SYMBOLP (var))
10674 continue;
10675
10676 val = find_symbol_value (var);
10677
10678 if (MARKERP (val)
10679 && current_buffer == XMARKER (val)->buffer
10680 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
10681 {
10682 if (FRAME_WINDOW_P (it->f)
10683 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
10684 {
10685 #ifdef HAVE_WINDOW_SYSTEM
10686 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
10687 {
10688 int fringe_bitmap;
10689 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
10690 return make_number (fringe_bitmap);
10691 }
10692 #endif
10693 return make_number (-1); /* Use default arrow bitmap */
10694 }
10695 return overlay_arrow_string_or_property (var);
10696 }
10697 }
10698
10699 return Qnil;
10700 }
10701
10702 /* Return 1 if point moved out of or into a composition. Otherwise
10703 return 0. PREV_BUF and PREV_PT are the last point buffer and
10704 position. BUF and PT are the current point buffer and position. */
10705
10706 int
10707 check_point_in_composition (prev_buf, prev_pt, buf, pt)
10708 struct buffer *prev_buf, *buf;
10709 int prev_pt, pt;
10710 {
10711 int start, end;
10712 Lisp_Object prop;
10713 Lisp_Object buffer;
10714
10715 XSETBUFFER (buffer, buf);
10716 /* Check a composition at the last point if point moved within the
10717 same buffer. */
10718 if (prev_buf == buf)
10719 {
10720 if (prev_pt == pt)
10721 /* Point didn't move. */
10722 return 0;
10723
10724 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
10725 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
10726 && COMPOSITION_VALID_P (start, end, prop)
10727 && start < prev_pt && end > prev_pt)
10728 /* The last point was within the composition. Return 1 iff
10729 point moved out of the composition. */
10730 return (pt <= start || pt >= end);
10731 }
10732
10733 /* Check a composition at the current point. */
10734 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
10735 && find_composition (pt, -1, &start, &end, &prop, buffer)
10736 && COMPOSITION_VALID_P (start, end, prop)
10737 && start < pt && end > pt);
10738 }
10739
10740
10741 /* Reconsider the setting of B->clip_changed which is displayed
10742 in window W. */
10743
10744 static INLINE void
10745 reconsider_clip_changes (w, b)
10746 struct window *w;
10747 struct buffer *b;
10748 {
10749 if (b->clip_changed
10750 && !NILP (w->window_end_valid)
10751 && w->current_matrix->buffer == b
10752 && w->current_matrix->zv == BUF_ZV (b)
10753 && w->current_matrix->begv == BUF_BEGV (b))
10754 b->clip_changed = 0;
10755
10756 /* If display wasn't paused, and W is not a tool bar window, see if
10757 point has been moved into or out of a composition. In that case,
10758 we set b->clip_changed to 1 to force updating the screen. If
10759 b->clip_changed has already been set to 1, we can skip this
10760 check. */
10761 if (!b->clip_changed
10762 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
10763 {
10764 int pt;
10765
10766 if (w == XWINDOW (selected_window))
10767 pt = BUF_PT (current_buffer);
10768 else
10769 pt = marker_position (w->pointm);
10770
10771 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
10772 || pt != XINT (w->last_point))
10773 && check_point_in_composition (w->current_matrix->buffer,
10774 XINT (w->last_point),
10775 XBUFFER (w->buffer), pt))
10776 b->clip_changed = 1;
10777 }
10778 }
10779 \f
10780
10781 /* Select FRAME to forward the values of frame-local variables into C
10782 variables so that the redisplay routines can access those values
10783 directly. */
10784
10785 static void
10786 select_frame_for_redisplay (frame)
10787 Lisp_Object frame;
10788 {
10789 Lisp_Object tail, sym, val;
10790 Lisp_Object old = selected_frame;
10791
10792 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
10793
10794 selected_frame = frame;
10795
10796 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
10797 if (CONSP (XCAR (tail))
10798 && (sym = XCAR (XCAR (tail)),
10799 SYMBOLP (sym))
10800 && (sym = indirect_variable (sym),
10801 val = SYMBOL_VALUE (sym),
10802 (BUFFER_LOCAL_VALUEP (val)
10803 || SOME_BUFFER_LOCAL_VALUEP (val)))
10804 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10805 /* Use find_symbol_value rather than Fsymbol_value
10806 to avoid an error if it is void. */
10807 find_symbol_value (sym);
10808
10809 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
10810 if (CONSP (XCAR (tail))
10811 && (sym = XCAR (XCAR (tail)),
10812 SYMBOLP (sym))
10813 && (sym = indirect_variable (sym),
10814 val = SYMBOL_VALUE (sym),
10815 (BUFFER_LOCAL_VALUEP (val)
10816 || SOME_BUFFER_LOCAL_VALUEP (val)))
10817 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10818 find_symbol_value (sym);
10819 }
10820
10821
10822 #define STOP_POLLING \
10823 do { if (! polling_stopped_here) stop_polling (); \
10824 polling_stopped_here = 1; } while (0)
10825
10826 #define RESUME_POLLING \
10827 do { if (polling_stopped_here) start_polling (); \
10828 polling_stopped_here = 0; } while (0)
10829
10830
10831 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
10832 response to any user action; therefore, we should preserve the echo
10833 area. (Actually, our caller does that job.) Perhaps in the future
10834 avoid recentering windows if it is not necessary; currently that
10835 causes some problems. */
10836
10837 static void
10838 redisplay_internal (preserve_echo_area)
10839 int preserve_echo_area;
10840 {
10841 struct window *w = XWINDOW (selected_window);
10842 struct frame *f;
10843 int pause;
10844 int must_finish = 0;
10845 struct text_pos tlbufpos, tlendpos;
10846 int number_of_visible_frames;
10847 int count, count1;
10848 struct frame *sf;
10849 int polling_stopped_here = 0;
10850 Lisp_Object old_frame = selected_frame;
10851
10852 /* Non-zero means redisplay has to consider all windows on all
10853 frames. Zero means, only selected_window is considered. */
10854 int consider_all_windows_p;
10855
10856 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
10857
10858 /* No redisplay if running in batch mode or frame is not yet fully
10859 initialized, or redisplay is explicitly turned off by setting
10860 Vinhibit_redisplay. */
10861 if (noninteractive
10862 || !NILP (Vinhibit_redisplay))
10863 return;
10864
10865 /* Don't examine these until after testing Vinhibit_redisplay.
10866 When Emacs is shutting down, perhaps because its connection to
10867 X has dropped, we should not look at them at all. */
10868 f = XFRAME (w->frame);
10869 sf = SELECTED_FRAME ();
10870
10871 if (!f->glyphs_initialized_p)
10872 return;
10873
10874 /* The flag redisplay_performed_directly_p is set by
10875 direct_output_for_insert when it already did the whole screen
10876 update necessary. */
10877 if (redisplay_performed_directly_p)
10878 {
10879 redisplay_performed_directly_p = 0;
10880 if (!hscroll_windows (selected_window))
10881 return;
10882 }
10883
10884 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
10885 if (popup_activated ())
10886 return;
10887 #endif
10888
10889 /* I don't think this happens but let's be paranoid. */
10890 if (redisplaying_p)
10891 return;
10892
10893 /* Record a function that resets redisplaying_p to its old value
10894 when we leave this function. */
10895 count = SPECPDL_INDEX ();
10896 record_unwind_protect (unwind_redisplay,
10897 Fcons (make_number (redisplaying_p), selected_frame));
10898 ++redisplaying_p;
10899 specbind (Qinhibit_free_realized_faces, Qnil);
10900
10901 {
10902 Lisp_Object tail, frame;
10903
10904 FOR_EACH_FRAME (tail, frame)
10905 {
10906 struct frame *f = XFRAME (frame);
10907 f->already_hscrolled_p = 0;
10908 }
10909 }
10910
10911 retry:
10912 if (!EQ (old_frame, selected_frame)
10913 && FRAME_LIVE_P (XFRAME (old_frame)))
10914 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
10915 selected_frame and selected_window to be temporarily out-of-sync so
10916 when we come back here via `goto retry', we need to resync because we
10917 may need to run Elisp code (via prepare_menu_bars). */
10918 select_frame_for_redisplay (old_frame);
10919
10920 pause = 0;
10921 reconsider_clip_changes (w, current_buffer);
10922 last_escape_glyph_frame = NULL;
10923 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
10924
10925 /* If new fonts have been loaded that make a glyph matrix adjustment
10926 necessary, do it. */
10927 if (fonts_changed_p)
10928 {
10929 adjust_glyphs (NULL);
10930 ++windows_or_buffers_changed;
10931 fonts_changed_p = 0;
10932 }
10933
10934 /* If face_change_count is non-zero, init_iterator will free all
10935 realized faces, which includes the faces referenced from current
10936 matrices. So, we can't reuse current matrices in this case. */
10937 if (face_change_count)
10938 ++windows_or_buffers_changed;
10939
10940 if (FRAME_TERMCAP_P (sf)
10941 && FRAME_TTY (sf)->previous_frame != sf)
10942 {
10943 /* Since frames on a single ASCII terminal share the same
10944 display area, displaying a different frame means redisplay
10945 the whole thing. */
10946 windows_or_buffers_changed++;
10947 SET_FRAME_GARBAGED (sf);
10948 FRAME_TTY (sf)->previous_frame = sf;
10949 }
10950
10951 /* Set the visible flags for all frames. Do this before checking
10952 for resized or garbaged frames; they want to know if their frames
10953 are visible. See the comment in frame.h for
10954 FRAME_SAMPLE_VISIBILITY. */
10955 {
10956 Lisp_Object tail, frame;
10957
10958 number_of_visible_frames = 0;
10959
10960 FOR_EACH_FRAME (tail, frame)
10961 {
10962 struct frame *f = XFRAME (frame);
10963
10964 FRAME_SAMPLE_VISIBILITY (f);
10965 if (FRAME_VISIBLE_P (f))
10966 ++number_of_visible_frames;
10967 clear_desired_matrices (f);
10968 }
10969 }
10970
10971
10972 /* Notice any pending interrupt request to change frame size. */
10973 do_pending_window_change (1);
10974
10975 /* Clear frames marked as garbaged. */
10976 if (frame_garbaged)
10977 clear_garbaged_frames ();
10978
10979 /* Build menubar and tool-bar items. */
10980 if (NILP (Vmemory_full))
10981 prepare_menu_bars ();
10982
10983 if (windows_or_buffers_changed)
10984 update_mode_lines++;
10985
10986 /* Detect case that we need to write or remove a star in the mode line. */
10987 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
10988 {
10989 w->update_mode_line = Qt;
10990 if (buffer_shared > 1)
10991 update_mode_lines++;
10992 }
10993
10994 /* Avoid invocation of point motion hooks by `current_column' below. */
10995 count1 = SPECPDL_INDEX ();
10996 specbind (Qinhibit_point_motion_hooks, Qt);
10997
10998 /* If %c is in the mode line, update it if needed. */
10999 if (!NILP (w->column_number_displayed)
11000 /* This alternative quickly identifies a common case
11001 where no change is needed. */
11002 && !(PT == XFASTINT (w->last_point)
11003 && XFASTINT (w->last_modified) >= MODIFF
11004 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11005 && (XFASTINT (w->column_number_displayed)
11006 != (int) current_column ())) /* iftc */
11007 w->update_mode_line = Qt;
11008
11009 unbind_to (count1, Qnil);
11010
11011 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11012
11013 /* The variable buffer_shared is set in redisplay_window and
11014 indicates that we redisplay a buffer in different windows. See
11015 there. */
11016 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11017 || cursor_type_changed);
11018
11019 /* If specs for an arrow have changed, do thorough redisplay
11020 to ensure we remove any arrow that should no longer exist. */
11021 if (overlay_arrows_changed_p ())
11022 consider_all_windows_p = windows_or_buffers_changed = 1;
11023
11024 /* Normally the message* functions will have already displayed and
11025 updated the echo area, but the frame may have been trashed, or
11026 the update may have been preempted, so display the echo area
11027 again here. Checking message_cleared_p captures the case that
11028 the echo area should be cleared. */
11029 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11030 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11031 || (message_cleared_p
11032 && minibuf_level == 0
11033 /* If the mini-window is currently selected, this means the
11034 echo-area doesn't show through. */
11035 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11036 {
11037 int window_height_changed_p = echo_area_display (0);
11038 must_finish = 1;
11039
11040 /* If we don't display the current message, don't clear the
11041 message_cleared_p flag, because, if we did, we wouldn't clear
11042 the echo area in the next redisplay which doesn't preserve
11043 the echo area. */
11044 if (!display_last_displayed_message_p)
11045 message_cleared_p = 0;
11046
11047 if (fonts_changed_p)
11048 goto retry;
11049 else if (window_height_changed_p)
11050 {
11051 consider_all_windows_p = 1;
11052 ++update_mode_lines;
11053 ++windows_or_buffers_changed;
11054
11055 /* If window configuration was changed, frames may have been
11056 marked garbaged. Clear them or we will experience
11057 surprises wrt scrolling. */
11058 if (frame_garbaged)
11059 clear_garbaged_frames ();
11060 }
11061 }
11062 else if (EQ (selected_window, minibuf_window)
11063 && (current_buffer->clip_changed
11064 || XFASTINT (w->last_modified) < MODIFF
11065 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11066 && resize_mini_window (w, 0))
11067 {
11068 /* Resized active mini-window to fit the size of what it is
11069 showing if its contents might have changed. */
11070 must_finish = 1;
11071 consider_all_windows_p = 1;
11072 ++windows_or_buffers_changed;
11073 ++update_mode_lines;
11074
11075 /* If window configuration was changed, frames may have been
11076 marked garbaged. Clear them or we will experience
11077 surprises wrt scrolling. */
11078 if (frame_garbaged)
11079 clear_garbaged_frames ();
11080 }
11081
11082
11083 /* If showing the region, and mark has changed, we must redisplay
11084 the whole window. The assignment to this_line_start_pos prevents
11085 the optimization directly below this if-statement. */
11086 if (((!NILP (Vtransient_mark_mode)
11087 && !NILP (XBUFFER (w->buffer)->mark_active))
11088 != !NILP (w->region_showing))
11089 || (!NILP (w->region_showing)
11090 && !EQ (w->region_showing,
11091 Fmarker_position (XBUFFER (w->buffer)->mark))))
11092 CHARPOS (this_line_start_pos) = 0;
11093
11094 /* Optimize the case that only the line containing the cursor in the
11095 selected window has changed. Variables starting with this_ are
11096 set in display_line and record information about the line
11097 containing the cursor. */
11098 tlbufpos = this_line_start_pos;
11099 tlendpos = this_line_end_pos;
11100 if (!consider_all_windows_p
11101 && CHARPOS (tlbufpos) > 0
11102 && NILP (w->update_mode_line)
11103 && !current_buffer->clip_changed
11104 && !current_buffer->prevent_redisplay_optimizations_p
11105 && FRAME_VISIBLE_P (XFRAME (w->frame))
11106 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11107 /* Make sure recorded data applies to current buffer, etc. */
11108 && this_line_buffer == current_buffer
11109 && current_buffer == XBUFFER (w->buffer)
11110 && NILP (w->force_start)
11111 && NILP (w->optional_new_start)
11112 /* Point must be on the line that we have info recorded about. */
11113 && PT >= CHARPOS (tlbufpos)
11114 && PT <= Z - CHARPOS (tlendpos)
11115 /* All text outside that line, including its final newline,
11116 must be unchanged */
11117 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11118 CHARPOS (tlendpos)))
11119 {
11120 if (CHARPOS (tlbufpos) > BEGV
11121 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11122 && (CHARPOS (tlbufpos) == ZV
11123 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11124 /* Former continuation line has disappeared by becoming empty */
11125 goto cancel;
11126 else if (XFASTINT (w->last_modified) < MODIFF
11127 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11128 || MINI_WINDOW_P (w))
11129 {
11130 /* We have to handle the case of continuation around a
11131 wide-column character (See the comment in indent.c around
11132 line 885).
11133
11134 For instance, in the following case:
11135
11136 -------- Insert --------
11137 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11138 J_I_ ==> J_I_ `^^' are cursors.
11139 ^^ ^^
11140 -------- --------
11141
11142 As we have to redraw the line above, we should goto cancel. */
11143
11144 struct it it;
11145 int line_height_before = this_line_pixel_height;
11146
11147 /* Note that start_display will handle the case that the
11148 line starting at tlbufpos is a continuation lines. */
11149 start_display (&it, w, tlbufpos);
11150
11151 /* Implementation note: It this still necessary? */
11152 if (it.current_x != this_line_start_x)
11153 goto cancel;
11154
11155 TRACE ((stderr, "trying display optimization 1\n"));
11156 w->cursor.vpos = -1;
11157 overlay_arrow_seen = 0;
11158 it.vpos = this_line_vpos;
11159 it.current_y = this_line_y;
11160 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11161 display_line (&it);
11162
11163 /* If line contains point, is not continued,
11164 and ends at same distance from eob as before, we win */
11165 if (w->cursor.vpos >= 0
11166 /* Line is not continued, otherwise this_line_start_pos
11167 would have been set to 0 in display_line. */
11168 && CHARPOS (this_line_start_pos)
11169 /* Line ends as before. */
11170 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11171 /* Line has same height as before. Otherwise other lines
11172 would have to be shifted up or down. */
11173 && this_line_pixel_height == line_height_before)
11174 {
11175 /* If this is not the window's last line, we must adjust
11176 the charstarts of the lines below. */
11177 if (it.current_y < it.last_visible_y)
11178 {
11179 struct glyph_row *row
11180 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11181 int delta, delta_bytes;
11182
11183 if (Z - CHARPOS (tlendpos) == ZV)
11184 {
11185 /* This line ends at end of (accessible part of)
11186 buffer. There is no newline to count. */
11187 delta = (Z
11188 - CHARPOS (tlendpos)
11189 - MATRIX_ROW_START_CHARPOS (row));
11190 delta_bytes = (Z_BYTE
11191 - BYTEPOS (tlendpos)
11192 - MATRIX_ROW_START_BYTEPOS (row));
11193 }
11194 else
11195 {
11196 /* This line ends in a newline. Must take
11197 account of the newline and the rest of the
11198 text that follows. */
11199 delta = (Z
11200 - CHARPOS (tlendpos)
11201 - MATRIX_ROW_START_CHARPOS (row));
11202 delta_bytes = (Z_BYTE
11203 - BYTEPOS (tlendpos)
11204 - MATRIX_ROW_START_BYTEPOS (row));
11205 }
11206
11207 increment_matrix_positions (w->current_matrix,
11208 this_line_vpos + 1,
11209 w->current_matrix->nrows,
11210 delta, delta_bytes);
11211 }
11212
11213 /* If this row displays text now but previously didn't,
11214 or vice versa, w->window_end_vpos may have to be
11215 adjusted. */
11216 if ((it.glyph_row - 1)->displays_text_p)
11217 {
11218 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11219 XSETINT (w->window_end_vpos, this_line_vpos);
11220 }
11221 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11222 && this_line_vpos > 0)
11223 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11224 w->window_end_valid = Qnil;
11225
11226 /* Update hint: No need to try to scroll in update_window. */
11227 w->desired_matrix->no_scrolling_p = 1;
11228
11229 #if GLYPH_DEBUG
11230 *w->desired_matrix->method = 0;
11231 debug_method_add (w, "optimization 1");
11232 #endif
11233 #ifdef HAVE_WINDOW_SYSTEM
11234 update_window_fringes (w, 0);
11235 #endif
11236 goto update;
11237 }
11238 else
11239 goto cancel;
11240 }
11241 else if (/* Cursor position hasn't changed. */
11242 PT == XFASTINT (w->last_point)
11243 /* Make sure the cursor was last displayed
11244 in this window. Otherwise we have to reposition it. */
11245 && 0 <= w->cursor.vpos
11246 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11247 {
11248 if (!must_finish)
11249 {
11250 do_pending_window_change (1);
11251
11252 /* We used to always goto end_of_redisplay here, but this
11253 isn't enough if we have a blinking cursor. */
11254 if (w->cursor_off_p == w->last_cursor_off_p)
11255 goto end_of_redisplay;
11256 }
11257 goto update;
11258 }
11259 /* If highlighting the region, or if the cursor is in the echo area,
11260 then we can't just move the cursor. */
11261 else if (! (!NILP (Vtransient_mark_mode)
11262 && !NILP (current_buffer->mark_active))
11263 && (EQ (selected_window, current_buffer->last_selected_window)
11264 || highlight_nonselected_windows)
11265 && NILP (w->region_showing)
11266 && NILP (Vshow_trailing_whitespace)
11267 && !cursor_in_echo_area)
11268 {
11269 struct it it;
11270 struct glyph_row *row;
11271
11272 /* Skip from tlbufpos to PT and see where it is. Note that
11273 PT may be in invisible text. If so, we will end at the
11274 next visible position. */
11275 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11276 NULL, DEFAULT_FACE_ID);
11277 it.current_x = this_line_start_x;
11278 it.current_y = this_line_y;
11279 it.vpos = this_line_vpos;
11280
11281 /* The call to move_it_to stops in front of PT, but
11282 moves over before-strings. */
11283 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11284
11285 if (it.vpos == this_line_vpos
11286 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11287 row->enabled_p))
11288 {
11289 xassert (this_line_vpos == it.vpos);
11290 xassert (this_line_y == it.current_y);
11291 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11292 #if GLYPH_DEBUG
11293 *w->desired_matrix->method = 0;
11294 debug_method_add (w, "optimization 3");
11295 #endif
11296 goto update;
11297 }
11298 else
11299 goto cancel;
11300 }
11301
11302 cancel:
11303 /* Text changed drastically or point moved off of line. */
11304 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11305 }
11306
11307 CHARPOS (this_line_start_pos) = 0;
11308 consider_all_windows_p |= buffer_shared > 1;
11309 ++clear_face_cache_count;
11310 #ifdef HAVE_WINDOW_SYSTEM
11311 ++clear_image_cache_count;
11312 #endif
11313
11314 /* Build desired matrices, and update the display. If
11315 consider_all_windows_p is non-zero, do it for all windows on all
11316 frames. Otherwise do it for selected_window, only. */
11317
11318 if (consider_all_windows_p)
11319 {
11320 Lisp_Object tail, frame;
11321
11322 FOR_EACH_FRAME (tail, frame)
11323 XFRAME (frame)->updated_p = 0;
11324
11325 /* Recompute # windows showing selected buffer. This will be
11326 incremented each time such a window is displayed. */
11327 buffer_shared = 0;
11328
11329 FOR_EACH_FRAME (tail, frame)
11330 {
11331 struct frame *f = XFRAME (frame);
11332
11333 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
11334 {
11335 if (! EQ (frame, selected_frame))
11336 /* Select the frame, for the sake of frame-local
11337 variables. */
11338 select_frame_for_redisplay (frame);
11339
11340 /* Mark all the scroll bars to be removed; we'll redeem
11341 the ones we want when we redisplay their windows. */
11342 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
11343 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
11344
11345 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11346 redisplay_windows (FRAME_ROOT_WINDOW (f));
11347
11348 /* Any scroll bars which redisplay_windows should have
11349 nuked should now go away. */
11350 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
11351 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
11352
11353 /* If fonts changed, display again. */
11354 /* ??? rms: I suspect it is a mistake to jump all the way
11355 back to retry here. It should just retry this frame. */
11356 if (fonts_changed_p)
11357 goto retry;
11358
11359 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11360 {
11361 /* See if we have to hscroll. */
11362 if (!f->already_hscrolled_p)
11363 {
11364 f->already_hscrolled_p = 1;
11365 if (hscroll_windows (f->root_window))
11366 goto retry;
11367 }
11368
11369 /* Prevent various kinds of signals during display
11370 update. stdio is not robust about handling
11371 signals, which can cause an apparent I/O
11372 error. */
11373 if (interrupt_input)
11374 unrequest_sigio ();
11375 STOP_POLLING;
11376
11377 /* Update the display. */
11378 set_window_update_flags (XWINDOW (f->root_window), 1);
11379 pause |= update_frame (f, 0, 0);
11380 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
11381 if (pause)
11382 break;
11383 #endif
11384
11385 f->updated_p = 1;
11386 }
11387 }
11388 }
11389
11390 if (!pause)
11391 {
11392 /* Do the mark_window_display_accurate after all windows have
11393 been redisplayed because this call resets flags in buffers
11394 which are needed for proper redisplay. */
11395 FOR_EACH_FRAME (tail, frame)
11396 {
11397 struct frame *f = XFRAME (frame);
11398 if (f->updated_p)
11399 {
11400 mark_window_display_accurate (f->root_window, 1);
11401 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
11402 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
11403 }
11404 }
11405 }
11406 }
11407 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11408 {
11409 Lisp_Object mini_window;
11410 struct frame *mini_frame;
11411
11412 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
11413 /* Use list_of_error, not Qerror, so that
11414 we catch only errors and don't run the debugger. */
11415 internal_condition_case_1 (redisplay_window_1, selected_window,
11416 list_of_error,
11417 redisplay_window_error);
11418
11419 /* Compare desired and current matrices, perform output. */
11420
11421 update:
11422 /* If fonts changed, display again. */
11423 if (fonts_changed_p)
11424 goto retry;
11425
11426 /* Prevent various kinds of signals during display update.
11427 stdio is not robust about handling signals,
11428 which can cause an apparent I/O error. */
11429 if (interrupt_input)
11430 unrequest_sigio ();
11431 STOP_POLLING;
11432
11433 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11434 {
11435 if (hscroll_windows (selected_window))
11436 goto retry;
11437
11438 XWINDOW (selected_window)->must_be_updated_p = 1;
11439 pause = update_frame (sf, 0, 0);
11440 }
11441
11442 /* We may have called echo_area_display at the top of this
11443 function. If the echo area is on another frame, that may
11444 have put text on a frame other than the selected one, so the
11445 above call to update_frame would not have caught it. Catch
11446 it here. */
11447 mini_window = FRAME_MINIBUF_WINDOW (sf);
11448 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
11449
11450 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
11451 {
11452 XWINDOW (mini_window)->must_be_updated_p = 1;
11453 pause |= update_frame (mini_frame, 0, 0);
11454 if (!pause && hscroll_windows (mini_window))
11455 goto retry;
11456 }
11457 }
11458
11459 /* If display was paused because of pending input, make sure we do a
11460 thorough update the next time. */
11461 if (pause)
11462 {
11463 /* Prevent the optimization at the beginning of
11464 redisplay_internal that tries a single-line update of the
11465 line containing the cursor in the selected window. */
11466 CHARPOS (this_line_start_pos) = 0;
11467
11468 /* Let the overlay arrow be updated the next time. */
11469 update_overlay_arrows (0);
11470
11471 /* If we pause after scrolling, some rows in the current
11472 matrices of some windows are not valid. */
11473 if (!WINDOW_FULL_WIDTH_P (w)
11474 && !FRAME_WINDOW_P (XFRAME (w->frame)))
11475 update_mode_lines = 1;
11476 }
11477 else
11478 {
11479 if (!consider_all_windows_p)
11480 {
11481 /* This has already been done above if
11482 consider_all_windows_p is set. */
11483 mark_window_display_accurate_1 (w, 1);
11484
11485 /* Say overlay arrows are up to date. */
11486 update_overlay_arrows (1);
11487
11488 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
11489 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
11490 }
11491
11492 update_mode_lines = 0;
11493 windows_or_buffers_changed = 0;
11494 cursor_type_changed = 0;
11495 }
11496
11497 /* Start SIGIO interrupts coming again. Having them off during the
11498 code above makes it less likely one will discard output, but not
11499 impossible, since there might be stuff in the system buffer here.
11500 But it is much hairier to try to do anything about that. */
11501 if (interrupt_input)
11502 request_sigio ();
11503 RESUME_POLLING;
11504
11505 /* If a frame has become visible which was not before, redisplay
11506 again, so that we display it. Expose events for such a frame
11507 (which it gets when becoming visible) don't call the parts of
11508 redisplay constructing glyphs, so simply exposing a frame won't
11509 display anything in this case. So, we have to display these
11510 frames here explicitly. */
11511 if (!pause)
11512 {
11513 Lisp_Object tail, frame;
11514 int new_count = 0;
11515
11516 FOR_EACH_FRAME (tail, frame)
11517 {
11518 int this_is_visible = 0;
11519
11520 if (XFRAME (frame)->visible)
11521 this_is_visible = 1;
11522 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
11523 if (XFRAME (frame)->visible)
11524 this_is_visible = 1;
11525
11526 if (this_is_visible)
11527 new_count++;
11528 }
11529
11530 if (new_count != number_of_visible_frames)
11531 windows_or_buffers_changed++;
11532 }
11533
11534 /* Change frame size now if a change is pending. */
11535 do_pending_window_change (1);
11536
11537 /* If we just did a pending size change, or have additional
11538 visible frames, redisplay again. */
11539 if (windows_or_buffers_changed && !pause)
11540 goto retry;
11541
11542 /* Clear the face cache eventually. */
11543 if (consider_all_windows_p)
11544 {
11545 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
11546 {
11547 clear_face_cache (0);
11548 clear_face_cache_count = 0;
11549 }
11550 #ifdef HAVE_WINDOW_SYSTEM
11551 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
11552 {
11553 Lisp_Object tail, frame;
11554 FOR_EACH_FRAME (tail, frame)
11555 {
11556 struct frame *f = XFRAME (frame);
11557 if (FRAME_WINDOW_P (f))
11558 clear_image_cache (f, 0);
11559 }
11560 clear_image_cache_count = 0;
11561 }
11562 #endif /* HAVE_WINDOW_SYSTEM */
11563 }
11564
11565 end_of_redisplay:
11566 unbind_to (count, Qnil);
11567 RESUME_POLLING;
11568 }
11569
11570
11571 /* Redisplay, but leave alone any recent echo area message unless
11572 another message has been requested in its place.
11573
11574 This is useful in situations where you need to redisplay but no
11575 user action has occurred, making it inappropriate for the message
11576 area to be cleared. See tracking_off and
11577 wait_reading_process_output for examples of these situations.
11578
11579 FROM_WHERE is an integer saying from where this function was
11580 called. This is useful for debugging. */
11581
11582 void
11583 redisplay_preserve_echo_area (from_where)
11584 int from_where;
11585 {
11586 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
11587
11588 if (!NILP (echo_area_buffer[1]))
11589 {
11590 /* We have a previously displayed message, but no current
11591 message. Redisplay the previous message. */
11592 display_last_displayed_message_p = 1;
11593 redisplay_internal (1);
11594 display_last_displayed_message_p = 0;
11595 }
11596 else
11597 redisplay_internal (1);
11598
11599 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
11600 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11601 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
11602 }
11603
11604
11605 /* Function registered with record_unwind_protect in
11606 redisplay_internal. Reset redisplaying_p to the value it had
11607 before redisplay_internal was called, and clear
11608 prevent_freeing_realized_faces_p. It also selects the previously
11609 selected frame, unless it has been deleted (by an X connection
11610 failure during redisplay, for example). */
11611
11612 static Lisp_Object
11613 unwind_redisplay (val)
11614 Lisp_Object val;
11615 {
11616 Lisp_Object old_redisplaying_p, old_frame;
11617
11618 old_redisplaying_p = XCAR (val);
11619 redisplaying_p = XFASTINT (old_redisplaying_p);
11620 old_frame = XCDR (val);
11621 if (! EQ (old_frame, selected_frame)
11622 && FRAME_LIVE_P (XFRAME (old_frame)))
11623 select_frame_for_redisplay (old_frame);
11624 return Qnil;
11625 }
11626
11627
11628 /* Mark the display of window W as accurate or inaccurate. If
11629 ACCURATE_P is non-zero mark display of W as accurate. If
11630 ACCURATE_P is zero, arrange for W to be redisplayed the next time
11631 redisplay_internal is called. */
11632
11633 static void
11634 mark_window_display_accurate_1 (w, accurate_p)
11635 struct window *w;
11636 int accurate_p;
11637 {
11638 if (BUFFERP (w->buffer))
11639 {
11640 struct buffer *b = XBUFFER (w->buffer);
11641
11642 w->last_modified
11643 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
11644 w->last_overlay_modified
11645 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
11646 w->last_had_star
11647 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
11648
11649 if (accurate_p)
11650 {
11651 b->clip_changed = 0;
11652 b->prevent_redisplay_optimizations_p = 0;
11653
11654 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
11655 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
11656 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
11657 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
11658
11659 w->current_matrix->buffer = b;
11660 w->current_matrix->begv = BUF_BEGV (b);
11661 w->current_matrix->zv = BUF_ZV (b);
11662
11663 w->last_cursor = w->cursor;
11664 w->last_cursor_off_p = w->cursor_off_p;
11665
11666 if (w == XWINDOW (selected_window))
11667 w->last_point = make_number (BUF_PT (b));
11668 else
11669 w->last_point = make_number (XMARKER (w->pointm)->charpos);
11670 }
11671 }
11672
11673 if (accurate_p)
11674 {
11675 w->window_end_valid = w->buffer;
11676 #if 0 /* This is incorrect with variable-height lines. */
11677 xassert (XINT (w->window_end_vpos)
11678 < (WINDOW_TOTAL_LINES (w)
11679 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
11680 #endif
11681 w->update_mode_line = Qnil;
11682 }
11683 }
11684
11685
11686 /* Mark the display of windows in the window tree rooted at WINDOW as
11687 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
11688 windows as accurate. If ACCURATE_P is zero, arrange for windows to
11689 be redisplayed the next time redisplay_internal is called. */
11690
11691 void
11692 mark_window_display_accurate (window, accurate_p)
11693 Lisp_Object window;
11694 int accurate_p;
11695 {
11696 struct window *w;
11697
11698 for (; !NILP (window); window = w->next)
11699 {
11700 w = XWINDOW (window);
11701 mark_window_display_accurate_1 (w, accurate_p);
11702
11703 if (!NILP (w->vchild))
11704 mark_window_display_accurate (w->vchild, accurate_p);
11705 if (!NILP (w->hchild))
11706 mark_window_display_accurate (w->hchild, accurate_p);
11707 }
11708
11709 if (accurate_p)
11710 {
11711 update_overlay_arrows (1);
11712 }
11713 else
11714 {
11715 /* Force a thorough redisplay the next time by setting
11716 last_arrow_position and last_arrow_string to t, which is
11717 unequal to any useful value of Voverlay_arrow_... */
11718 update_overlay_arrows (-1);
11719 }
11720 }
11721
11722
11723 /* Return value in display table DP (Lisp_Char_Table *) for character
11724 C. Since a display table doesn't have any parent, we don't have to
11725 follow parent. Do not call this function directly but use the
11726 macro DISP_CHAR_VECTOR. */
11727
11728 Lisp_Object
11729 disp_char_vector (dp, c)
11730 struct Lisp_Char_Table *dp;
11731 int c;
11732 {
11733 int code[4], i;
11734 Lisp_Object val;
11735
11736 if (SINGLE_BYTE_CHAR_P (c))
11737 return (dp->contents[c]);
11738
11739 SPLIT_CHAR (c, code[0], code[1], code[2]);
11740 if (code[1] < 32)
11741 code[1] = -1;
11742 else if (code[2] < 32)
11743 code[2] = -1;
11744
11745 /* Here, the possible range of code[0] (== charset ID) is
11746 128..max_charset. Since the top level char table contains data
11747 for multibyte characters after 256th element, we must increment
11748 code[0] by 128 to get a correct index. */
11749 code[0] += 128;
11750 code[3] = -1; /* anchor */
11751
11752 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
11753 {
11754 val = dp->contents[code[i]];
11755 if (!SUB_CHAR_TABLE_P (val))
11756 return (NILP (val) ? dp->defalt : val);
11757 }
11758
11759 /* Here, val is a sub char table. We return the default value of
11760 it. */
11761 return (dp->defalt);
11762 }
11763
11764
11765 \f
11766 /***********************************************************************
11767 Window Redisplay
11768 ***********************************************************************/
11769
11770 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
11771
11772 static void
11773 redisplay_windows (window)
11774 Lisp_Object window;
11775 {
11776 while (!NILP (window))
11777 {
11778 struct window *w = XWINDOW (window);
11779
11780 if (!NILP (w->hchild))
11781 redisplay_windows (w->hchild);
11782 else if (!NILP (w->vchild))
11783 redisplay_windows (w->vchild);
11784 else
11785 {
11786 displayed_buffer = XBUFFER (w->buffer);
11787 /* Use list_of_error, not Qerror, so that
11788 we catch only errors and don't run the debugger. */
11789 internal_condition_case_1 (redisplay_window_0, window,
11790 list_of_error,
11791 redisplay_window_error);
11792 }
11793
11794 window = w->next;
11795 }
11796 }
11797
11798 static Lisp_Object
11799 redisplay_window_error ()
11800 {
11801 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
11802 return Qnil;
11803 }
11804
11805 static Lisp_Object
11806 redisplay_window_0 (window)
11807 Lisp_Object window;
11808 {
11809 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11810 redisplay_window (window, 0);
11811 return Qnil;
11812 }
11813
11814 static Lisp_Object
11815 redisplay_window_1 (window)
11816 Lisp_Object window;
11817 {
11818 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11819 redisplay_window (window, 1);
11820 return Qnil;
11821 }
11822 \f
11823
11824 /* Increment GLYPH until it reaches END or CONDITION fails while
11825 adding (GLYPH)->pixel_width to X. */
11826
11827 #define SKIP_GLYPHS(glyph, end, x, condition) \
11828 do \
11829 { \
11830 (x) += (glyph)->pixel_width; \
11831 ++(glyph); \
11832 } \
11833 while ((glyph) < (end) && (condition))
11834
11835
11836 /* Set cursor position of W. PT is assumed to be displayed in ROW.
11837 DELTA is the number of bytes by which positions recorded in ROW
11838 differ from current buffer positions.
11839
11840 Return 0 if cursor is not on this row. 1 otherwise. */
11841
11842 int
11843 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
11844 struct window *w;
11845 struct glyph_row *row;
11846 struct glyph_matrix *matrix;
11847 int delta, delta_bytes, dy, dvpos;
11848 {
11849 struct glyph *glyph = row->glyphs[TEXT_AREA];
11850 struct glyph *end = glyph + row->used[TEXT_AREA];
11851 struct glyph *cursor = NULL;
11852 /* The first glyph that starts a sequence of glyphs from string. */
11853 struct glyph *string_start;
11854 /* The X coordinate of string_start. */
11855 int string_start_x;
11856 /* The last known character position. */
11857 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
11858 /* The last known character position before string_start. */
11859 int string_before_pos;
11860 int x = row->x;
11861 int cursor_x = x;
11862 int cursor_from_overlay_pos = 0;
11863 int pt_old = PT - delta;
11864
11865 /* Skip over glyphs not having an object at the start of the row.
11866 These are special glyphs like truncation marks on terminal
11867 frames. */
11868 if (row->displays_text_p)
11869 while (glyph < end
11870 && INTEGERP (glyph->object)
11871 && glyph->charpos < 0)
11872 {
11873 x += glyph->pixel_width;
11874 ++glyph;
11875 }
11876
11877 string_start = NULL;
11878 while (glyph < end
11879 && !INTEGERP (glyph->object)
11880 && (!BUFFERP (glyph->object)
11881 || (last_pos = glyph->charpos) < pt_old))
11882 {
11883 if (! STRINGP (glyph->object))
11884 {
11885 string_start = NULL;
11886 x += glyph->pixel_width;
11887 ++glyph;
11888 if (cursor_from_overlay_pos
11889 && last_pos >= cursor_from_overlay_pos)
11890 {
11891 cursor_from_overlay_pos = 0;
11892 cursor = 0;
11893 }
11894 }
11895 else
11896 {
11897 if (string_start == NULL)
11898 {
11899 string_before_pos = last_pos;
11900 string_start = glyph;
11901 string_start_x = x;
11902 }
11903 /* Skip all glyphs from string. */
11904 do
11905 {
11906 Lisp_Object cprop;
11907 int pos;
11908 if ((cursor == NULL || glyph > cursor)
11909 && (cprop = Fget_char_property (make_number ((glyph)->charpos),
11910 Qcursor, (glyph)->object),
11911 !NILP (cprop))
11912 && (pos = string_buffer_position (w, glyph->object,
11913 string_before_pos),
11914 (pos == 0 /* From overlay */
11915 || pos == pt_old)))
11916 {
11917 /* Estimate overlay buffer position from the buffer
11918 positions of the glyphs before and after the overlay.
11919 Add 1 to last_pos so that if point corresponds to the
11920 glyph right after the overlay, we still use a 'cursor'
11921 property found in that overlay. */
11922 cursor_from_overlay_pos = (pos ? 0 : last_pos
11923 + (INTEGERP (cprop) ? XINT (cprop) : 0));
11924 cursor = glyph;
11925 cursor_x = x;
11926 }
11927 x += glyph->pixel_width;
11928 ++glyph;
11929 }
11930 while (glyph < end && EQ (glyph->object, string_start->object));
11931 }
11932 }
11933
11934 if (cursor != NULL)
11935 {
11936 glyph = cursor;
11937 x = cursor_x;
11938 }
11939 else if (row->ends_in_ellipsis_p && glyph == end)
11940 {
11941 /* Scan back over the ellipsis glyphs, decrementing positions. */
11942 while (glyph > row->glyphs[TEXT_AREA]
11943 && (glyph - 1)->charpos == last_pos)
11944 glyph--, x -= glyph->pixel_width;
11945 /* That loop always goes one position too far,
11946 including the glyph before the ellipsis.
11947 So scan forward over that one. */
11948 x += glyph->pixel_width;
11949 glyph++;
11950 }
11951 else if (string_start
11952 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
11953 {
11954 /* We may have skipped over point because the previous glyphs
11955 are from string. As there's no easy way to know the
11956 character position of the current glyph, find the correct
11957 glyph on point by scanning from string_start again. */
11958 Lisp_Object limit;
11959 Lisp_Object string;
11960 struct glyph *stop = glyph;
11961 int pos;
11962
11963 limit = make_number (pt_old + 1);
11964 glyph = string_start;
11965 x = string_start_x;
11966 string = glyph->object;
11967 pos = string_buffer_position (w, string, string_before_pos);
11968 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11969 because we always put cursor after overlay strings. */
11970 while (pos == 0 && glyph < stop)
11971 {
11972 string = glyph->object;
11973 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
11974 if (glyph < stop)
11975 pos = string_buffer_position (w, glyph->object, string_before_pos);
11976 }
11977
11978 while (glyph < stop)
11979 {
11980 pos = XINT (Fnext_single_char_property_change
11981 (make_number (pos), Qdisplay, Qnil, limit));
11982 if (pos > pt_old)
11983 break;
11984 /* Skip glyphs from the same string. */
11985 string = glyph->object;
11986 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
11987 /* Skip glyphs from an overlay. */
11988 while (glyph < stop
11989 && ! string_buffer_position (w, glyph->object, pos))
11990 {
11991 string = glyph->object;
11992 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
11993 }
11994 }
11995
11996 /* If we reached the end of the line, and end was from a string,
11997 cursor is not on this line. */
11998 if (glyph == end && row->continued_p)
11999 return 0;
12000 }
12001
12002 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12003 w->cursor.x = x;
12004 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12005 w->cursor.y = row->y + dy;
12006
12007 if (w == XWINDOW (selected_window))
12008 {
12009 if (!row->continued_p
12010 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12011 && row->x == 0)
12012 {
12013 this_line_buffer = XBUFFER (w->buffer);
12014
12015 CHARPOS (this_line_start_pos)
12016 = MATRIX_ROW_START_CHARPOS (row) + delta;
12017 BYTEPOS (this_line_start_pos)
12018 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12019
12020 CHARPOS (this_line_end_pos)
12021 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12022 BYTEPOS (this_line_end_pos)
12023 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12024
12025 this_line_y = w->cursor.y;
12026 this_line_pixel_height = row->height;
12027 this_line_vpos = w->cursor.vpos;
12028 this_line_start_x = row->x;
12029 }
12030 else
12031 CHARPOS (this_line_start_pos) = 0;
12032 }
12033
12034 return 1;
12035 }
12036
12037
12038 /* Run window scroll functions, if any, for WINDOW with new window
12039 start STARTP. Sets the window start of WINDOW to that position.
12040
12041 We assume that the window's buffer is really current. */
12042
12043 static INLINE struct text_pos
12044 run_window_scroll_functions (window, startp)
12045 Lisp_Object window;
12046 struct text_pos startp;
12047 {
12048 struct window *w = XWINDOW (window);
12049 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12050
12051 if (current_buffer != XBUFFER (w->buffer))
12052 abort ();
12053
12054 if (!NILP (Vwindow_scroll_functions))
12055 {
12056 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12057 make_number (CHARPOS (startp)));
12058 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12059 /* In case the hook functions switch buffers. */
12060 if (current_buffer != XBUFFER (w->buffer))
12061 set_buffer_internal_1 (XBUFFER (w->buffer));
12062 }
12063
12064 return startp;
12065 }
12066
12067
12068 /* Make sure the line containing the cursor is fully visible.
12069 A value of 1 means there is nothing to be done.
12070 (Either the line is fully visible, or it cannot be made so,
12071 or we cannot tell.)
12072
12073 If FORCE_P is non-zero, return 0 even if partial visible cursor row
12074 is higher than window.
12075
12076 A value of 0 means the caller should do scrolling
12077 as if point had gone off the screen. */
12078
12079 static int
12080 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
12081 struct window *w;
12082 int force_p;
12083 int current_matrix_p;
12084 {
12085 struct glyph_matrix *matrix;
12086 struct glyph_row *row;
12087 int window_height;
12088
12089 if (!make_cursor_line_fully_visible_p)
12090 return 1;
12091
12092 /* It's not always possible to find the cursor, e.g, when a window
12093 is full of overlay strings. Don't do anything in that case. */
12094 if (w->cursor.vpos < 0)
12095 return 1;
12096
12097 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
12098 row = MATRIX_ROW (matrix, w->cursor.vpos);
12099
12100 /* If the cursor row is not partially visible, there's nothing to do. */
12101 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
12102 return 1;
12103
12104 /* If the row the cursor is in is taller than the window's height,
12105 it's not clear what to do, so do nothing. */
12106 window_height = window_box_height (w);
12107 if (row->height >= window_height)
12108 {
12109 if (!force_p || MINI_WINDOW_P (w)
12110 || w->vscroll || w->cursor.vpos == 0)
12111 return 1;
12112 }
12113 return 0;
12114
12115 #if 0
12116 /* This code used to try to scroll the window just enough to make
12117 the line visible. It returned 0 to say that the caller should
12118 allocate larger glyph matrices. */
12119
12120 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
12121 {
12122 int dy = row->height - row->visible_height;
12123 w->vscroll = 0;
12124 w->cursor.y += dy;
12125 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12126 }
12127 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
12128 {
12129 int dy = - (row->height - row->visible_height);
12130 w->vscroll = dy;
12131 w->cursor.y += dy;
12132 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12133 }
12134
12135 /* When we change the cursor y-position of the selected window,
12136 change this_line_y as well so that the display optimization for
12137 the cursor line of the selected window in redisplay_internal uses
12138 the correct y-position. */
12139 if (w == XWINDOW (selected_window))
12140 this_line_y = w->cursor.y;
12141
12142 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
12143 redisplay with larger matrices. */
12144 if (matrix->nrows < required_matrix_height (w))
12145 {
12146 fonts_changed_p = 1;
12147 return 0;
12148 }
12149
12150 return 1;
12151 #endif /* 0 */
12152 }
12153
12154
12155 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
12156 non-zero means only WINDOW is redisplayed in redisplay_internal.
12157 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
12158 in redisplay_window to bring a partially visible line into view in
12159 the case that only the cursor has moved.
12160
12161 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
12162 last screen line's vertical height extends past the end of the screen.
12163
12164 Value is
12165
12166 1 if scrolling succeeded
12167
12168 0 if scrolling didn't find point.
12169
12170 -1 if new fonts have been loaded so that we must interrupt
12171 redisplay, adjust glyph matrices, and try again. */
12172
12173 enum
12174 {
12175 SCROLLING_SUCCESS,
12176 SCROLLING_FAILED,
12177 SCROLLING_NEED_LARGER_MATRICES
12178 };
12179
12180 static int
12181 try_scrolling (window, just_this_one_p, scroll_conservatively,
12182 scroll_step, temp_scroll_step, last_line_misfit)
12183 Lisp_Object window;
12184 int just_this_one_p;
12185 EMACS_INT scroll_conservatively, scroll_step;
12186 int temp_scroll_step;
12187 int last_line_misfit;
12188 {
12189 struct window *w = XWINDOW (window);
12190 struct frame *f = XFRAME (w->frame);
12191 struct text_pos scroll_margin_pos;
12192 struct text_pos pos;
12193 struct text_pos startp;
12194 struct it it;
12195 Lisp_Object window_end;
12196 int this_scroll_margin;
12197 int dy = 0;
12198 int scroll_max;
12199 int rc;
12200 int amount_to_scroll = 0;
12201 Lisp_Object aggressive;
12202 int height;
12203 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
12204
12205 #if GLYPH_DEBUG
12206 debug_method_add (w, "try_scrolling");
12207 #endif
12208
12209 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12210
12211 /* Compute scroll margin height in pixels. We scroll when point is
12212 within this distance from the top or bottom of the window. */
12213 if (scroll_margin > 0)
12214 {
12215 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12216 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12217 }
12218 else
12219 this_scroll_margin = 0;
12220
12221 /* Force scroll_conservatively to have a reasonable value so it doesn't
12222 cause an overflow while computing how much to scroll. */
12223 if (scroll_conservatively)
12224 scroll_conservatively = min (scroll_conservatively,
12225 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
12226
12227 /* Compute how much we should try to scroll maximally to bring point
12228 into view. */
12229 if (scroll_step || scroll_conservatively || temp_scroll_step)
12230 scroll_max = max (scroll_step,
12231 max (scroll_conservatively, temp_scroll_step));
12232 else if (NUMBERP (current_buffer->scroll_down_aggressively)
12233 || NUMBERP (current_buffer->scroll_up_aggressively))
12234 /* We're trying to scroll because of aggressive scrolling
12235 but no scroll_step is set. Choose an arbitrary one. Maybe
12236 there should be a variable for this. */
12237 scroll_max = 10;
12238 else
12239 scroll_max = 0;
12240 scroll_max *= FRAME_LINE_HEIGHT (f);
12241
12242 /* Decide whether we have to scroll down. Start at the window end
12243 and move this_scroll_margin up to find the position of the scroll
12244 margin. */
12245 window_end = Fwindow_end (window, Qt);
12246
12247 too_near_end:
12248
12249 CHARPOS (scroll_margin_pos) = XINT (window_end);
12250 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
12251
12252 if (this_scroll_margin || extra_scroll_margin_lines)
12253 {
12254 start_display (&it, w, scroll_margin_pos);
12255 if (this_scroll_margin)
12256 move_it_vertically_backward (&it, this_scroll_margin);
12257 if (extra_scroll_margin_lines)
12258 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
12259 scroll_margin_pos = it.current.pos;
12260 }
12261
12262 if (PT >= CHARPOS (scroll_margin_pos))
12263 {
12264 int y0;
12265
12266 /* Point is in the scroll margin at the bottom of the window, or
12267 below. Compute a new window start that makes point visible. */
12268
12269 /* Compute the distance from the scroll margin to PT.
12270 Give up if the distance is greater than scroll_max. */
12271 start_display (&it, w, scroll_margin_pos);
12272 y0 = it.current_y;
12273 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12274 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12275
12276 /* To make point visible, we have to move the window start
12277 down so that the line the cursor is in is visible, which
12278 means we have to add in the height of the cursor line. */
12279 dy = line_bottom_y (&it) - y0;
12280
12281 if (dy > scroll_max)
12282 return SCROLLING_FAILED;
12283
12284 /* Move the window start down. If scrolling conservatively,
12285 move it just enough down to make point visible. If
12286 scroll_step is set, move it down by scroll_step. */
12287 start_display (&it, w, startp);
12288
12289 if (scroll_conservatively)
12290 /* Set AMOUNT_TO_SCROLL to at least one line,
12291 and at most scroll_conservatively lines. */
12292 amount_to_scroll
12293 = min (max (dy, FRAME_LINE_HEIGHT (f)),
12294 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
12295 else if (scroll_step || temp_scroll_step)
12296 amount_to_scroll = scroll_max;
12297 else
12298 {
12299 aggressive = current_buffer->scroll_up_aggressively;
12300 height = WINDOW_BOX_TEXT_HEIGHT (w);
12301 if (NUMBERP (aggressive))
12302 {
12303 double float_amount = XFLOATINT (aggressive) * height;
12304 amount_to_scroll = float_amount;
12305 if (amount_to_scroll == 0 && float_amount > 0)
12306 amount_to_scroll = 1;
12307 }
12308 }
12309
12310 if (amount_to_scroll <= 0)
12311 return SCROLLING_FAILED;
12312
12313 /* If moving by amount_to_scroll leaves STARTP unchanged,
12314 move it down one screen line. */
12315
12316 move_it_vertically (&it, amount_to_scroll);
12317 if (CHARPOS (it.current.pos) == CHARPOS (startp))
12318 move_it_by_lines (&it, 1, 1);
12319 startp = it.current.pos;
12320 }
12321 else
12322 {
12323 /* See if point is inside the scroll margin at the top of the
12324 window. */
12325 scroll_margin_pos = startp;
12326 if (this_scroll_margin)
12327 {
12328 start_display (&it, w, startp);
12329 move_it_vertically (&it, this_scroll_margin);
12330 scroll_margin_pos = it.current.pos;
12331 }
12332
12333 if (PT < CHARPOS (scroll_margin_pos))
12334 {
12335 /* Point is in the scroll margin at the top of the window or
12336 above what is displayed in the window. */
12337 int y0;
12338
12339 /* Compute the vertical distance from PT to the scroll
12340 margin position. Give up if distance is greater than
12341 scroll_max. */
12342 SET_TEXT_POS (pos, PT, PT_BYTE);
12343 start_display (&it, w, pos);
12344 y0 = it.current_y;
12345 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
12346 it.last_visible_y, -1,
12347 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12348 dy = it.current_y - y0;
12349 if (dy > scroll_max)
12350 return SCROLLING_FAILED;
12351
12352 /* Compute new window start. */
12353 start_display (&it, w, startp);
12354
12355 if (scroll_conservatively)
12356 amount_to_scroll
12357 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
12358 else if (scroll_step || temp_scroll_step)
12359 amount_to_scroll = scroll_max;
12360 else
12361 {
12362 aggressive = current_buffer->scroll_down_aggressively;
12363 height = WINDOW_BOX_TEXT_HEIGHT (w);
12364 if (NUMBERP (aggressive))
12365 {
12366 double float_amount = XFLOATINT (aggressive) * height;
12367 amount_to_scroll = float_amount;
12368 if (amount_to_scroll == 0 && float_amount > 0)
12369 amount_to_scroll = 1;
12370 }
12371 }
12372
12373 if (amount_to_scroll <= 0)
12374 return SCROLLING_FAILED;
12375
12376 move_it_vertically_backward (&it, amount_to_scroll);
12377 startp = it.current.pos;
12378 }
12379 }
12380
12381 /* Run window scroll functions. */
12382 startp = run_window_scroll_functions (window, startp);
12383
12384 /* Display the window. Give up if new fonts are loaded, or if point
12385 doesn't appear. */
12386 if (!try_window (window, startp, 0))
12387 rc = SCROLLING_NEED_LARGER_MATRICES;
12388 else if (w->cursor.vpos < 0)
12389 {
12390 clear_glyph_matrix (w->desired_matrix);
12391 rc = SCROLLING_FAILED;
12392 }
12393 else
12394 {
12395 /* Maybe forget recorded base line for line number display. */
12396 if (!just_this_one_p
12397 || current_buffer->clip_changed
12398 || BEG_UNCHANGED < CHARPOS (startp))
12399 w->base_line_number = Qnil;
12400
12401 /* If cursor ends up on a partially visible line,
12402 treat that as being off the bottom of the screen. */
12403 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
12404 {
12405 clear_glyph_matrix (w->desired_matrix);
12406 ++extra_scroll_margin_lines;
12407 goto too_near_end;
12408 }
12409 rc = SCROLLING_SUCCESS;
12410 }
12411
12412 return rc;
12413 }
12414
12415
12416 /* Compute a suitable window start for window W if display of W starts
12417 on a continuation line. Value is non-zero if a new window start
12418 was computed.
12419
12420 The new window start will be computed, based on W's width, starting
12421 from the start of the continued line. It is the start of the
12422 screen line with the minimum distance from the old start W->start. */
12423
12424 static int
12425 compute_window_start_on_continuation_line (w)
12426 struct window *w;
12427 {
12428 struct text_pos pos, start_pos;
12429 int window_start_changed_p = 0;
12430
12431 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
12432
12433 /* If window start is on a continuation line... Window start may be
12434 < BEGV in case there's invisible text at the start of the
12435 buffer (M-x rmail, for example). */
12436 if (CHARPOS (start_pos) > BEGV
12437 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
12438 {
12439 struct it it;
12440 struct glyph_row *row;
12441
12442 /* Handle the case that the window start is out of range. */
12443 if (CHARPOS (start_pos) < BEGV)
12444 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
12445 else if (CHARPOS (start_pos) > ZV)
12446 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
12447
12448 /* Find the start of the continued line. This should be fast
12449 because scan_buffer is fast (newline cache). */
12450 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
12451 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
12452 row, DEFAULT_FACE_ID);
12453 reseat_at_previous_visible_line_start (&it);
12454
12455 /* If the line start is "too far" away from the window start,
12456 say it takes too much time to compute a new window start. */
12457 if (CHARPOS (start_pos) - IT_CHARPOS (it)
12458 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
12459 {
12460 int min_distance, distance;
12461
12462 /* Move forward by display lines to find the new window
12463 start. If window width was enlarged, the new start can
12464 be expected to be > the old start. If window width was
12465 decreased, the new window start will be < the old start.
12466 So, we're looking for the display line start with the
12467 minimum distance from the old window start. */
12468 pos = it.current.pos;
12469 min_distance = INFINITY;
12470 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
12471 distance < min_distance)
12472 {
12473 min_distance = distance;
12474 pos = it.current.pos;
12475 move_it_by_lines (&it, 1, 0);
12476 }
12477
12478 /* Set the window start there. */
12479 SET_MARKER_FROM_TEXT_POS (w->start, pos);
12480 window_start_changed_p = 1;
12481 }
12482 }
12483
12484 return window_start_changed_p;
12485 }
12486
12487
12488 /* Try cursor movement in case text has not changed in window WINDOW,
12489 with window start STARTP. Value is
12490
12491 CURSOR_MOVEMENT_SUCCESS if successful
12492
12493 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
12494
12495 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
12496 display. *SCROLL_STEP is set to 1, under certain circumstances, if
12497 we want to scroll as if scroll-step were set to 1. See the code.
12498
12499 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
12500 which case we have to abort this redisplay, and adjust matrices
12501 first. */
12502
12503 enum
12504 {
12505 CURSOR_MOVEMENT_SUCCESS,
12506 CURSOR_MOVEMENT_CANNOT_BE_USED,
12507 CURSOR_MOVEMENT_MUST_SCROLL,
12508 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
12509 };
12510
12511 static int
12512 try_cursor_movement (window, startp, scroll_step)
12513 Lisp_Object window;
12514 struct text_pos startp;
12515 int *scroll_step;
12516 {
12517 struct window *w = XWINDOW (window);
12518 struct frame *f = XFRAME (w->frame);
12519 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
12520
12521 #if GLYPH_DEBUG
12522 if (inhibit_try_cursor_movement)
12523 return rc;
12524 #endif
12525
12526 /* Handle case where text has not changed, only point, and it has
12527 not moved off the frame. */
12528 if (/* Point may be in this window. */
12529 PT >= CHARPOS (startp)
12530 /* Selective display hasn't changed. */
12531 && !current_buffer->clip_changed
12532 /* Function force-mode-line-update is used to force a thorough
12533 redisplay. It sets either windows_or_buffers_changed or
12534 update_mode_lines. So don't take a shortcut here for these
12535 cases. */
12536 && !update_mode_lines
12537 && !windows_or_buffers_changed
12538 && !cursor_type_changed
12539 /* Can't use this case if highlighting a region. When a
12540 region exists, cursor movement has to do more than just
12541 set the cursor. */
12542 && !(!NILP (Vtransient_mark_mode)
12543 && !NILP (current_buffer->mark_active))
12544 && NILP (w->region_showing)
12545 && NILP (Vshow_trailing_whitespace)
12546 /* Right after splitting windows, last_point may be nil. */
12547 && INTEGERP (w->last_point)
12548 /* This code is not used for mini-buffer for the sake of the case
12549 of redisplaying to replace an echo area message; since in
12550 that case the mini-buffer contents per se are usually
12551 unchanged. This code is of no real use in the mini-buffer
12552 since the handling of this_line_start_pos, etc., in redisplay
12553 handles the same cases. */
12554 && !EQ (window, minibuf_window)
12555 /* When splitting windows or for new windows, it happens that
12556 redisplay is called with a nil window_end_vpos or one being
12557 larger than the window. This should really be fixed in
12558 window.c. I don't have this on my list, now, so we do
12559 approximately the same as the old redisplay code. --gerd. */
12560 && INTEGERP (w->window_end_vpos)
12561 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
12562 && (FRAME_WINDOW_P (f)
12563 || !overlay_arrow_in_current_buffer_p ()))
12564 {
12565 int this_scroll_margin, top_scroll_margin;
12566 struct glyph_row *row = NULL;
12567
12568 #if GLYPH_DEBUG
12569 debug_method_add (w, "cursor movement");
12570 #endif
12571
12572 /* Scroll if point within this distance from the top or bottom
12573 of the window. This is a pixel value. */
12574 this_scroll_margin = max (0, scroll_margin);
12575 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12576 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12577
12578 top_scroll_margin = this_scroll_margin;
12579 if (WINDOW_WANTS_HEADER_LINE_P (w))
12580 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
12581
12582 /* Start with the row the cursor was displayed during the last
12583 not paused redisplay. Give up if that row is not valid. */
12584 if (w->last_cursor.vpos < 0
12585 || w->last_cursor.vpos >= w->current_matrix->nrows)
12586 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12587 else
12588 {
12589 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
12590 if (row->mode_line_p)
12591 ++row;
12592 if (!row->enabled_p)
12593 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12594 }
12595
12596 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
12597 {
12598 int scroll_p = 0;
12599 int last_y = window_text_bottom_y (w) - this_scroll_margin;
12600
12601 if (PT > XFASTINT (w->last_point))
12602 {
12603 /* Point has moved forward. */
12604 while (MATRIX_ROW_END_CHARPOS (row) < PT
12605 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
12606 {
12607 xassert (row->enabled_p);
12608 ++row;
12609 }
12610
12611 /* The end position of a row equals the start position
12612 of the next row. If PT is there, we would rather
12613 display it in the next line. */
12614 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12615 && MATRIX_ROW_END_CHARPOS (row) == PT
12616 && !cursor_row_p (w, row))
12617 ++row;
12618
12619 /* If within the scroll margin, scroll. Note that
12620 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
12621 the next line would be drawn, and that
12622 this_scroll_margin can be zero. */
12623 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
12624 || PT > MATRIX_ROW_END_CHARPOS (row)
12625 /* Line is completely visible last line in window
12626 and PT is to be set in the next line. */
12627 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
12628 && PT == MATRIX_ROW_END_CHARPOS (row)
12629 && !row->ends_at_zv_p
12630 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12631 scroll_p = 1;
12632 }
12633 else if (PT < XFASTINT (w->last_point))
12634 {
12635 /* Cursor has to be moved backward. Note that PT >=
12636 CHARPOS (startp) because of the outer if-statement. */
12637 while (!row->mode_line_p
12638 && (MATRIX_ROW_START_CHARPOS (row) > PT
12639 || (MATRIX_ROW_START_CHARPOS (row) == PT
12640 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
12641 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
12642 row > w->current_matrix->rows
12643 && (row-1)->ends_in_newline_from_string_p))))
12644 && (row->y > top_scroll_margin
12645 || CHARPOS (startp) == BEGV))
12646 {
12647 xassert (row->enabled_p);
12648 --row;
12649 }
12650
12651 /* Consider the following case: Window starts at BEGV,
12652 there is invisible, intangible text at BEGV, so that
12653 display starts at some point START > BEGV. It can
12654 happen that we are called with PT somewhere between
12655 BEGV and START. Try to handle that case. */
12656 if (row < w->current_matrix->rows
12657 || row->mode_line_p)
12658 {
12659 row = w->current_matrix->rows;
12660 if (row->mode_line_p)
12661 ++row;
12662 }
12663
12664 /* Due to newlines in overlay strings, we may have to
12665 skip forward over overlay strings. */
12666 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12667 && MATRIX_ROW_END_CHARPOS (row) == PT
12668 && !cursor_row_p (w, row))
12669 ++row;
12670
12671 /* If within the scroll margin, scroll. */
12672 if (row->y < top_scroll_margin
12673 && CHARPOS (startp) != BEGV)
12674 scroll_p = 1;
12675 }
12676 else
12677 {
12678 /* Cursor did not move. So don't scroll even if cursor line
12679 is partially visible, as it was so before. */
12680 rc = CURSOR_MOVEMENT_SUCCESS;
12681 }
12682
12683 if (PT < MATRIX_ROW_START_CHARPOS (row)
12684 || PT > MATRIX_ROW_END_CHARPOS (row))
12685 {
12686 /* if PT is not in the glyph row, give up. */
12687 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12688 }
12689 else if (rc != CURSOR_MOVEMENT_SUCCESS
12690 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
12691 && make_cursor_line_fully_visible_p)
12692 {
12693 if (PT == MATRIX_ROW_END_CHARPOS (row)
12694 && !row->ends_at_zv_p
12695 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
12696 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12697 else if (row->height > window_box_height (w))
12698 {
12699 /* If we end up in a partially visible line, let's
12700 make it fully visible, except when it's taller
12701 than the window, in which case we can't do much
12702 about it. */
12703 *scroll_step = 1;
12704 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12705 }
12706 else
12707 {
12708 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12709 if (!cursor_row_fully_visible_p (w, 0, 1))
12710 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12711 else
12712 rc = CURSOR_MOVEMENT_SUCCESS;
12713 }
12714 }
12715 else if (scroll_p)
12716 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12717 else
12718 {
12719 do
12720 {
12721 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
12722 {
12723 rc = CURSOR_MOVEMENT_SUCCESS;
12724 break;
12725 }
12726 ++row;
12727 }
12728 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12729 && MATRIX_ROW_START_CHARPOS (row) == PT
12730 && cursor_row_p (w, row));
12731 }
12732 }
12733 }
12734
12735 return rc;
12736 }
12737
12738 void
12739 set_vertical_scroll_bar (w)
12740 struct window *w;
12741 {
12742 int start, end, whole;
12743
12744 /* Calculate the start and end positions for the current window.
12745 At some point, it would be nice to choose between scrollbars
12746 which reflect the whole buffer size, with special markers
12747 indicating narrowing, and scrollbars which reflect only the
12748 visible region.
12749
12750 Note that mini-buffers sometimes aren't displaying any text. */
12751 if (!MINI_WINDOW_P (w)
12752 || (w == XWINDOW (minibuf_window)
12753 && NILP (echo_area_buffer[0])))
12754 {
12755 struct buffer *buf = XBUFFER (w->buffer);
12756 whole = BUF_ZV (buf) - BUF_BEGV (buf);
12757 start = marker_position (w->start) - BUF_BEGV (buf);
12758 /* I don't think this is guaranteed to be right. For the
12759 moment, we'll pretend it is. */
12760 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
12761
12762 if (end < start)
12763 end = start;
12764 if (whole < (end - start))
12765 whole = end - start;
12766 }
12767 else
12768 start = end = whole = 0;
12769
12770 /* Indicate what this scroll bar ought to be displaying now. */
12771 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
12772 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
12773 (w, end - start, whole, start);
12774 }
12775
12776
12777 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
12778 selected_window is redisplayed.
12779
12780 We can return without actually redisplaying the window if
12781 fonts_changed_p is nonzero. In that case, redisplay_internal will
12782 retry. */
12783
12784 static void
12785 redisplay_window (window, just_this_one_p)
12786 Lisp_Object window;
12787 int just_this_one_p;
12788 {
12789 struct window *w = XWINDOW (window);
12790 struct frame *f = XFRAME (w->frame);
12791 struct buffer *buffer = XBUFFER (w->buffer);
12792 struct buffer *old = current_buffer;
12793 struct text_pos lpoint, opoint, startp;
12794 int update_mode_line;
12795 int tem;
12796 struct it it;
12797 /* Record it now because it's overwritten. */
12798 int current_matrix_up_to_date_p = 0;
12799 int used_current_matrix_p = 0;
12800 /* This is less strict than current_matrix_up_to_date_p.
12801 It indictes that the buffer contents and narrowing are unchanged. */
12802 int buffer_unchanged_p = 0;
12803 int temp_scroll_step = 0;
12804 int count = SPECPDL_INDEX ();
12805 int rc;
12806 int centering_position = -1;
12807 int last_line_misfit = 0;
12808 int beg_unchanged, end_unchanged;
12809
12810 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12811 opoint = lpoint;
12812
12813 /* W must be a leaf window here. */
12814 xassert (!NILP (w->buffer));
12815 #if GLYPH_DEBUG
12816 *w->desired_matrix->method = 0;
12817 #endif
12818
12819 specbind (Qinhibit_point_motion_hooks, Qt);
12820
12821 reconsider_clip_changes (w, buffer);
12822
12823 /* Has the mode line to be updated? */
12824 update_mode_line = (!NILP (w->update_mode_line)
12825 || update_mode_lines
12826 || buffer->clip_changed
12827 || buffer->prevent_redisplay_optimizations_p);
12828
12829 if (MINI_WINDOW_P (w))
12830 {
12831 if (w == XWINDOW (echo_area_window)
12832 && !NILP (echo_area_buffer[0]))
12833 {
12834 if (update_mode_line)
12835 /* We may have to update a tty frame's menu bar or a
12836 tool-bar. Example `M-x C-h C-h C-g'. */
12837 goto finish_menu_bars;
12838 else
12839 /* We've already displayed the echo area glyphs in this window. */
12840 goto finish_scroll_bars;
12841 }
12842 else if ((w != XWINDOW (minibuf_window)
12843 || minibuf_level == 0)
12844 /* When buffer is nonempty, redisplay window normally. */
12845 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
12846 /* Quail displays non-mini buffers in minibuffer window.
12847 In that case, redisplay the window normally. */
12848 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
12849 {
12850 /* W is a mini-buffer window, but it's not active, so clear
12851 it. */
12852 int yb = window_text_bottom_y (w);
12853 struct glyph_row *row;
12854 int y;
12855
12856 for (y = 0, row = w->desired_matrix->rows;
12857 y < yb;
12858 y += row->height, ++row)
12859 blank_row (w, row, y);
12860 goto finish_scroll_bars;
12861 }
12862
12863 clear_glyph_matrix (w->desired_matrix);
12864 }
12865
12866 /* Otherwise set up data on this window; select its buffer and point
12867 value. */
12868 /* Really select the buffer, for the sake of buffer-local
12869 variables. */
12870 set_buffer_internal_1 (XBUFFER (w->buffer));
12871 SET_TEXT_POS (opoint, PT, PT_BYTE);
12872
12873 beg_unchanged = BEG_UNCHANGED;
12874 end_unchanged = END_UNCHANGED;
12875
12876 current_matrix_up_to_date_p
12877 = (!NILP (w->window_end_valid)
12878 && !current_buffer->clip_changed
12879 && !current_buffer->prevent_redisplay_optimizations_p
12880 && XFASTINT (w->last_modified) >= MODIFF
12881 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12882
12883 buffer_unchanged_p
12884 = (!NILP (w->window_end_valid)
12885 && !current_buffer->clip_changed
12886 && XFASTINT (w->last_modified) >= MODIFF
12887 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12888
12889 /* When windows_or_buffers_changed is non-zero, we can't rely on
12890 the window end being valid, so set it to nil there. */
12891 if (windows_or_buffers_changed)
12892 {
12893 /* If window starts on a continuation line, maybe adjust the
12894 window start in case the window's width changed. */
12895 if (XMARKER (w->start)->buffer == current_buffer)
12896 compute_window_start_on_continuation_line (w);
12897
12898 w->window_end_valid = Qnil;
12899 }
12900
12901 /* Some sanity checks. */
12902 CHECK_WINDOW_END (w);
12903 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
12904 abort ();
12905 if (BYTEPOS (opoint) < CHARPOS (opoint))
12906 abort ();
12907
12908 /* If %c is in mode line, update it if needed. */
12909 if (!NILP (w->column_number_displayed)
12910 /* This alternative quickly identifies a common case
12911 where no change is needed. */
12912 && !(PT == XFASTINT (w->last_point)
12913 && XFASTINT (w->last_modified) >= MODIFF
12914 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
12915 && (XFASTINT (w->column_number_displayed)
12916 != (int) current_column ())) /* iftc */
12917 update_mode_line = 1;
12918
12919 /* Count number of windows showing the selected buffer. An indirect
12920 buffer counts as its base buffer. */
12921 if (!just_this_one_p)
12922 {
12923 struct buffer *current_base, *window_base;
12924 current_base = current_buffer;
12925 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
12926 if (current_base->base_buffer)
12927 current_base = current_base->base_buffer;
12928 if (window_base->base_buffer)
12929 window_base = window_base->base_buffer;
12930 if (current_base == window_base)
12931 buffer_shared++;
12932 }
12933
12934 /* Point refers normally to the selected window. For any other
12935 window, set up appropriate value. */
12936 if (!EQ (window, selected_window))
12937 {
12938 int new_pt = XMARKER (w->pointm)->charpos;
12939 int new_pt_byte = marker_byte_position (w->pointm);
12940 if (new_pt < BEGV)
12941 {
12942 new_pt = BEGV;
12943 new_pt_byte = BEGV_BYTE;
12944 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
12945 }
12946 else if (new_pt > (ZV - 1))
12947 {
12948 new_pt = ZV;
12949 new_pt_byte = ZV_BYTE;
12950 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
12951 }
12952
12953 /* We don't use SET_PT so that the point-motion hooks don't run. */
12954 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
12955 }
12956
12957 /* If any of the character widths specified in the display table
12958 have changed, invalidate the width run cache. It's true that
12959 this may be a bit late to catch such changes, but the rest of
12960 redisplay goes (non-fatally) haywire when the display table is
12961 changed, so why should we worry about doing any better? */
12962 if (current_buffer->width_run_cache)
12963 {
12964 struct Lisp_Char_Table *disptab = buffer_display_table ();
12965
12966 if (! disptab_matches_widthtab (disptab,
12967 XVECTOR (current_buffer->width_table)))
12968 {
12969 invalidate_region_cache (current_buffer,
12970 current_buffer->width_run_cache,
12971 BEG, Z);
12972 recompute_width_table (current_buffer, disptab);
12973 }
12974 }
12975
12976 /* If window-start is screwed up, choose a new one. */
12977 if (XMARKER (w->start)->buffer != current_buffer)
12978 goto recenter;
12979
12980 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12981
12982 /* If someone specified a new starting point but did not insist,
12983 check whether it can be used. */
12984 if (!NILP (w->optional_new_start)
12985 && CHARPOS (startp) >= BEGV
12986 && CHARPOS (startp) <= ZV)
12987 {
12988 w->optional_new_start = Qnil;
12989 start_display (&it, w, startp);
12990 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12991 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12992 if (IT_CHARPOS (it) == PT)
12993 w->force_start = Qt;
12994 /* IT may overshoot PT if text at PT is invisible. */
12995 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
12996 w->force_start = Qt;
12997 }
12998
12999 force_start:
13000
13001 /* Handle case where place to start displaying has been specified,
13002 unless the specified location is outside the accessible range. */
13003 if (!NILP (w->force_start)
13004 || w->frozen_window_start_p)
13005 {
13006 /* We set this later on if we have to adjust point. */
13007 int new_vpos = -1;
13008 int val;
13009
13010 w->force_start = Qnil;
13011 w->vscroll = 0;
13012 w->window_end_valid = Qnil;
13013
13014 /* Forget any recorded base line for line number display. */
13015 if (!buffer_unchanged_p)
13016 w->base_line_number = Qnil;
13017
13018 /* Redisplay the mode line. Select the buffer properly for that.
13019 Also, run the hook window-scroll-functions
13020 because we have scrolled. */
13021 /* Note, we do this after clearing force_start because
13022 if there's an error, it is better to forget about force_start
13023 than to get into an infinite loop calling the hook functions
13024 and having them get more errors. */
13025 if (!update_mode_line
13026 || ! NILP (Vwindow_scroll_functions))
13027 {
13028 update_mode_line = 1;
13029 w->update_mode_line = Qt;
13030 startp = run_window_scroll_functions (window, startp);
13031 }
13032
13033 w->last_modified = make_number (0);
13034 w->last_overlay_modified = make_number (0);
13035 if (CHARPOS (startp) < BEGV)
13036 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
13037 else if (CHARPOS (startp) > ZV)
13038 SET_TEXT_POS (startp, ZV, ZV_BYTE);
13039
13040 /* Redisplay, then check if cursor has been set during the
13041 redisplay. Give up if new fonts were loaded. */
13042 val = try_window (window, startp, 1);
13043 if (!val)
13044 {
13045 w->force_start = Qt;
13046 clear_glyph_matrix (w->desired_matrix);
13047 goto need_larger_matrices;
13048 }
13049 /* Point was outside the scroll margins. */
13050 if (val < 0)
13051 new_vpos = window_box_height (w) / 2;
13052
13053 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
13054 {
13055 /* If point does not appear, try to move point so it does
13056 appear. The desired matrix has been built above, so we
13057 can use it here. */
13058 new_vpos = window_box_height (w) / 2;
13059 }
13060
13061 if (!cursor_row_fully_visible_p (w, 0, 0))
13062 {
13063 /* Point does appear, but on a line partly visible at end of window.
13064 Move it back to a fully-visible line. */
13065 new_vpos = window_box_height (w);
13066 }
13067
13068 /* If we need to move point for either of the above reasons,
13069 now actually do it. */
13070 if (new_vpos >= 0)
13071 {
13072 struct glyph_row *row;
13073
13074 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
13075 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
13076 ++row;
13077
13078 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
13079 MATRIX_ROW_START_BYTEPOS (row));
13080
13081 if (w != XWINDOW (selected_window))
13082 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
13083 else if (current_buffer == old)
13084 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13085
13086 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
13087
13088 /* If we are highlighting the region, then we just changed
13089 the region, so redisplay to show it. */
13090 if (!NILP (Vtransient_mark_mode)
13091 && !NILP (current_buffer->mark_active))
13092 {
13093 clear_glyph_matrix (w->desired_matrix);
13094 if (!try_window (window, startp, 0))
13095 goto need_larger_matrices;
13096 }
13097 }
13098
13099 #if GLYPH_DEBUG
13100 debug_method_add (w, "forced window start");
13101 #endif
13102 goto done;
13103 }
13104
13105 /* Handle case where text has not changed, only point, and it has
13106 not moved off the frame, and we are not retrying after hscroll.
13107 (current_matrix_up_to_date_p is nonzero when retrying.) */
13108 if (current_matrix_up_to_date_p
13109 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
13110 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
13111 {
13112 switch (rc)
13113 {
13114 case CURSOR_MOVEMENT_SUCCESS:
13115 used_current_matrix_p = 1;
13116 goto done;
13117
13118 #if 0 /* try_cursor_movement never returns this value. */
13119 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
13120 goto need_larger_matrices;
13121 #endif
13122
13123 case CURSOR_MOVEMENT_MUST_SCROLL:
13124 goto try_to_scroll;
13125
13126 default:
13127 abort ();
13128 }
13129 }
13130 /* If current starting point was originally the beginning of a line
13131 but no longer is, find a new starting point. */
13132 else if (!NILP (w->start_at_line_beg)
13133 && !(CHARPOS (startp) <= BEGV
13134 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
13135 {
13136 #if GLYPH_DEBUG
13137 debug_method_add (w, "recenter 1");
13138 #endif
13139 goto recenter;
13140 }
13141
13142 /* Try scrolling with try_window_id. Value is > 0 if update has
13143 been done, it is -1 if we know that the same window start will
13144 not work. It is 0 if unsuccessful for some other reason. */
13145 else if ((tem = try_window_id (w)) != 0)
13146 {
13147 #if GLYPH_DEBUG
13148 debug_method_add (w, "try_window_id %d", tem);
13149 #endif
13150
13151 if (fonts_changed_p)
13152 goto need_larger_matrices;
13153 if (tem > 0)
13154 goto done;
13155
13156 /* Otherwise try_window_id has returned -1 which means that we
13157 don't want the alternative below this comment to execute. */
13158 }
13159 else if (CHARPOS (startp) >= BEGV
13160 && CHARPOS (startp) <= ZV
13161 && PT >= CHARPOS (startp)
13162 && (CHARPOS (startp) < ZV
13163 /* Avoid starting at end of buffer. */
13164 || CHARPOS (startp) == BEGV
13165 || (XFASTINT (w->last_modified) >= MODIFF
13166 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
13167 {
13168
13169 /* If first window line is a continuation line, and window start
13170 is inside the modified region, but the first change is before
13171 current window start, we must select a new window start.
13172
13173 However, if this is the result of a down-mouse event (e.g. by
13174 extending the mouse-drag-overlay), we don't want to select a
13175 new window start, since that would change the position under
13176 the mouse, resulting in an unwanted mouse-movement rather
13177 than a simple mouse-click. */
13178 if (NILP (w->start_at_line_beg)
13179 && NILP (do_mouse_tracking)
13180 && CHARPOS (startp) > BEGV
13181 && CHARPOS (startp) > BEG + beg_unchanged
13182 && CHARPOS (startp) <= Z - end_unchanged)
13183 {
13184 w->force_start = Qt;
13185 if (XMARKER (w->start)->buffer == current_buffer)
13186 compute_window_start_on_continuation_line (w);
13187 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13188 goto force_start;
13189 }
13190
13191 #if GLYPH_DEBUG
13192 debug_method_add (w, "same window start");
13193 #endif
13194
13195 /* Try to redisplay starting at same place as before.
13196 If point has not moved off frame, accept the results. */
13197 if (!current_matrix_up_to_date_p
13198 /* Don't use try_window_reusing_current_matrix in this case
13199 because a window scroll function can have changed the
13200 buffer. */
13201 || !NILP (Vwindow_scroll_functions)
13202 || MINI_WINDOW_P (w)
13203 || !(used_current_matrix_p
13204 = try_window_reusing_current_matrix (w)))
13205 {
13206 IF_DEBUG (debug_method_add (w, "1"));
13207 if (try_window (window, startp, 1) < 0)
13208 /* -1 means we need to scroll.
13209 0 means we need new matrices, but fonts_changed_p
13210 is set in that case, so we will detect it below. */
13211 goto try_to_scroll;
13212 }
13213
13214 if (fonts_changed_p)
13215 goto need_larger_matrices;
13216
13217 if (w->cursor.vpos >= 0)
13218 {
13219 if (!just_this_one_p
13220 || current_buffer->clip_changed
13221 || BEG_UNCHANGED < CHARPOS (startp))
13222 /* Forget any recorded base line for line number display. */
13223 w->base_line_number = Qnil;
13224
13225 if (!cursor_row_fully_visible_p (w, 1, 0))
13226 {
13227 clear_glyph_matrix (w->desired_matrix);
13228 last_line_misfit = 1;
13229 }
13230 /* Drop through and scroll. */
13231 else
13232 goto done;
13233 }
13234 else
13235 clear_glyph_matrix (w->desired_matrix);
13236 }
13237
13238 try_to_scroll:
13239
13240 w->last_modified = make_number (0);
13241 w->last_overlay_modified = make_number (0);
13242
13243 /* Redisplay the mode line. Select the buffer properly for that. */
13244 if (!update_mode_line)
13245 {
13246 update_mode_line = 1;
13247 w->update_mode_line = Qt;
13248 }
13249
13250 /* Try to scroll by specified few lines. */
13251 if ((scroll_conservatively
13252 || scroll_step
13253 || temp_scroll_step
13254 || NUMBERP (current_buffer->scroll_up_aggressively)
13255 || NUMBERP (current_buffer->scroll_down_aggressively))
13256 && !current_buffer->clip_changed
13257 && CHARPOS (startp) >= BEGV
13258 && CHARPOS (startp) <= ZV)
13259 {
13260 /* The function returns -1 if new fonts were loaded, 1 if
13261 successful, 0 if not successful. */
13262 int rc = try_scrolling (window, just_this_one_p,
13263 scroll_conservatively,
13264 scroll_step,
13265 temp_scroll_step, last_line_misfit);
13266 switch (rc)
13267 {
13268 case SCROLLING_SUCCESS:
13269 goto done;
13270
13271 case SCROLLING_NEED_LARGER_MATRICES:
13272 goto need_larger_matrices;
13273
13274 case SCROLLING_FAILED:
13275 break;
13276
13277 default:
13278 abort ();
13279 }
13280 }
13281
13282 /* Finally, just choose place to start which centers point */
13283
13284 recenter:
13285 if (centering_position < 0)
13286 centering_position = window_box_height (w) / 2;
13287
13288 #if GLYPH_DEBUG
13289 debug_method_add (w, "recenter");
13290 #endif
13291
13292 /* w->vscroll = 0; */
13293
13294 /* Forget any previously recorded base line for line number display. */
13295 if (!buffer_unchanged_p)
13296 w->base_line_number = Qnil;
13297
13298 /* Move backward half the height of the window. */
13299 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13300 it.current_y = it.last_visible_y;
13301 move_it_vertically_backward (&it, centering_position);
13302 xassert (IT_CHARPOS (it) >= BEGV);
13303
13304 /* The function move_it_vertically_backward may move over more
13305 than the specified y-distance. If it->w is small, e.g. a
13306 mini-buffer window, we may end up in front of the window's
13307 display area. Start displaying at the start of the line
13308 containing PT in this case. */
13309 if (it.current_y <= 0)
13310 {
13311 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13312 move_it_vertically_backward (&it, 0);
13313 #if 0
13314 /* I think this assert is bogus if buffer contains
13315 invisible text or images. KFS. */
13316 xassert (IT_CHARPOS (it) <= PT);
13317 #endif
13318 it.current_y = 0;
13319 }
13320
13321 it.current_x = it.hpos = 0;
13322
13323 /* Set startp here explicitly in case that helps avoid an infinite loop
13324 in case the window-scroll-functions functions get errors. */
13325 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
13326
13327 /* Run scroll hooks. */
13328 startp = run_window_scroll_functions (window, it.current.pos);
13329
13330 /* Redisplay the window. */
13331 if (!current_matrix_up_to_date_p
13332 || windows_or_buffers_changed
13333 || cursor_type_changed
13334 /* Don't use try_window_reusing_current_matrix in this case
13335 because it can have changed the buffer. */
13336 || !NILP (Vwindow_scroll_functions)
13337 || !just_this_one_p
13338 || MINI_WINDOW_P (w)
13339 || !(used_current_matrix_p
13340 = try_window_reusing_current_matrix (w)))
13341 try_window (window, startp, 0);
13342
13343 /* If new fonts have been loaded (due to fontsets), give up. We
13344 have to start a new redisplay since we need to re-adjust glyph
13345 matrices. */
13346 if (fonts_changed_p)
13347 goto need_larger_matrices;
13348
13349 /* If cursor did not appear assume that the middle of the window is
13350 in the first line of the window. Do it again with the next line.
13351 (Imagine a window of height 100, displaying two lines of height
13352 60. Moving back 50 from it->last_visible_y will end in the first
13353 line.) */
13354 if (w->cursor.vpos < 0)
13355 {
13356 if (!NILP (w->window_end_valid)
13357 && PT >= Z - XFASTINT (w->window_end_pos))
13358 {
13359 clear_glyph_matrix (w->desired_matrix);
13360 move_it_by_lines (&it, 1, 0);
13361 try_window (window, it.current.pos, 0);
13362 }
13363 else if (PT < IT_CHARPOS (it))
13364 {
13365 clear_glyph_matrix (w->desired_matrix);
13366 move_it_by_lines (&it, -1, 0);
13367 try_window (window, it.current.pos, 0);
13368 }
13369 else
13370 {
13371 /* Not much we can do about it. */
13372 }
13373 }
13374
13375 /* Consider the following case: Window starts at BEGV, there is
13376 invisible, intangible text at BEGV, so that display starts at
13377 some point START > BEGV. It can happen that we are called with
13378 PT somewhere between BEGV and START. Try to handle that case. */
13379 if (w->cursor.vpos < 0)
13380 {
13381 struct glyph_row *row = w->current_matrix->rows;
13382 if (row->mode_line_p)
13383 ++row;
13384 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13385 }
13386
13387 if (!cursor_row_fully_visible_p (w, 0, 0))
13388 {
13389 /* If vscroll is enabled, disable it and try again. */
13390 if (w->vscroll)
13391 {
13392 w->vscroll = 0;
13393 clear_glyph_matrix (w->desired_matrix);
13394 goto recenter;
13395 }
13396
13397 /* If centering point failed to make the whole line visible,
13398 put point at the top instead. That has to make the whole line
13399 visible, if it can be done. */
13400 if (centering_position == 0)
13401 goto done;
13402
13403 clear_glyph_matrix (w->desired_matrix);
13404 centering_position = 0;
13405 goto recenter;
13406 }
13407
13408 done:
13409
13410 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13411 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
13412 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
13413 ? Qt : Qnil);
13414
13415 /* Display the mode line, if we must. */
13416 if ((update_mode_line
13417 /* If window not full width, must redo its mode line
13418 if (a) the window to its side is being redone and
13419 (b) we do a frame-based redisplay. This is a consequence
13420 of how inverted lines are drawn in frame-based redisplay. */
13421 || (!just_this_one_p
13422 && !FRAME_WINDOW_P (f)
13423 && !WINDOW_FULL_WIDTH_P (w))
13424 /* Line number to display. */
13425 || INTEGERP (w->base_line_pos)
13426 /* Column number is displayed and different from the one displayed. */
13427 || (!NILP (w->column_number_displayed)
13428 && (XFASTINT (w->column_number_displayed)
13429 != (int) current_column ()))) /* iftc */
13430 /* This means that the window has a mode line. */
13431 && (WINDOW_WANTS_MODELINE_P (w)
13432 || WINDOW_WANTS_HEADER_LINE_P (w)))
13433 {
13434 display_mode_lines (w);
13435
13436 /* If mode line height has changed, arrange for a thorough
13437 immediate redisplay using the correct mode line height. */
13438 if (WINDOW_WANTS_MODELINE_P (w)
13439 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
13440 {
13441 fonts_changed_p = 1;
13442 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
13443 = DESIRED_MODE_LINE_HEIGHT (w);
13444 }
13445
13446 /* If top line height has changed, arrange for a thorough
13447 immediate redisplay using the correct mode line height. */
13448 if (WINDOW_WANTS_HEADER_LINE_P (w)
13449 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
13450 {
13451 fonts_changed_p = 1;
13452 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
13453 = DESIRED_HEADER_LINE_HEIGHT (w);
13454 }
13455
13456 if (fonts_changed_p)
13457 goto need_larger_matrices;
13458 }
13459
13460 if (!line_number_displayed
13461 && !BUFFERP (w->base_line_pos))
13462 {
13463 w->base_line_pos = Qnil;
13464 w->base_line_number = Qnil;
13465 }
13466
13467 finish_menu_bars:
13468
13469 /* When we reach a frame's selected window, redo the frame's menu bar. */
13470 if (update_mode_line
13471 && EQ (FRAME_SELECTED_WINDOW (f), window))
13472 {
13473 int redisplay_menu_p = 0;
13474 int redisplay_tool_bar_p = 0;
13475
13476 if (FRAME_WINDOW_P (f))
13477 {
13478 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
13479 || defined (USE_GTK)
13480 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
13481 #else
13482 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13483 #endif
13484 }
13485 else
13486 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13487
13488 if (redisplay_menu_p)
13489 display_menu_bar (w);
13490
13491 #ifdef HAVE_WINDOW_SYSTEM
13492 if (FRAME_WINDOW_P (f))
13493 {
13494 #if defined (USE_GTK) || USE_MAC_TOOLBAR
13495 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
13496 #else
13497 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
13498 && (FRAME_TOOL_BAR_LINES (f) > 0
13499 || !NILP (Vauto_resize_tool_bars));
13500 #endif
13501
13502 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
13503 {
13504 extern int ignore_mouse_drag_p;
13505 ignore_mouse_drag_p = 1;
13506 }
13507 }
13508 #endif
13509 }
13510
13511 #ifdef HAVE_WINDOW_SYSTEM
13512 if (FRAME_WINDOW_P (f)
13513 && update_window_fringes (w, (just_this_one_p
13514 || (!used_current_matrix_p && !overlay_arrow_seen)
13515 || w->pseudo_window_p)))
13516 {
13517 update_begin (f);
13518 BLOCK_INPUT;
13519 if (draw_window_fringes (w, 1))
13520 x_draw_vertical_border (w);
13521 UNBLOCK_INPUT;
13522 update_end (f);
13523 }
13524 #endif /* HAVE_WINDOW_SYSTEM */
13525
13526 /* We go to this label, with fonts_changed_p nonzero,
13527 if it is necessary to try again using larger glyph matrices.
13528 We have to redeem the scroll bar even in this case,
13529 because the loop in redisplay_internal expects that. */
13530 need_larger_matrices:
13531 ;
13532 finish_scroll_bars:
13533
13534 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
13535 {
13536 /* Set the thumb's position and size. */
13537 set_vertical_scroll_bar (w);
13538
13539 /* Note that we actually used the scroll bar attached to this
13540 window, so it shouldn't be deleted at the end of redisplay. */
13541 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
13542 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
13543 }
13544
13545 /* Restore current_buffer and value of point in it. */
13546 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
13547 set_buffer_internal_1 (old);
13548 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
13549 shorter. This can be caused by log truncation in *Messages*. */
13550 if (CHARPOS (lpoint) <= ZV)
13551 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
13552
13553 unbind_to (count, Qnil);
13554 }
13555
13556
13557 /* Build the complete desired matrix of WINDOW with a window start
13558 buffer position POS.
13559
13560 Value is 1 if successful. It is zero if fonts were loaded during
13561 redisplay which makes re-adjusting glyph matrices necessary, and -1
13562 if point would appear in the scroll margins.
13563 (We check that only if CHECK_MARGINS is nonzero. */
13564
13565 int
13566 try_window (window, pos, check_margins)
13567 Lisp_Object window;
13568 struct text_pos pos;
13569 int check_margins;
13570 {
13571 struct window *w = XWINDOW (window);
13572 struct it it;
13573 struct glyph_row *last_text_row = NULL;
13574 struct frame *f = XFRAME (w->frame);
13575
13576 /* Make POS the new window start. */
13577 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
13578
13579 /* Mark cursor position as unknown. No overlay arrow seen. */
13580 w->cursor.vpos = -1;
13581 overlay_arrow_seen = 0;
13582
13583 /* Initialize iterator and info to start at POS. */
13584 start_display (&it, w, pos);
13585
13586 /* Display all lines of W. */
13587 while (it.current_y < it.last_visible_y)
13588 {
13589 if (display_line (&it))
13590 last_text_row = it.glyph_row - 1;
13591 if (fonts_changed_p)
13592 return 0;
13593 }
13594
13595 /* Don't let the cursor end in the scroll margins. */
13596 if (check_margins
13597 && !MINI_WINDOW_P (w))
13598 {
13599 int this_scroll_margin;
13600
13601 this_scroll_margin = max (0, scroll_margin);
13602 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13603 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13604
13605 if ((w->cursor.y >= 0 /* not vscrolled */
13606 && w->cursor.y < this_scroll_margin
13607 && CHARPOS (pos) > BEGV
13608 && IT_CHARPOS (it) < ZV)
13609 /* rms: considering make_cursor_line_fully_visible_p here
13610 seems to give wrong results. We don't want to recenter
13611 when the last line is partly visible, we want to allow
13612 that case to be handled in the usual way. */
13613 || (w->cursor.y + 1) > it.last_visible_y)
13614 {
13615 w->cursor.vpos = -1;
13616 clear_glyph_matrix (w->desired_matrix);
13617 return -1;
13618 }
13619 }
13620
13621 /* If bottom moved off end of frame, change mode line percentage. */
13622 if (XFASTINT (w->window_end_pos) <= 0
13623 && Z != IT_CHARPOS (it))
13624 w->update_mode_line = Qt;
13625
13626 /* Set window_end_pos to the offset of the last character displayed
13627 on the window from the end of current_buffer. Set
13628 window_end_vpos to its row number. */
13629 if (last_text_row)
13630 {
13631 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
13632 w->window_end_bytepos
13633 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13634 w->window_end_pos
13635 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13636 w->window_end_vpos
13637 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13638 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
13639 ->displays_text_p);
13640 }
13641 else
13642 {
13643 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13644 w->window_end_pos = make_number (Z - ZV);
13645 w->window_end_vpos = make_number (0);
13646 }
13647
13648 /* But that is not valid info until redisplay finishes. */
13649 w->window_end_valid = Qnil;
13650 return 1;
13651 }
13652
13653
13654 \f
13655 /************************************************************************
13656 Window redisplay reusing current matrix when buffer has not changed
13657 ************************************************************************/
13658
13659 /* Try redisplay of window W showing an unchanged buffer with a
13660 different window start than the last time it was displayed by
13661 reusing its current matrix. Value is non-zero if successful.
13662 W->start is the new window start. */
13663
13664 static int
13665 try_window_reusing_current_matrix (w)
13666 struct window *w;
13667 {
13668 struct frame *f = XFRAME (w->frame);
13669 struct glyph_row *row, *bottom_row;
13670 struct it it;
13671 struct run run;
13672 struct text_pos start, new_start;
13673 int nrows_scrolled, i;
13674 struct glyph_row *last_text_row;
13675 struct glyph_row *last_reused_text_row;
13676 struct glyph_row *start_row;
13677 int start_vpos, min_y, max_y;
13678
13679 #if GLYPH_DEBUG
13680 if (inhibit_try_window_reusing)
13681 return 0;
13682 #endif
13683
13684 if (/* This function doesn't handle terminal frames. */
13685 !FRAME_WINDOW_P (f)
13686 /* Don't try to reuse the display if windows have been split
13687 or such. */
13688 || windows_or_buffers_changed
13689 || cursor_type_changed)
13690 return 0;
13691
13692 /* Can't do this if region may have changed. */
13693 if ((!NILP (Vtransient_mark_mode)
13694 && !NILP (current_buffer->mark_active))
13695 || !NILP (w->region_showing)
13696 || !NILP (Vshow_trailing_whitespace))
13697 return 0;
13698
13699 /* If top-line visibility has changed, give up. */
13700 if (WINDOW_WANTS_HEADER_LINE_P (w)
13701 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
13702 return 0;
13703
13704 /* Give up if old or new display is scrolled vertically. We could
13705 make this function handle this, but right now it doesn't. */
13706 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13707 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
13708 return 0;
13709
13710 /* The variable new_start now holds the new window start. The old
13711 start `start' can be determined from the current matrix. */
13712 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
13713 start = start_row->start.pos;
13714 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13715
13716 /* Clear the desired matrix for the display below. */
13717 clear_glyph_matrix (w->desired_matrix);
13718
13719 if (CHARPOS (new_start) <= CHARPOS (start))
13720 {
13721 int first_row_y;
13722
13723 /* Don't use this method if the display starts with an ellipsis
13724 displayed for invisible text. It's not easy to handle that case
13725 below, and it's certainly not worth the effort since this is
13726 not a frequent case. */
13727 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
13728 return 0;
13729
13730 IF_DEBUG (debug_method_add (w, "twu1"));
13731
13732 /* Display up to a row that can be reused. The variable
13733 last_text_row is set to the last row displayed that displays
13734 text. Note that it.vpos == 0 if or if not there is a
13735 header-line; it's not the same as the MATRIX_ROW_VPOS! */
13736 start_display (&it, w, new_start);
13737 first_row_y = it.current_y;
13738 w->cursor.vpos = -1;
13739 last_text_row = last_reused_text_row = NULL;
13740
13741 while (it.current_y < it.last_visible_y
13742 && !fonts_changed_p)
13743 {
13744 /* If we have reached into the characters in the START row,
13745 that means the line boundaries have changed. So we
13746 can't start copying with the row START. Maybe it will
13747 work to start copying with the following row. */
13748 while (IT_CHARPOS (it) > CHARPOS (start))
13749 {
13750 /* Advance to the next row as the "start". */
13751 start_row++;
13752 start = start_row->start.pos;
13753 /* If there are no more rows to try, or just one, give up. */
13754 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
13755 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
13756 || CHARPOS (start) == ZV)
13757 {
13758 clear_glyph_matrix (w->desired_matrix);
13759 return 0;
13760 }
13761
13762 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13763 }
13764 /* If we have reached alignment,
13765 we can copy the rest of the rows. */
13766 if (IT_CHARPOS (it) == CHARPOS (start))
13767 break;
13768
13769 if (display_line (&it))
13770 last_text_row = it.glyph_row - 1;
13771 }
13772
13773 /* A value of current_y < last_visible_y means that we stopped
13774 at the previous window start, which in turn means that we
13775 have at least one reusable row. */
13776 if (it.current_y < it.last_visible_y)
13777 {
13778 /* IT.vpos always starts from 0; it counts text lines. */
13779 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
13780
13781 /* Find PT if not already found in the lines displayed. */
13782 if (w->cursor.vpos < 0)
13783 {
13784 int dy = it.current_y - start_row->y;
13785
13786 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13787 row = row_containing_pos (w, PT, row, NULL, dy);
13788 if (row)
13789 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
13790 dy, nrows_scrolled);
13791 else
13792 {
13793 clear_glyph_matrix (w->desired_matrix);
13794 return 0;
13795 }
13796 }
13797
13798 /* Scroll the display. Do it before the current matrix is
13799 changed. The problem here is that update has not yet
13800 run, i.e. part of the current matrix is not up to date.
13801 scroll_run_hook will clear the cursor, and use the
13802 current matrix to get the height of the row the cursor is
13803 in. */
13804 run.current_y = start_row->y;
13805 run.desired_y = it.current_y;
13806 run.height = it.last_visible_y - it.current_y;
13807
13808 if (run.height > 0 && run.current_y != run.desired_y)
13809 {
13810 update_begin (f);
13811 FRAME_RIF (f)->update_window_begin_hook (w);
13812 FRAME_RIF (f)->clear_window_mouse_face (w);
13813 FRAME_RIF (f)->scroll_run_hook (w, &run);
13814 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
13815 update_end (f);
13816 }
13817
13818 /* Shift current matrix down by nrows_scrolled lines. */
13819 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13820 rotate_matrix (w->current_matrix,
13821 start_vpos,
13822 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13823 nrows_scrolled);
13824
13825 /* Disable lines that must be updated. */
13826 for (i = 0; i < nrows_scrolled; ++i)
13827 (start_row + i)->enabled_p = 0;
13828
13829 /* Re-compute Y positions. */
13830 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13831 max_y = it.last_visible_y;
13832 for (row = start_row + nrows_scrolled;
13833 row < bottom_row;
13834 ++row)
13835 {
13836 row->y = it.current_y;
13837 row->visible_height = row->height;
13838
13839 if (row->y < min_y)
13840 row->visible_height -= min_y - row->y;
13841 if (row->y + row->height > max_y)
13842 row->visible_height -= row->y + row->height - max_y;
13843 row->redraw_fringe_bitmaps_p = 1;
13844
13845 it.current_y += row->height;
13846
13847 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13848 last_reused_text_row = row;
13849 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
13850 break;
13851 }
13852
13853 /* Disable lines in the current matrix which are now
13854 below the window. */
13855 for (++row; row < bottom_row; ++row)
13856 row->enabled_p = row->mode_line_p = 0;
13857 }
13858
13859 /* Update window_end_pos etc.; last_reused_text_row is the last
13860 reused row from the current matrix containing text, if any.
13861 The value of last_text_row is the last displayed line
13862 containing text. */
13863 if (last_reused_text_row)
13864 {
13865 w->window_end_bytepos
13866 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
13867 w->window_end_pos
13868 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
13869 w->window_end_vpos
13870 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
13871 w->current_matrix));
13872 }
13873 else if (last_text_row)
13874 {
13875 w->window_end_bytepos
13876 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13877 w->window_end_pos
13878 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13879 w->window_end_vpos
13880 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13881 }
13882 else
13883 {
13884 /* This window must be completely empty. */
13885 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13886 w->window_end_pos = make_number (Z - ZV);
13887 w->window_end_vpos = make_number (0);
13888 }
13889 w->window_end_valid = Qnil;
13890
13891 /* Update hint: don't try scrolling again in update_window. */
13892 w->desired_matrix->no_scrolling_p = 1;
13893
13894 #if GLYPH_DEBUG
13895 debug_method_add (w, "try_window_reusing_current_matrix 1");
13896 #endif
13897 return 1;
13898 }
13899 else if (CHARPOS (new_start) > CHARPOS (start))
13900 {
13901 struct glyph_row *pt_row, *row;
13902 struct glyph_row *first_reusable_row;
13903 struct glyph_row *first_row_to_display;
13904 int dy;
13905 int yb = window_text_bottom_y (w);
13906
13907 /* Find the row starting at new_start, if there is one. Don't
13908 reuse a partially visible line at the end. */
13909 first_reusable_row = start_row;
13910 while (first_reusable_row->enabled_p
13911 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
13912 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13913 < CHARPOS (new_start)))
13914 ++first_reusable_row;
13915
13916 /* Give up if there is no row to reuse. */
13917 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
13918 || !first_reusable_row->enabled_p
13919 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13920 != CHARPOS (new_start)))
13921 return 0;
13922
13923 /* We can reuse fully visible rows beginning with
13924 first_reusable_row to the end of the window. Set
13925 first_row_to_display to the first row that cannot be reused.
13926 Set pt_row to the row containing point, if there is any. */
13927 pt_row = NULL;
13928 for (first_row_to_display = first_reusable_row;
13929 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
13930 ++first_row_to_display)
13931 {
13932 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
13933 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
13934 pt_row = first_row_to_display;
13935 }
13936
13937 /* Start displaying at the start of first_row_to_display. */
13938 xassert (first_row_to_display->y < yb);
13939 init_to_row_start (&it, w, first_row_to_display);
13940
13941 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
13942 - start_vpos);
13943 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
13944 - nrows_scrolled);
13945 it.current_y = (first_row_to_display->y - first_reusable_row->y
13946 + WINDOW_HEADER_LINE_HEIGHT (w));
13947
13948 /* Display lines beginning with first_row_to_display in the
13949 desired matrix. Set last_text_row to the last row displayed
13950 that displays text. */
13951 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
13952 if (pt_row == NULL)
13953 w->cursor.vpos = -1;
13954 last_text_row = NULL;
13955 while (it.current_y < it.last_visible_y && !fonts_changed_p)
13956 if (display_line (&it))
13957 last_text_row = it.glyph_row - 1;
13958
13959 /* Give up If point isn't in a row displayed or reused. */
13960 if (w->cursor.vpos < 0)
13961 {
13962 clear_glyph_matrix (w->desired_matrix);
13963 return 0;
13964 }
13965
13966 /* If point is in a reused row, adjust y and vpos of the cursor
13967 position. */
13968 if (pt_row)
13969 {
13970 w->cursor.vpos -= nrows_scrolled;
13971 w->cursor.y -= first_reusable_row->y - start_row->y;
13972 }
13973
13974 /* Scroll the display. */
13975 run.current_y = first_reusable_row->y;
13976 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
13977 run.height = it.last_visible_y - run.current_y;
13978 dy = run.current_y - run.desired_y;
13979
13980 if (run.height)
13981 {
13982 update_begin (f);
13983 FRAME_RIF (f)->update_window_begin_hook (w);
13984 FRAME_RIF (f)->clear_window_mouse_face (w);
13985 FRAME_RIF (f)->scroll_run_hook (w, &run);
13986 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
13987 update_end (f);
13988 }
13989
13990 /* Adjust Y positions of reused rows. */
13991 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13992 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13993 max_y = it.last_visible_y;
13994 for (row = first_reusable_row; row < first_row_to_display; ++row)
13995 {
13996 row->y -= dy;
13997 row->visible_height = row->height;
13998 if (row->y < min_y)
13999 row->visible_height -= min_y - row->y;
14000 if (row->y + row->height > max_y)
14001 row->visible_height -= row->y + row->height - max_y;
14002 row->redraw_fringe_bitmaps_p = 1;
14003 }
14004
14005 /* Scroll the current matrix. */
14006 xassert (nrows_scrolled > 0);
14007 rotate_matrix (w->current_matrix,
14008 start_vpos,
14009 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14010 -nrows_scrolled);
14011
14012 /* Disable rows not reused. */
14013 for (row -= nrows_scrolled; row < bottom_row; ++row)
14014 row->enabled_p = 0;
14015
14016 /* Point may have moved to a different line, so we cannot assume that
14017 the previous cursor position is valid; locate the correct row. */
14018 if (pt_row)
14019 {
14020 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
14021 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
14022 row++)
14023 {
14024 w->cursor.vpos++;
14025 w->cursor.y = row->y;
14026 }
14027 if (row < bottom_row)
14028 {
14029 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
14030 while (glyph->charpos < PT)
14031 {
14032 w->cursor.hpos++;
14033 w->cursor.x += glyph->pixel_width;
14034 glyph++;
14035 }
14036 }
14037 }
14038
14039 /* Adjust window end. A null value of last_text_row means that
14040 the window end is in reused rows which in turn means that
14041 only its vpos can have changed. */
14042 if (last_text_row)
14043 {
14044 w->window_end_bytepos
14045 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14046 w->window_end_pos
14047 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14048 w->window_end_vpos
14049 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14050 }
14051 else
14052 {
14053 w->window_end_vpos
14054 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
14055 }
14056
14057 w->window_end_valid = Qnil;
14058 w->desired_matrix->no_scrolling_p = 1;
14059
14060 #if GLYPH_DEBUG
14061 debug_method_add (w, "try_window_reusing_current_matrix 2");
14062 #endif
14063 return 1;
14064 }
14065
14066 return 0;
14067 }
14068
14069
14070 \f
14071 /************************************************************************
14072 Window redisplay reusing current matrix when buffer has changed
14073 ************************************************************************/
14074
14075 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
14076 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
14077 int *, int *));
14078 static struct glyph_row *
14079 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
14080 struct glyph_row *));
14081
14082
14083 /* Return the last row in MATRIX displaying text. If row START is
14084 non-null, start searching with that row. IT gives the dimensions
14085 of the display. Value is null if matrix is empty; otherwise it is
14086 a pointer to the row found. */
14087
14088 static struct glyph_row *
14089 find_last_row_displaying_text (matrix, it, start)
14090 struct glyph_matrix *matrix;
14091 struct it *it;
14092 struct glyph_row *start;
14093 {
14094 struct glyph_row *row, *row_found;
14095
14096 /* Set row_found to the last row in IT->w's current matrix
14097 displaying text. The loop looks funny but think of partially
14098 visible lines. */
14099 row_found = NULL;
14100 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
14101 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14102 {
14103 xassert (row->enabled_p);
14104 row_found = row;
14105 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
14106 break;
14107 ++row;
14108 }
14109
14110 return row_found;
14111 }
14112
14113
14114 /* Return the last row in the current matrix of W that is not affected
14115 by changes at the start of current_buffer that occurred since W's
14116 current matrix was built. Value is null if no such row exists.
14117
14118 BEG_UNCHANGED us the number of characters unchanged at the start of
14119 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
14120 first changed character in current_buffer. Characters at positions <
14121 BEG + BEG_UNCHANGED are at the same buffer positions as they were
14122 when the current matrix was built. */
14123
14124 static struct glyph_row *
14125 find_last_unchanged_at_beg_row (w)
14126 struct window *w;
14127 {
14128 int first_changed_pos = BEG + BEG_UNCHANGED;
14129 struct glyph_row *row;
14130 struct glyph_row *row_found = NULL;
14131 int yb = window_text_bottom_y (w);
14132
14133 /* Find the last row displaying unchanged text. */
14134 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14135 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14136 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
14137 {
14138 if (/* If row ends before first_changed_pos, it is unchanged,
14139 except in some case. */
14140 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
14141 /* When row ends in ZV and we write at ZV it is not
14142 unchanged. */
14143 && !row->ends_at_zv_p
14144 /* When first_changed_pos is the end of a continued line,
14145 row is not unchanged because it may be no longer
14146 continued. */
14147 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
14148 && (row->continued_p
14149 || row->exact_window_width_line_p)))
14150 row_found = row;
14151
14152 /* Stop if last visible row. */
14153 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
14154 break;
14155
14156 ++row;
14157 }
14158
14159 return row_found;
14160 }
14161
14162
14163 /* Find the first glyph row in the current matrix of W that is not
14164 affected by changes at the end of current_buffer since the
14165 time W's current matrix was built.
14166
14167 Return in *DELTA the number of chars by which buffer positions in
14168 unchanged text at the end of current_buffer must be adjusted.
14169
14170 Return in *DELTA_BYTES the corresponding number of bytes.
14171
14172 Value is null if no such row exists, i.e. all rows are affected by
14173 changes. */
14174
14175 static struct glyph_row *
14176 find_first_unchanged_at_end_row (w, delta, delta_bytes)
14177 struct window *w;
14178 int *delta, *delta_bytes;
14179 {
14180 struct glyph_row *row;
14181 struct glyph_row *row_found = NULL;
14182
14183 *delta = *delta_bytes = 0;
14184
14185 /* Display must not have been paused, otherwise the current matrix
14186 is not up to date. */
14187 if (NILP (w->window_end_valid))
14188 abort ();
14189
14190 /* A value of window_end_pos >= END_UNCHANGED means that the window
14191 end is in the range of changed text. If so, there is no
14192 unchanged row at the end of W's current matrix. */
14193 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
14194 return NULL;
14195
14196 /* Set row to the last row in W's current matrix displaying text. */
14197 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14198
14199 /* If matrix is entirely empty, no unchanged row exists. */
14200 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14201 {
14202 /* The value of row is the last glyph row in the matrix having a
14203 meaningful buffer position in it. The end position of row
14204 corresponds to window_end_pos. This allows us to translate
14205 buffer positions in the current matrix to current buffer
14206 positions for characters not in changed text. */
14207 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14208 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14209 int last_unchanged_pos, last_unchanged_pos_old;
14210 struct glyph_row *first_text_row
14211 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14212
14213 *delta = Z - Z_old;
14214 *delta_bytes = Z_BYTE - Z_BYTE_old;
14215
14216 /* Set last_unchanged_pos to the buffer position of the last
14217 character in the buffer that has not been changed. Z is the
14218 index + 1 of the last character in current_buffer, i.e. by
14219 subtracting END_UNCHANGED we get the index of the last
14220 unchanged character, and we have to add BEG to get its buffer
14221 position. */
14222 last_unchanged_pos = Z - END_UNCHANGED + BEG;
14223 last_unchanged_pos_old = last_unchanged_pos - *delta;
14224
14225 /* Search backward from ROW for a row displaying a line that
14226 starts at a minimum position >= last_unchanged_pos_old. */
14227 for (; row > first_text_row; --row)
14228 {
14229 /* This used to abort, but it can happen.
14230 It is ok to just stop the search instead here. KFS. */
14231 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
14232 break;
14233
14234 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
14235 row_found = row;
14236 }
14237 }
14238
14239 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
14240 abort ();
14241
14242 return row_found;
14243 }
14244
14245
14246 /* Make sure that glyph rows in the current matrix of window W
14247 reference the same glyph memory as corresponding rows in the
14248 frame's frame matrix. This function is called after scrolling W's
14249 current matrix on a terminal frame in try_window_id and
14250 try_window_reusing_current_matrix. */
14251
14252 static void
14253 sync_frame_with_window_matrix_rows (w)
14254 struct window *w;
14255 {
14256 struct frame *f = XFRAME (w->frame);
14257 struct glyph_row *window_row, *window_row_end, *frame_row;
14258
14259 /* Preconditions: W must be a leaf window and full-width. Its frame
14260 must have a frame matrix. */
14261 xassert (NILP (w->hchild) && NILP (w->vchild));
14262 xassert (WINDOW_FULL_WIDTH_P (w));
14263 xassert (!FRAME_WINDOW_P (f));
14264
14265 /* If W is a full-width window, glyph pointers in W's current matrix
14266 have, by definition, to be the same as glyph pointers in the
14267 corresponding frame matrix. Note that frame matrices have no
14268 marginal areas (see build_frame_matrix). */
14269 window_row = w->current_matrix->rows;
14270 window_row_end = window_row + w->current_matrix->nrows;
14271 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
14272 while (window_row < window_row_end)
14273 {
14274 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
14275 struct glyph *end = window_row->glyphs[LAST_AREA];
14276
14277 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
14278 frame_row->glyphs[TEXT_AREA] = start;
14279 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
14280 frame_row->glyphs[LAST_AREA] = end;
14281
14282 /* Disable frame rows whose corresponding window rows have
14283 been disabled in try_window_id. */
14284 if (!window_row->enabled_p)
14285 frame_row->enabled_p = 0;
14286
14287 ++window_row, ++frame_row;
14288 }
14289 }
14290
14291
14292 /* Find the glyph row in window W containing CHARPOS. Consider all
14293 rows between START and END (not inclusive). END null means search
14294 all rows to the end of the display area of W. Value is the row
14295 containing CHARPOS or null. */
14296
14297 struct glyph_row *
14298 row_containing_pos (w, charpos, start, end, dy)
14299 struct window *w;
14300 int charpos;
14301 struct glyph_row *start, *end;
14302 int dy;
14303 {
14304 struct glyph_row *row = start;
14305 int last_y;
14306
14307 /* If we happen to start on a header-line, skip that. */
14308 if (row->mode_line_p)
14309 ++row;
14310
14311 if ((end && row >= end) || !row->enabled_p)
14312 return NULL;
14313
14314 last_y = window_text_bottom_y (w) - dy;
14315
14316 while (1)
14317 {
14318 /* Give up if we have gone too far. */
14319 if (end && row >= end)
14320 return NULL;
14321 /* This formerly returned if they were equal.
14322 I think that both quantities are of a "last plus one" type;
14323 if so, when they are equal, the row is within the screen. -- rms. */
14324 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
14325 return NULL;
14326
14327 /* If it is in this row, return this row. */
14328 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
14329 || (MATRIX_ROW_END_CHARPOS (row) == charpos
14330 /* The end position of a row equals the start
14331 position of the next row. If CHARPOS is there, we
14332 would rather display it in the next line, except
14333 when this line ends in ZV. */
14334 && !row->ends_at_zv_p
14335 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14336 && charpos >= MATRIX_ROW_START_CHARPOS (row))
14337 return row;
14338 ++row;
14339 }
14340 }
14341
14342
14343 /* Try to redisplay window W by reusing its existing display. W's
14344 current matrix must be up to date when this function is called,
14345 i.e. window_end_valid must not be nil.
14346
14347 Value is
14348
14349 1 if display has been updated
14350 0 if otherwise unsuccessful
14351 -1 if redisplay with same window start is known not to succeed
14352
14353 The following steps are performed:
14354
14355 1. Find the last row in the current matrix of W that is not
14356 affected by changes at the start of current_buffer. If no such row
14357 is found, give up.
14358
14359 2. Find the first row in W's current matrix that is not affected by
14360 changes at the end of current_buffer. Maybe there is no such row.
14361
14362 3. Display lines beginning with the row + 1 found in step 1 to the
14363 row found in step 2 or, if step 2 didn't find a row, to the end of
14364 the window.
14365
14366 4. If cursor is not known to appear on the window, give up.
14367
14368 5. If display stopped at the row found in step 2, scroll the
14369 display and current matrix as needed.
14370
14371 6. Maybe display some lines at the end of W, if we must. This can
14372 happen under various circumstances, like a partially visible line
14373 becoming fully visible, or because newly displayed lines are displayed
14374 in smaller font sizes.
14375
14376 7. Update W's window end information. */
14377
14378 static int
14379 try_window_id (w)
14380 struct window *w;
14381 {
14382 struct frame *f = XFRAME (w->frame);
14383 struct glyph_matrix *current_matrix = w->current_matrix;
14384 struct glyph_matrix *desired_matrix = w->desired_matrix;
14385 struct glyph_row *last_unchanged_at_beg_row;
14386 struct glyph_row *first_unchanged_at_end_row;
14387 struct glyph_row *row;
14388 struct glyph_row *bottom_row;
14389 int bottom_vpos;
14390 struct it it;
14391 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
14392 struct text_pos start_pos;
14393 struct run run;
14394 int first_unchanged_at_end_vpos = 0;
14395 struct glyph_row *last_text_row, *last_text_row_at_end;
14396 struct text_pos start;
14397 int first_changed_charpos, last_changed_charpos;
14398
14399 #if GLYPH_DEBUG
14400 if (inhibit_try_window_id)
14401 return 0;
14402 #endif
14403
14404 /* This is handy for debugging. */
14405 #if 0
14406 #define GIVE_UP(X) \
14407 do { \
14408 fprintf (stderr, "try_window_id give up %d\n", (X)); \
14409 return 0; \
14410 } while (0)
14411 #else
14412 #define GIVE_UP(X) return 0
14413 #endif
14414
14415 SET_TEXT_POS_FROM_MARKER (start, w->start);
14416
14417 /* Don't use this for mini-windows because these can show
14418 messages and mini-buffers, and we don't handle that here. */
14419 if (MINI_WINDOW_P (w))
14420 GIVE_UP (1);
14421
14422 /* This flag is used to prevent redisplay optimizations. */
14423 if (windows_or_buffers_changed || cursor_type_changed)
14424 GIVE_UP (2);
14425
14426 /* Verify that narrowing has not changed.
14427 Also verify that we were not told to prevent redisplay optimizations.
14428 It would be nice to further
14429 reduce the number of cases where this prevents try_window_id. */
14430 if (current_buffer->clip_changed
14431 || current_buffer->prevent_redisplay_optimizations_p)
14432 GIVE_UP (3);
14433
14434 /* Window must either use window-based redisplay or be full width. */
14435 if (!FRAME_WINDOW_P (f)
14436 && (!FRAME_LINE_INS_DEL_OK (f)
14437 || !WINDOW_FULL_WIDTH_P (w)))
14438 GIVE_UP (4);
14439
14440 /* Give up if point is not known NOT to appear in W. */
14441 if (PT < CHARPOS (start))
14442 GIVE_UP (5);
14443
14444 /* Another way to prevent redisplay optimizations. */
14445 if (XFASTINT (w->last_modified) == 0)
14446 GIVE_UP (6);
14447
14448 /* Verify that window is not hscrolled. */
14449 if (XFASTINT (w->hscroll) != 0)
14450 GIVE_UP (7);
14451
14452 /* Verify that display wasn't paused. */
14453 if (NILP (w->window_end_valid))
14454 GIVE_UP (8);
14455
14456 /* Can't use this if highlighting a region because a cursor movement
14457 will do more than just set the cursor. */
14458 if (!NILP (Vtransient_mark_mode)
14459 && !NILP (current_buffer->mark_active))
14460 GIVE_UP (9);
14461
14462 /* Likewise if highlighting trailing whitespace. */
14463 if (!NILP (Vshow_trailing_whitespace))
14464 GIVE_UP (11);
14465
14466 /* Likewise if showing a region. */
14467 if (!NILP (w->region_showing))
14468 GIVE_UP (10);
14469
14470 /* Can use this if overlay arrow position and or string have changed. */
14471 if (overlay_arrows_changed_p ())
14472 GIVE_UP (12);
14473
14474
14475 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
14476 only if buffer has really changed. The reason is that the gap is
14477 initially at Z for freshly visited files. The code below would
14478 set end_unchanged to 0 in that case. */
14479 if (MODIFF > SAVE_MODIFF
14480 /* This seems to happen sometimes after saving a buffer. */
14481 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
14482 {
14483 if (GPT - BEG < BEG_UNCHANGED)
14484 BEG_UNCHANGED = GPT - BEG;
14485 if (Z - GPT < END_UNCHANGED)
14486 END_UNCHANGED = Z - GPT;
14487 }
14488
14489 /* The position of the first and last character that has been changed. */
14490 first_changed_charpos = BEG + BEG_UNCHANGED;
14491 last_changed_charpos = Z - END_UNCHANGED;
14492
14493 /* If window starts after a line end, and the last change is in
14494 front of that newline, then changes don't affect the display.
14495 This case happens with stealth-fontification. Note that although
14496 the display is unchanged, glyph positions in the matrix have to
14497 be adjusted, of course. */
14498 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14499 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14500 && ((last_changed_charpos < CHARPOS (start)
14501 && CHARPOS (start) == BEGV)
14502 || (last_changed_charpos < CHARPOS (start) - 1
14503 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
14504 {
14505 int Z_old, delta, Z_BYTE_old, delta_bytes;
14506 struct glyph_row *r0;
14507
14508 /* Compute how many chars/bytes have been added to or removed
14509 from the buffer. */
14510 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14511 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14512 delta = Z - Z_old;
14513 delta_bytes = Z_BYTE - Z_BYTE_old;
14514
14515 /* Give up if PT is not in the window. Note that it already has
14516 been checked at the start of try_window_id that PT is not in
14517 front of the window start. */
14518 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
14519 GIVE_UP (13);
14520
14521 /* If window start is unchanged, we can reuse the whole matrix
14522 as is, after adjusting glyph positions. No need to compute
14523 the window end again, since its offset from Z hasn't changed. */
14524 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14525 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
14526 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
14527 /* PT must not be in a partially visible line. */
14528 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
14529 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14530 {
14531 /* Adjust positions in the glyph matrix. */
14532 if (delta || delta_bytes)
14533 {
14534 struct glyph_row *r1
14535 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14536 increment_matrix_positions (w->current_matrix,
14537 MATRIX_ROW_VPOS (r0, current_matrix),
14538 MATRIX_ROW_VPOS (r1, current_matrix),
14539 delta, delta_bytes);
14540 }
14541
14542 /* Set the cursor. */
14543 row = row_containing_pos (w, PT, r0, NULL, 0);
14544 if (row)
14545 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14546 else
14547 abort ();
14548 return 1;
14549 }
14550 }
14551
14552 /* Handle the case that changes are all below what is displayed in
14553 the window, and that PT is in the window. This shortcut cannot
14554 be taken if ZV is visible in the window, and text has been added
14555 there that is visible in the window. */
14556 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
14557 /* ZV is not visible in the window, or there are no
14558 changes at ZV, actually. */
14559 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
14560 || first_changed_charpos == last_changed_charpos))
14561 {
14562 struct glyph_row *r0;
14563
14564 /* Give up if PT is not in the window. Note that it already has
14565 been checked at the start of try_window_id that PT is not in
14566 front of the window start. */
14567 if (PT >= MATRIX_ROW_END_CHARPOS (row))
14568 GIVE_UP (14);
14569
14570 /* If window start is unchanged, we can reuse the whole matrix
14571 as is, without changing glyph positions since no text has
14572 been added/removed in front of the window end. */
14573 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14574 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
14575 /* PT must not be in a partially visible line. */
14576 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
14577 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14578 {
14579 /* We have to compute the window end anew since text
14580 can have been added/removed after it. */
14581 w->window_end_pos
14582 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14583 w->window_end_bytepos
14584 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14585
14586 /* Set the cursor. */
14587 row = row_containing_pos (w, PT, r0, NULL, 0);
14588 if (row)
14589 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14590 else
14591 abort ();
14592 return 2;
14593 }
14594 }
14595
14596 /* Give up if window start is in the changed area.
14597
14598 The condition used to read
14599
14600 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
14601
14602 but why that was tested escapes me at the moment. */
14603 if (CHARPOS (start) >= first_changed_charpos
14604 && CHARPOS (start) <= last_changed_charpos)
14605 GIVE_UP (15);
14606
14607 /* Check that window start agrees with the start of the first glyph
14608 row in its current matrix. Check this after we know the window
14609 start is not in changed text, otherwise positions would not be
14610 comparable. */
14611 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
14612 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
14613 GIVE_UP (16);
14614
14615 /* Give up if the window ends in strings. Overlay strings
14616 at the end are difficult to handle, so don't try. */
14617 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
14618 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
14619 GIVE_UP (20);
14620
14621 /* Compute the position at which we have to start displaying new
14622 lines. Some of the lines at the top of the window might be
14623 reusable because they are not displaying changed text. Find the
14624 last row in W's current matrix not affected by changes at the
14625 start of current_buffer. Value is null if changes start in the
14626 first line of window. */
14627 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
14628 if (last_unchanged_at_beg_row)
14629 {
14630 /* Avoid starting to display in the moddle of a character, a TAB
14631 for instance. This is easier than to set up the iterator
14632 exactly, and it's not a frequent case, so the additional
14633 effort wouldn't really pay off. */
14634 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
14635 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
14636 && last_unchanged_at_beg_row > w->current_matrix->rows)
14637 --last_unchanged_at_beg_row;
14638
14639 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
14640 GIVE_UP (17);
14641
14642 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
14643 GIVE_UP (18);
14644 start_pos = it.current.pos;
14645
14646 /* Start displaying new lines in the desired matrix at the same
14647 vpos we would use in the current matrix, i.e. below
14648 last_unchanged_at_beg_row. */
14649 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
14650 current_matrix);
14651 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14652 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
14653
14654 xassert (it.hpos == 0 && it.current_x == 0);
14655 }
14656 else
14657 {
14658 /* There are no reusable lines at the start of the window.
14659 Start displaying in the first text line. */
14660 start_display (&it, w, start);
14661 it.vpos = it.first_vpos;
14662 start_pos = it.current.pos;
14663 }
14664
14665 /* Find the first row that is not affected by changes at the end of
14666 the buffer. Value will be null if there is no unchanged row, in
14667 which case we must redisplay to the end of the window. delta
14668 will be set to the value by which buffer positions beginning with
14669 first_unchanged_at_end_row have to be adjusted due to text
14670 changes. */
14671 first_unchanged_at_end_row
14672 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
14673 IF_DEBUG (debug_delta = delta);
14674 IF_DEBUG (debug_delta_bytes = delta_bytes);
14675
14676 /* Set stop_pos to the buffer position up to which we will have to
14677 display new lines. If first_unchanged_at_end_row != NULL, this
14678 is the buffer position of the start of the line displayed in that
14679 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
14680 that we don't stop at a buffer position. */
14681 stop_pos = 0;
14682 if (first_unchanged_at_end_row)
14683 {
14684 xassert (last_unchanged_at_beg_row == NULL
14685 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
14686
14687 /* If this is a continuation line, move forward to the next one
14688 that isn't. Changes in lines above affect this line.
14689 Caution: this may move first_unchanged_at_end_row to a row
14690 not displaying text. */
14691 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
14692 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14693 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14694 < it.last_visible_y))
14695 ++first_unchanged_at_end_row;
14696
14697 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14698 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14699 >= it.last_visible_y))
14700 first_unchanged_at_end_row = NULL;
14701 else
14702 {
14703 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
14704 + delta);
14705 first_unchanged_at_end_vpos
14706 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
14707 xassert (stop_pos >= Z - END_UNCHANGED);
14708 }
14709 }
14710 else if (last_unchanged_at_beg_row == NULL)
14711 GIVE_UP (19);
14712
14713
14714 #if GLYPH_DEBUG
14715
14716 /* Either there is no unchanged row at the end, or the one we have
14717 now displays text. This is a necessary condition for the window
14718 end pos calculation at the end of this function. */
14719 xassert (first_unchanged_at_end_row == NULL
14720 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
14721
14722 debug_last_unchanged_at_beg_vpos
14723 = (last_unchanged_at_beg_row
14724 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
14725 : -1);
14726 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
14727
14728 #endif /* GLYPH_DEBUG != 0 */
14729
14730
14731 /* Display new lines. Set last_text_row to the last new line
14732 displayed which has text on it, i.e. might end up as being the
14733 line where the window_end_vpos is. */
14734 w->cursor.vpos = -1;
14735 last_text_row = NULL;
14736 overlay_arrow_seen = 0;
14737 while (it.current_y < it.last_visible_y
14738 && !fonts_changed_p
14739 && (first_unchanged_at_end_row == NULL
14740 || IT_CHARPOS (it) < stop_pos))
14741 {
14742 if (display_line (&it))
14743 last_text_row = it.glyph_row - 1;
14744 }
14745
14746 if (fonts_changed_p)
14747 return -1;
14748
14749
14750 /* Compute differences in buffer positions, y-positions etc. for
14751 lines reused at the bottom of the window. Compute what we can
14752 scroll. */
14753 if (first_unchanged_at_end_row
14754 /* No lines reused because we displayed everything up to the
14755 bottom of the window. */
14756 && it.current_y < it.last_visible_y)
14757 {
14758 dvpos = (it.vpos
14759 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
14760 current_matrix));
14761 dy = it.current_y - first_unchanged_at_end_row->y;
14762 run.current_y = first_unchanged_at_end_row->y;
14763 run.desired_y = run.current_y + dy;
14764 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
14765 }
14766 else
14767 {
14768 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
14769 first_unchanged_at_end_row = NULL;
14770 }
14771 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
14772
14773
14774 /* Find the cursor if not already found. We have to decide whether
14775 PT will appear on this window (it sometimes doesn't, but this is
14776 not a very frequent case.) This decision has to be made before
14777 the current matrix is altered. A value of cursor.vpos < 0 means
14778 that PT is either in one of the lines beginning at
14779 first_unchanged_at_end_row or below the window. Don't care for
14780 lines that might be displayed later at the window end; as
14781 mentioned, this is not a frequent case. */
14782 if (w->cursor.vpos < 0)
14783 {
14784 /* Cursor in unchanged rows at the top? */
14785 if (PT < CHARPOS (start_pos)
14786 && last_unchanged_at_beg_row)
14787 {
14788 row = row_containing_pos (w, PT,
14789 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
14790 last_unchanged_at_beg_row + 1, 0);
14791 if (row)
14792 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14793 }
14794
14795 /* Start from first_unchanged_at_end_row looking for PT. */
14796 else if (first_unchanged_at_end_row)
14797 {
14798 row = row_containing_pos (w, PT - delta,
14799 first_unchanged_at_end_row, NULL, 0);
14800 if (row)
14801 set_cursor_from_row (w, row, w->current_matrix, delta,
14802 delta_bytes, dy, dvpos);
14803 }
14804
14805 /* Give up if cursor was not found. */
14806 if (w->cursor.vpos < 0)
14807 {
14808 clear_glyph_matrix (w->desired_matrix);
14809 return -1;
14810 }
14811 }
14812
14813 /* Don't let the cursor end in the scroll margins. */
14814 {
14815 int this_scroll_margin, cursor_height;
14816
14817 this_scroll_margin = max (0, scroll_margin);
14818 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14819 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
14820 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
14821
14822 if ((w->cursor.y < this_scroll_margin
14823 && CHARPOS (start) > BEGV)
14824 /* Old redisplay didn't take scroll margin into account at the bottom,
14825 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
14826 || (w->cursor.y + (make_cursor_line_fully_visible_p
14827 ? cursor_height + this_scroll_margin
14828 : 1)) > it.last_visible_y)
14829 {
14830 w->cursor.vpos = -1;
14831 clear_glyph_matrix (w->desired_matrix);
14832 return -1;
14833 }
14834 }
14835
14836 /* Scroll the display. Do it before changing the current matrix so
14837 that xterm.c doesn't get confused about where the cursor glyph is
14838 found. */
14839 if (dy && run.height)
14840 {
14841 update_begin (f);
14842
14843 if (FRAME_WINDOW_P (f))
14844 {
14845 FRAME_RIF (f)->update_window_begin_hook (w);
14846 FRAME_RIF (f)->clear_window_mouse_face (w);
14847 FRAME_RIF (f)->scroll_run_hook (w, &run);
14848 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14849 }
14850 else
14851 {
14852 /* Terminal frame. In this case, dvpos gives the number of
14853 lines to scroll by; dvpos < 0 means scroll up. */
14854 int first_unchanged_at_end_vpos
14855 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
14856 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
14857 int end = (WINDOW_TOP_EDGE_LINE (w)
14858 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
14859 + window_internal_height (w));
14860
14861 /* Perform the operation on the screen. */
14862 if (dvpos > 0)
14863 {
14864 /* Scroll last_unchanged_at_beg_row to the end of the
14865 window down dvpos lines. */
14866 set_terminal_window (f, end);
14867
14868 /* On dumb terminals delete dvpos lines at the end
14869 before inserting dvpos empty lines. */
14870 if (!FRAME_SCROLL_REGION_OK (f))
14871 ins_del_lines (f, end - dvpos, -dvpos);
14872
14873 /* Insert dvpos empty lines in front of
14874 last_unchanged_at_beg_row. */
14875 ins_del_lines (f, from, dvpos);
14876 }
14877 else if (dvpos < 0)
14878 {
14879 /* Scroll up last_unchanged_at_beg_vpos to the end of
14880 the window to last_unchanged_at_beg_vpos - |dvpos|. */
14881 set_terminal_window (f, end);
14882
14883 /* Delete dvpos lines in front of
14884 last_unchanged_at_beg_vpos. ins_del_lines will set
14885 the cursor to the given vpos and emit |dvpos| delete
14886 line sequences. */
14887 ins_del_lines (f, from + dvpos, dvpos);
14888
14889 /* On a dumb terminal insert dvpos empty lines at the
14890 end. */
14891 if (!FRAME_SCROLL_REGION_OK (f))
14892 ins_del_lines (f, end + dvpos, -dvpos);
14893 }
14894
14895 set_terminal_window (f, 0);
14896 }
14897
14898 update_end (f);
14899 }
14900
14901 /* Shift reused rows of the current matrix to the right position.
14902 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
14903 text. */
14904 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14905 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
14906 if (dvpos < 0)
14907 {
14908 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
14909 bottom_vpos, dvpos);
14910 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
14911 bottom_vpos, 0);
14912 }
14913 else if (dvpos > 0)
14914 {
14915 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
14916 bottom_vpos, dvpos);
14917 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
14918 first_unchanged_at_end_vpos + dvpos, 0);
14919 }
14920
14921 /* For frame-based redisplay, make sure that current frame and window
14922 matrix are in sync with respect to glyph memory. */
14923 if (!FRAME_WINDOW_P (f))
14924 sync_frame_with_window_matrix_rows (w);
14925
14926 /* Adjust buffer positions in reused rows. */
14927 if (delta || delta_bytes)
14928 increment_matrix_positions (current_matrix,
14929 first_unchanged_at_end_vpos + dvpos,
14930 bottom_vpos, delta, delta_bytes);
14931
14932 /* Adjust Y positions. */
14933 if (dy)
14934 shift_glyph_matrix (w, current_matrix,
14935 first_unchanged_at_end_vpos + dvpos,
14936 bottom_vpos, dy);
14937
14938 if (first_unchanged_at_end_row)
14939 {
14940 first_unchanged_at_end_row += dvpos;
14941 if (first_unchanged_at_end_row->y >= it.last_visible_y
14942 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
14943 first_unchanged_at_end_row = NULL;
14944 }
14945
14946 /* If scrolling up, there may be some lines to display at the end of
14947 the window. */
14948 last_text_row_at_end = NULL;
14949 if (dy < 0)
14950 {
14951 /* Scrolling up can leave for example a partially visible line
14952 at the end of the window to be redisplayed. */
14953 /* Set last_row to the glyph row in the current matrix where the
14954 window end line is found. It has been moved up or down in
14955 the matrix by dvpos. */
14956 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
14957 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
14958
14959 /* If last_row is the window end line, it should display text. */
14960 xassert (last_row->displays_text_p);
14961
14962 /* If window end line was partially visible before, begin
14963 displaying at that line. Otherwise begin displaying with the
14964 line following it. */
14965 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
14966 {
14967 init_to_row_start (&it, w, last_row);
14968 it.vpos = last_vpos;
14969 it.current_y = last_row->y;
14970 }
14971 else
14972 {
14973 init_to_row_end (&it, w, last_row);
14974 it.vpos = 1 + last_vpos;
14975 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
14976 ++last_row;
14977 }
14978
14979 /* We may start in a continuation line. If so, we have to
14980 get the right continuation_lines_width and current_x. */
14981 it.continuation_lines_width = last_row->continuation_lines_width;
14982 it.hpos = it.current_x = 0;
14983
14984 /* Display the rest of the lines at the window end. */
14985 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14986 while (it.current_y < it.last_visible_y
14987 && !fonts_changed_p)
14988 {
14989 /* Is it always sure that the display agrees with lines in
14990 the current matrix? I don't think so, so we mark rows
14991 displayed invalid in the current matrix by setting their
14992 enabled_p flag to zero. */
14993 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
14994 if (display_line (&it))
14995 last_text_row_at_end = it.glyph_row - 1;
14996 }
14997 }
14998
14999 /* Update window_end_pos and window_end_vpos. */
15000 if (first_unchanged_at_end_row
15001 && !last_text_row_at_end)
15002 {
15003 /* Window end line if one of the preserved rows from the current
15004 matrix. Set row to the last row displaying text in current
15005 matrix starting at first_unchanged_at_end_row, after
15006 scrolling. */
15007 xassert (first_unchanged_at_end_row->displays_text_p);
15008 row = find_last_row_displaying_text (w->current_matrix, &it,
15009 first_unchanged_at_end_row);
15010 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
15011
15012 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15013 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15014 w->window_end_vpos
15015 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
15016 xassert (w->window_end_bytepos >= 0);
15017 IF_DEBUG (debug_method_add (w, "A"));
15018 }
15019 else if (last_text_row_at_end)
15020 {
15021 w->window_end_pos
15022 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
15023 w->window_end_bytepos
15024 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
15025 w->window_end_vpos
15026 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
15027 xassert (w->window_end_bytepos >= 0);
15028 IF_DEBUG (debug_method_add (w, "B"));
15029 }
15030 else if (last_text_row)
15031 {
15032 /* We have displayed either to the end of the window or at the
15033 end of the window, i.e. the last row with text is to be found
15034 in the desired matrix. */
15035 w->window_end_pos
15036 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15037 w->window_end_bytepos
15038 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15039 w->window_end_vpos
15040 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
15041 xassert (w->window_end_bytepos >= 0);
15042 }
15043 else if (first_unchanged_at_end_row == NULL
15044 && last_text_row == NULL
15045 && last_text_row_at_end == NULL)
15046 {
15047 /* Displayed to end of window, but no line containing text was
15048 displayed. Lines were deleted at the end of the window. */
15049 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
15050 int vpos = XFASTINT (w->window_end_vpos);
15051 struct glyph_row *current_row = current_matrix->rows + vpos;
15052 struct glyph_row *desired_row = desired_matrix->rows + vpos;
15053
15054 for (row = NULL;
15055 row == NULL && vpos >= first_vpos;
15056 --vpos, --current_row, --desired_row)
15057 {
15058 if (desired_row->enabled_p)
15059 {
15060 if (desired_row->displays_text_p)
15061 row = desired_row;
15062 }
15063 else if (current_row->displays_text_p)
15064 row = current_row;
15065 }
15066
15067 xassert (row != NULL);
15068 w->window_end_vpos = make_number (vpos + 1);
15069 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15070 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15071 xassert (w->window_end_bytepos >= 0);
15072 IF_DEBUG (debug_method_add (w, "C"));
15073 }
15074 else
15075 abort ();
15076
15077 #if 0 /* This leads to problems, for instance when the cursor is
15078 at ZV, and the cursor line displays no text. */
15079 /* Disable rows below what's displayed in the window. This makes
15080 debugging easier. */
15081 enable_glyph_matrix_rows (current_matrix,
15082 XFASTINT (w->window_end_vpos) + 1,
15083 bottom_vpos, 0);
15084 #endif
15085
15086 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
15087 debug_end_vpos = XFASTINT (w->window_end_vpos));
15088
15089 /* Record that display has not been completed. */
15090 w->window_end_valid = Qnil;
15091 w->desired_matrix->no_scrolling_p = 1;
15092 return 3;
15093
15094 #undef GIVE_UP
15095 }
15096
15097
15098 \f
15099 /***********************************************************************
15100 More debugging support
15101 ***********************************************************************/
15102
15103 #if GLYPH_DEBUG
15104
15105 void dump_glyph_row P_ ((struct glyph_row *, int, int));
15106 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
15107 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
15108
15109
15110 /* Dump the contents of glyph matrix MATRIX on stderr.
15111
15112 GLYPHS 0 means don't show glyph contents.
15113 GLYPHS 1 means show glyphs in short form
15114 GLYPHS > 1 means show glyphs in long form. */
15115
15116 void
15117 dump_glyph_matrix (matrix, glyphs)
15118 struct glyph_matrix *matrix;
15119 int glyphs;
15120 {
15121 int i;
15122 for (i = 0; i < matrix->nrows; ++i)
15123 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
15124 }
15125
15126
15127 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
15128 the glyph row and area where the glyph comes from. */
15129
15130 void
15131 dump_glyph (row, glyph, area)
15132 struct glyph_row *row;
15133 struct glyph *glyph;
15134 int area;
15135 {
15136 if (glyph->type == CHAR_GLYPH)
15137 {
15138 fprintf (stderr,
15139 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15140 glyph - row->glyphs[TEXT_AREA],
15141 'C',
15142 glyph->charpos,
15143 (BUFFERP (glyph->object)
15144 ? 'B'
15145 : (STRINGP (glyph->object)
15146 ? 'S'
15147 : '-')),
15148 glyph->pixel_width,
15149 glyph->u.ch,
15150 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
15151 ? glyph->u.ch
15152 : '.'),
15153 glyph->face_id,
15154 glyph->left_box_line_p,
15155 glyph->right_box_line_p);
15156 }
15157 else if (glyph->type == STRETCH_GLYPH)
15158 {
15159 fprintf (stderr,
15160 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15161 glyph - row->glyphs[TEXT_AREA],
15162 'S',
15163 glyph->charpos,
15164 (BUFFERP (glyph->object)
15165 ? 'B'
15166 : (STRINGP (glyph->object)
15167 ? 'S'
15168 : '-')),
15169 glyph->pixel_width,
15170 0,
15171 '.',
15172 glyph->face_id,
15173 glyph->left_box_line_p,
15174 glyph->right_box_line_p);
15175 }
15176 else if (glyph->type == IMAGE_GLYPH)
15177 {
15178 fprintf (stderr,
15179 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15180 glyph - row->glyphs[TEXT_AREA],
15181 'I',
15182 glyph->charpos,
15183 (BUFFERP (glyph->object)
15184 ? 'B'
15185 : (STRINGP (glyph->object)
15186 ? 'S'
15187 : '-')),
15188 glyph->pixel_width,
15189 glyph->u.img_id,
15190 '.',
15191 glyph->face_id,
15192 glyph->left_box_line_p,
15193 glyph->right_box_line_p);
15194 }
15195 else if (glyph->type == COMPOSITE_GLYPH)
15196 {
15197 fprintf (stderr,
15198 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15199 glyph - row->glyphs[TEXT_AREA],
15200 '+',
15201 glyph->charpos,
15202 (BUFFERP (glyph->object)
15203 ? 'B'
15204 : (STRINGP (glyph->object)
15205 ? 'S'
15206 : '-')),
15207 glyph->pixel_width,
15208 glyph->u.cmp_id,
15209 '.',
15210 glyph->face_id,
15211 glyph->left_box_line_p,
15212 glyph->right_box_line_p);
15213 }
15214 }
15215
15216
15217 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
15218 GLYPHS 0 means don't show glyph contents.
15219 GLYPHS 1 means show glyphs in short form
15220 GLYPHS > 1 means show glyphs in long form. */
15221
15222 void
15223 dump_glyph_row (row, vpos, glyphs)
15224 struct glyph_row *row;
15225 int vpos, glyphs;
15226 {
15227 if (glyphs != 1)
15228 {
15229 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
15230 fprintf (stderr, "======================================================================\n");
15231
15232 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
15233 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
15234 vpos,
15235 MATRIX_ROW_START_CHARPOS (row),
15236 MATRIX_ROW_END_CHARPOS (row),
15237 row->used[TEXT_AREA],
15238 row->contains_overlapping_glyphs_p,
15239 row->enabled_p,
15240 row->truncated_on_left_p,
15241 row->truncated_on_right_p,
15242 row->continued_p,
15243 MATRIX_ROW_CONTINUATION_LINE_P (row),
15244 row->displays_text_p,
15245 row->ends_at_zv_p,
15246 row->fill_line_p,
15247 row->ends_in_middle_of_char_p,
15248 row->starts_in_middle_of_char_p,
15249 row->mouse_face_p,
15250 row->x,
15251 row->y,
15252 row->pixel_width,
15253 row->height,
15254 row->visible_height,
15255 row->ascent,
15256 row->phys_ascent);
15257 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
15258 row->end.overlay_string_index,
15259 row->continuation_lines_width);
15260 fprintf (stderr, "%9d %5d\n",
15261 CHARPOS (row->start.string_pos),
15262 CHARPOS (row->end.string_pos));
15263 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
15264 row->end.dpvec_index);
15265 }
15266
15267 if (glyphs > 1)
15268 {
15269 int area;
15270
15271 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15272 {
15273 struct glyph *glyph = row->glyphs[area];
15274 struct glyph *glyph_end = glyph + row->used[area];
15275
15276 /* Glyph for a line end in text. */
15277 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
15278 ++glyph_end;
15279
15280 if (glyph < glyph_end)
15281 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
15282
15283 for (; glyph < glyph_end; ++glyph)
15284 dump_glyph (row, glyph, area);
15285 }
15286 }
15287 else if (glyphs == 1)
15288 {
15289 int area;
15290
15291 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15292 {
15293 char *s = (char *) alloca (row->used[area] + 1);
15294 int i;
15295
15296 for (i = 0; i < row->used[area]; ++i)
15297 {
15298 struct glyph *glyph = row->glyphs[area] + i;
15299 if (glyph->type == CHAR_GLYPH
15300 && glyph->u.ch < 0x80
15301 && glyph->u.ch >= ' ')
15302 s[i] = glyph->u.ch;
15303 else
15304 s[i] = '.';
15305 }
15306
15307 s[i] = '\0';
15308 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
15309 }
15310 }
15311 }
15312
15313
15314 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
15315 Sdump_glyph_matrix, 0, 1, "p",
15316 doc: /* Dump the current matrix of the selected window to stderr.
15317 Shows contents of glyph row structures. With non-nil
15318 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
15319 glyphs in short form, otherwise show glyphs in long form. */)
15320 (glyphs)
15321 Lisp_Object glyphs;
15322 {
15323 struct window *w = XWINDOW (selected_window);
15324 struct buffer *buffer = XBUFFER (w->buffer);
15325
15326 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
15327 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
15328 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
15329 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
15330 fprintf (stderr, "=============================================\n");
15331 dump_glyph_matrix (w->current_matrix,
15332 NILP (glyphs) ? 0 : XINT (glyphs));
15333 return Qnil;
15334 }
15335
15336
15337 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
15338 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
15339 ()
15340 {
15341 struct frame *f = XFRAME (selected_frame);
15342 dump_glyph_matrix (f->current_matrix, 1);
15343 return Qnil;
15344 }
15345
15346
15347 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
15348 doc: /* Dump glyph row ROW to stderr.
15349 GLYPH 0 means don't dump glyphs.
15350 GLYPH 1 means dump glyphs in short form.
15351 GLYPH > 1 or omitted means dump glyphs in long form. */)
15352 (row, glyphs)
15353 Lisp_Object row, glyphs;
15354 {
15355 struct glyph_matrix *matrix;
15356 int vpos;
15357
15358 CHECK_NUMBER (row);
15359 matrix = XWINDOW (selected_window)->current_matrix;
15360 vpos = XINT (row);
15361 if (vpos >= 0 && vpos < matrix->nrows)
15362 dump_glyph_row (MATRIX_ROW (matrix, vpos),
15363 vpos,
15364 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15365 return Qnil;
15366 }
15367
15368
15369 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
15370 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
15371 GLYPH 0 means don't dump glyphs.
15372 GLYPH 1 means dump glyphs in short form.
15373 GLYPH > 1 or omitted means dump glyphs in long form. */)
15374 (row, glyphs)
15375 Lisp_Object row, glyphs;
15376 {
15377 struct frame *sf = SELECTED_FRAME ();
15378 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
15379 int vpos;
15380
15381 CHECK_NUMBER (row);
15382 vpos = XINT (row);
15383 if (vpos >= 0 && vpos < m->nrows)
15384 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
15385 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15386 return Qnil;
15387 }
15388
15389
15390 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
15391 doc: /* Toggle tracing of redisplay.
15392 With ARG, turn tracing on if and only if ARG is positive. */)
15393 (arg)
15394 Lisp_Object arg;
15395 {
15396 if (NILP (arg))
15397 trace_redisplay_p = !trace_redisplay_p;
15398 else
15399 {
15400 arg = Fprefix_numeric_value (arg);
15401 trace_redisplay_p = XINT (arg) > 0;
15402 }
15403
15404 return Qnil;
15405 }
15406
15407
15408 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
15409 doc: /* Like `format', but print result to stderr.
15410 usage: (trace-to-stderr STRING &rest OBJECTS) */)
15411 (nargs, args)
15412 int nargs;
15413 Lisp_Object *args;
15414 {
15415 Lisp_Object s = Fformat (nargs, args);
15416 fprintf (stderr, "%s", SDATA (s));
15417 return Qnil;
15418 }
15419
15420 #endif /* GLYPH_DEBUG */
15421
15422
15423 \f
15424 /***********************************************************************
15425 Building Desired Matrix Rows
15426 ***********************************************************************/
15427
15428 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
15429 Used for non-window-redisplay windows, and for windows w/o left fringe. */
15430
15431 static struct glyph_row *
15432 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
15433 struct window *w;
15434 Lisp_Object overlay_arrow_string;
15435 {
15436 struct frame *f = XFRAME (WINDOW_FRAME (w));
15437 struct buffer *buffer = XBUFFER (w->buffer);
15438 struct buffer *old = current_buffer;
15439 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
15440 int arrow_len = SCHARS (overlay_arrow_string);
15441 const unsigned char *arrow_end = arrow_string + arrow_len;
15442 const unsigned char *p;
15443 struct it it;
15444 int multibyte_p;
15445 int n_glyphs_before;
15446
15447 set_buffer_temp (buffer);
15448 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
15449 it.glyph_row->used[TEXT_AREA] = 0;
15450 SET_TEXT_POS (it.position, 0, 0);
15451
15452 multibyte_p = !NILP (buffer->enable_multibyte_characters);
15453 p = arrow_string;
15454 while (p < arrow_end)
15455 {
15456 Lisp_Object face, ilisp;
15457
15458 /* Get the next character. */
15459 if (multibyte_p)
15460 it.c = string_char_and_length (p, arrow_len, &it.len);
15461 else
15462 it.c = *p, it.len = 1;
15463 p += it.len;
15464
15465 /* Get its face. */
15466 ilisp = make_number (p - arrow_string);
15467 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
15468 it.face_id = compute_char_face (f, it.c, face);
15469
15470 /* Compute its width, get its glyphs. */
15471 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
15472 SET_TEXT_POS (it.position, -1, -1);
15473 PRODUCE_GLYPHS (&it);
15474
15475 /* If this character doesn't fit any more in the line, we have
15476 to remove some glyphs. */
15477 if (it.current_x > it.last_visible_x)
15478 {
15479 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
15480 break;
15481 }
15482 }
15483
15484 set_buffer_temp (old);
15485 return it.glyph_row;
15486 }
15487
15488
15489 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
15490 glyphs are only inserted for terminal frames since we can't really
15491 win with truncation glyphs when partially visible glyphs are
15492 involved. Which glyphs to insert is determined by
15493 produce_special_glyphs. */
15494
15495 static void
15496 insert_left_trunc_glyphs (it)
15497 struct it *it;
15498 {
15499 struct it truncate_it;
15500 struct glyph *from, *end, *to, *toend;
15501
15502 xassert (!FRAME_WINDOW_P (it->f));
15503
15504 /* Get the truncation glyphs. */
15505 truncate_it = *it;
15506 truncate_it.current_x = 0;
15507 truncate_it.face_id = DEFAULT_FACE_ID;
15508 truncate_it.glyph_row = &scratch_glyph_row;
15509 truncate_it.glyph_row->used[TEXT_AREA] = 0;
15510 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
15511 truncate_it.object = make_number (0);
15512 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
15513
15514 /* Overwrite glyphs from IT with truncation glyphs. */
15515 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15516 end = from + truncate_it.glyph_row->used[TEXT_AREA];
15517 to = it->glyph_row->glyphs[TEXT_AREA];
15518 toend = to + it->glyph_row->used[TEXT_AREA];
15519
15520 while (from < end)
15521 *to++ = *from++;
15522
15523 /* There may be padding glyphs left over. Overwrite them too. */
15524 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
15525 {
15526 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15527 while (from < end)
15528 *to++ = *from++;
15529 }
15530
15531 if (to > toend)
15532 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
15533 }
15534
15535
15536 /* Compute the pixel height and width of IT->glyph_row.
15537
15538 Most of the time, ascent and height of a display line will be equal
15539 to the max_ascent and max_height values of the display iterator
15540 structure. This is not the case if
15541
15542 1. We hit ZV without displaying anything. In this case, max_ascent
15543 and max_height will be zero.
15544
15545 2. We have some glyphs that don't contribute to the line height.
15546 (The glyph row flag contributes_to_line_height_p is for future
15547 pixmap extensions).
15548
15549 The first case is easily covered by using default values because in
15550 these cases, the line height does not really matter, except that it
15551 must not be zero. */
15552
15553 static void
15554 compute_line_metrics (it)
15555 struct it *it;
15556 {
15557 struct glyph_row *row = it->glyph_row;
15558 int area, i;
15559
15560 if (FRAME_WINDOW_P (it->f))
15561 {
15562 int i, min_y, max_y;
15563
15564 /* The line may consist of one space only, that was added to
15565 place the cursor on it. If so, the row's height hasn't been
15566 computed yet. */
15567 if (row->height == 0)
15568 {
15569 if (it->max_ascent + it->max_descent == 0)
15570 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
15571 row->ascent = it->max_ascent;
15572 row->height = it->max_ascent + it->max_descent;
15573 row->phys_ascent = it->max_phys_ascent;
15574 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15575 row->extra_line_spacing = it->max_extra_line_spacing;
15576 }
15577
15578 /* Compute the width of this line. */
15579 row->pixel_width = row->x;
15580 for (i = 0; i < row->used[TEXT_AREA]; ++i)
15581 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
15582
15583 xassert (row->pixel_width >= 0);
15584 xassert (row->ascent >= 0 && row->height > 0);
15585
15586 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
15587 || MATRIX_ROW_OVERLAPS_PRED_P (row));
15588
15589 /* If first line's physical ascent is larger than its logical
15590 ascent, use the physical ascent, and make the row taller.
15591 This makes accented characters fully visible. */
15592 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
15593 && row->phys_ascent > row->ascent)
15594 {
15595 row->height += row->phys_ascent - row->ascent;
15596 row->ascent = row->phys_ascent;
15597 }
15598
15599 /* Compute how much of the line is visible. */
15600 row->visible_height = row->height;
15601
15602 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
15603 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
15604
15605 if (row->y < min_y)
15606 row->visible_height -= min_y - row->y;
15607 if (row->y + row->height > max_y)
15608 row->visible_height -= row->y + row->height - max_y;
15609 }
15610 else
15611 {
15612 row->pixel_width = row->used[TEXT_AREA];
15613 if (row->continued_p)
15614 row->pixel_width -= it->continuation_pixel_width;
15615 else if (row->truncated_on_right_p)
15616 row->pixel_width -= it->truncation_pixel_width;
15617 row->ascent = row->phys_ascent = 0;
15618 row->height = row->phys_height = row->visible_height = 1;
15619 row->extra_line_spacing = 0;
15620 }
15621
15622 /* Compute a hash code for this row. */
15623 row->hash = 0;
15624 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15625 for (i = 0; i < row->used[area]; ++i)
15626 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
15627 + row->glyphs[area][i].u.val
15628 + row->glyphs[area][i].face_id
15629 + row->glyphs[area][i].padding_p
15630 + (row->glyphs[area][i].type << 2));
15631
15632 it->max_ascent = it->max_descent = 0;
15633 it->max_phys_ascent = it->max_phys_descent = 0;
15634 }
15635
15636
15637 /* Append one space to the glyph row of iterator IT if doing a
15638 window-based redisplay. The space has the same face as
15639 IT->face_id. Value is non-zero if a space was added.
15640
15641 This function is called to make sure that there is always one glyph
15642 at the end of a glyph row that the cursor can be set on under
15643 window-systems. (If there weren't such a glyph we would not know
15644 how wide and tall a box cursor should be displayed).
15645
15646 At the same time this space let's a nicely handle clearing to the
15647 end of the line if the row ends in italic text. */
15648
15649 static int
15650 append_space_for_newline (it, default_face_p)
15651 struct it *it;
15652 int default_face_p;
15653 {
15654 if (FRAME_WINDOW_P (it->f))
15655 {
15656 int n = it->glyph_row->used[TEXT_AREA];
15657
15658 if (it->glyph_row->glyphs[TEXT_AREA] + n
15659 < it->glyph_row->glyphs[1 + TEXT_AREA])
15660 {
15661 /* Save some values that must not be changed.
15662 Must save IT->c and IT->len because otherwise
15663 ITERATOR_AT_END_P wouldn't work anymore after
15664 append_space_for_newline has been called. */
15665 enum display_element_type saved_what = it->what;
15666 int saved_c = it->c, saved_len = it->len;
15667 int saved_x = it->current_x;
15668 int saved_face_id = it->face_id;
15669 struct text_pos saved_pos;
15670 Lisp_Object saved_object;
15671 struct face *face;
15672
15673 saved_object = it->object;
15674 saved_pos = it->position;
15675
15676 it->what = IT_CHARACTER;
15677 bzero (&it->position, sizeof it->position);
15678 it->object = make_number (0);
15679 it->c = ' ';
15680 it->len = 1;
15681
15682 if (default_face_p)
15683 it->face_id = DEFAULT_FACE_ID;
15684 else if (it->face_before_selective_p)
15685 it->face_id = it->saved_face_id;
15686 face = FACE_FROM_ID (it->f, it->face_id);
15687 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
15688
15689 PRODUCE_GLYPHS (it);
15690
15691 it->override_ascent = -1;
15692 it->constrain_row_ascent_descent_p = 0;
15693 it->current_x = saved_x;
15694 it->object = saved_object;
15695 it->position = saved_pos;
15696 it->what = saved_what;
15697 it->face_id = saved_face_id;
15698 it->len = saved_len;
15699 it->c = saved_c;
15700 return 1;
15701 }
15702 }
15703
15704 return 0;
15705 }
15706
15707
15708 /* Extend the face of the last glyph in the text area of IT->glyph_row
15709 to the end of the display line. Called from display_line.
15710 If the glyph row is empty, add a space glyph to it so that we
15711 know the face to draw. Set the glyph row flag fill_line_p. */
15712
15713 static void
15714 extend_face_to_end_of_line (it)
15715 struct it *it;
15716 {
15717 struct face *face;
15718 struct frame *f = it->f;
15719
15720 /* If line is already filled, do nothing. */
15721 if (it->current_x >= it->last_visible_x)
15722 return;
15723
15724 /* Face extension extends the background and box of IT->face_id
15725 to the end of the line. If the background equals the background
15726 of the frame, we don't have to do anything. */
15727 if (it->face_before_selective_p)
15728 face = FACE_FROM_ID (it->f, it->saved_face_id);
15729 else
15730 face = FACE_FROM_ID (f, it->face_id);
15731
15732 if (FRAME_WINDOW_P (f)
15733 && it->glyph_row->displays_text_p
15734 && face->box == FACE_NO_BOX
15735 && face->background == FRAME_BACKGROUND_PIXEL (f)
15736 && !face->stipple)
15737 return;
15738
15739 /* Set the glyph row flag indicating that the face of the last glyph
15740 in the text area has to be drawn to the end of the text area. */
15741 it->glyph_row->fill_line_p = 1;
15742
15743 /* If current character of IT is not ASCII, make sure we have the
15744 ASCII face. This will be automatically undone the next time
15745 get_next_display_element returns a multibyte character. Note
15746 that the character will always be single byte in unibyte text. */
15747 if (!SINGLE_BYTE_CHAR_P (it->c))
15748 {
15749 it->face_id = FACE_FOR_CHAR (f, face, 0);
15750 }
15751
15752 if (FRAME_WINDOW_P (f))
15753 {
15754 /* If the row is empty, add a space with the current face of IT,
15755 so that we know which face to draw. */
15756 if (it->glyph_row->used[TEXT_AREA] == 0)
15757 {
15758 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
15759 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
15760 it->glyph_row->used[TEXT_AREA] = 1;
15761 }
15762 }
15763 else
15764 {
15765 /* Save some values that must not be changed. */
15766 int saved_x = it->current_x;
15767 struct text_pos saved_pos;
15768 Lisp_Object saved_object;
15769 enum display_element_type saved_what = it->what;
15770 int saved_face_id = it->face_id;
15771
15772 saved_object = it->object;
15773 saved_pos = it->position;
15774
15775 it->what = IT_CHARACTER;
15776 bzero (&it->position, sizeof it->position);
15777 it->object = make_number (0);
15778 it->c = ' ';
15779 it->len = 1;
15780 it->face_id = face->id;
15781
15782 PRODUCE_GLYPHS (it);
15783
15784 while (it->current_x <= it->last_visible_x)
15785 PRODUCE_GLYPHS (it);
15786
15787 /* Don't count these blanks really. It would let us insert a left
15788 truncation glyph below and make us set the cursor on them, maybe. */
15789 it->current_x = saved_x;
15790 it->object = saved_object;
15791 it->position = saved_pos;
15792 it->what = saved_what;
15793 it->face_id = saved_face_id;
15794 }
15795 }
15796
15797
15798 /* Value is non-zero if text starting at CHARPOS in current_buffer is
15799 trailing whitespace. */
15800
15801 static int
15802 trailing_whitespace_p (charpos)
15803 int charpos;
15804 {
15805 int bytepos = CHAR_TO_BYTE (charpos);
15806 int c = 0;
15807
15808 while (bytepos < ZV_BYTE
15809 && (c = FETCH_CHAR (bytepos),
15810 c == ' ' || c == '\t'))
15811 ++bytepos;
15812
15813 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
15814 {
15815 if (bytepos != PT_BYTE)
15816 return 1;
15817 }
15818 return 0;
15819 }
15820
15821
15822 /* Highlight trailing whitespace, if any, in ROW. */
15823
15824 void
15825 highlight_trailing_whitespace (f, row)
15826 struct frame *f;
15827 struct glyph_row *row;
15828 {
15829 int used = row->used[TEXT_AREA];
15830
15831 if (used)
15832 {
15833 struct glyph *start = row->glyphs[TEXT_AREA];
15834 struct glyph *glyph = start + used - 1;
15835
15836 /* Skip over glyphs inserted to display the cursor at the
15837 end of a line, for extending the face of the last glyph
15838 to the end of the line on terminals, and for truncation
15839 and continuation glyphs. */
15840 while (glyph >= start
15841 && glyph->type == CHAR_GLYPH
15842 && INTEGERP (glyph->object))
15843 --glyph;
15844
15845 /* If last glyph is a space or stretch, and it's trailing
15846 whitespace, set the face of all trailing whitespace glyphs in
15847 IT->glyph_row to `trailing-whitespace'. */
15848 if (glyph >= start
15849 && BUFFERP (glyph->object)
15850 && (glyph->type == STRETCH_GLYPH
15851 || (glyph->type == CHAR_GLYPH
15852 && glyph->u.ch == ' '))
15853 && trailing_whitespace_p (glyph->charpos))
15854 {
15855 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
15856 if (face_id < 0)
15857 return;
15858
15859 while (glyph >= start
15860 && BUFFERP (glyph->object)
15861 && (glyph->type == STRETCH_GLYPH
15862 || (glyph->type == CHAR_GLYPH
15863 && glyph->u.ch == ' ')))
15864 (glyph--)->face_id = face_id;
15865 }
15866 }
15867 }
15868
15869
15870 /* Value is non-zero if glyph row ROW in window W should be
15871 used to hold the cursor. */
15872
15873 static int
15874 cursor_row_p (w, row)
15875 struct window *w;
15876 struct glyph_row *row;
15877 {
15878 int cursor_row_p = 1;
15879
15880 if (PT == MATRIX_ROW_END_CHARPOS (row))
15881 {
15882 /* Suppose the row ends on a string.
15883 Unless the row is continued, that means it ends on a newline
15884 in the string. If it's anything other than a display string
15885 (e.g. a before-string from an overlay), we don't want the
15886 cursor there. (This heuristic seems to give the optimal
15887 behavior for the various types of multi-line strings.) */
15888 if (CHARPOS (row->end.string_pos) >= 0)
15889 {
15890 if (row->continued_p)
15891 cursor_row_p = 1;
15892 else
15893 {
15894 /* Check for `display' property. */
15895 struct glyph *beg = row->glyphs[TEXT_AREA];
15896 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
15897 struct glyph *glyph;
15898
15899 cursor_row_p = 0;
15900 for (glyph = end; glyph >= beg; --glyph)
15901 if (STRINGP (glyph->object))
15902 {
15903 Lisp_Object prop
15904 = Fget_char_property (make_number (PT),
15905 Qdisplay, Qnil);
15906 cursor_row_p =
15907 (!NILP (prop)
15908 && display_prop_string_p (prop, glyph->object));
15909 break;
15910 }
15911 }
15912 }
15913 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15914 {
15915 /* If the row ends in middle of a real character,
15916 and the line is continued, we want the cursor here.
15917 That's because MATRIX_ROW_END_CHARPOS would equal
15918 PT if PT is before the character. */
15919 if (!row->ends_in_ellipsis_p)
15920 cursor_row_p = row->continued_p;
15921 else
15922 /* If the row ends in an ellipsis, then
15923 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
15924 We want that position to be displayed after the ellipsis. */
15925 cursor_row_p = 0;
15926 }
15927 /* If the row ends at ZV, display the cursor at the end of that
15928 row instead of at the start of the row below. */
15929 else if (row->ends_at_zv_p)
15930 cursor_row_p = 1;
15931 else
15932 cursor_row_p = 0;
15933 }
15934
15935 return cursor_row_p;
15936 }
15937
15938
15939 /* Construct the glyph row IT->glyph_row in the desired matrix of
15940 IT->w from text at the current position of IT. See dispextern.h
15941 for an overview of struct it. Value is non-zero if
15942 IT->glyph_row displays text, as opposed to a line displaying ZV
15943 only. */
15944
15945 static int
15946 display_line (it)
15947 struct it *it;
15948 {
15949 struct glyph_row *row = it->glyph_row;
15950 Lisp_Object overlay_arrow_string;
15951
15952 /* We always start displaying at hpos zero even if hscrolled. */
15953 xassert (it->hpos == 0 && it->current_x == 0);
15954
15955 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
15956 >= it->w->desired_matrix->nrows)
15957 {
15958 it->w->nrows_scale_factor++;
15959 fonts_changed_p = 1;
15960 return 0;
15961 }
15962
15963 /* Is IT->w showing the region? */
15964 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
15965
15966 /* Clear the result glyph row and enable it. */
15967 prepare_desired_row (row);
15968
15969 row->y = it->current_y;
15970 row->start = it->start;
15971 row->continuation_lines_width = it->continuation_lines_width;
15972 row->displays_text_p = 1;
15973 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
15974 it->starts_in_middle_of_char_p = 0;
15975
15976 /* Arrange the overlays nicely for our purposes. Usually, we call
15977 display_line on only one line at a time, in which case this
15978 can't really hurt too much, or we call it on lines which appear
15979 one after another in the buffer, in which case all calls to
15980 recenter_overlay_lists but the first will be pretty cheap. */
15981 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
15982
15983 /* Move over display elements that are not visible because we are
15984 hscrolled. This may stop at an x-position < IT->first_visible_x
15985 if the first glyph is partially visible or if we hit a line end. */
15986 if (it->current_x < it->first_visible_x)
15987 {
15988 move_it_in_display_line_to (it, ZV, it->first_visible_x,
15989 MOVE_TO_POS | MOVE_TO_X);
15990 }
15991
15992 /* Get the initial row height. This is either the height of the
15993 text hscrolled, if there is any, or zero. */
15994 row->ascent = it->max_ascent;
15995 row->height = it->max_ascent + it->max_descent;
15996 row->phys_ascent = it->max_phys_ascent;
15997 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15998 row->extra_line_spacing = it->max_extra_line_spacing;
15999
16000 /* Loop generating characters. The loop is left with IT on the next
16001 character to display. */
16002 while (1)
16003 {
16004 int n_glyphs_before, hpos_before, x_before;
16005 int x, i, nglyphs;
16006 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
16007
16008 /* Retrieve the next thing to display. Value is zero if end of
16009 buffer reached. */
16010 if (!get_next_display_element (it))
16011 {
16012 /* Maybe add a space at the end of this line that is used to
16013 display the cursor there under X. Set the charpos of the
16014 first glyph of blank lines not corresponding to any text
16015 to -1. */
16016 #ifdef HAVE_WINDOW_SYSTEM
16017 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16018 row->exact_window_width_line_p = 1;
16019 else
16020 #endif /* HAVE_WINDOW_SYSTEM */
16021 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
16022 || row->used[TEXT_AREA] == 0)
16023 {
16024 row->glyphs[TEXT_AREA]->charpos = -1;
16025 row->displays_text_p = 0;
16026
16027 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
16028 && (!MINI_WINDOW_P (it->w)
16029 || (minibuf_level && EQ (it->window, minibuf_window))))
16030 row->indicate_empty_line_p = 1;
16031 }
16032
16033 it->continuation_lines_width = 0;
16034 row->ends_at_zv_p = 1;
16035 break;
16036 }
16037
16038 /* Now, get the metrics of what we want to display. This also
16039 generates glyphs in `row' (which is IT->glyph_row). */
16040 n_glyphs_before = row->used[TEXT_AREA];
16041 x = it->current_x;
16042
16043 /* Remember the line height so far in case the next element doesn't
16044 fit on the line. */
16045 if (!it->truncate_lines_p)
16046 {
16047 ascent = it->max_ascent;
16048 descent = it->max_descent;
16049 phys_ascent = it->max_phys_ascent;
16050 phys_descent = it->max_phys_descent;
16051 }
16052
16053 PRODUCE_GLYPHS (it);
16054
16055 /* If this display element was in marginal areas, continue with
16056 the next one. */
16057 if (it->area != TEXT_AREA)
16058 {
16059 row->ascent = max (row->ascent, it->max_ascent);
16060 row->height = max (row->height, it->max_ascent + it->max_descent);
16061 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16062 row->phys_height = max (row->phys_height,
16063 it->max_phys_ascent + it->max_phys_descent);
16064 row->extra_line_spacing = max (row->extra_line_spacing,
16065 it->max_extra_line_spacing);
16066 set_iterator_to_next (it, 1);
16067 continue;
16068 }
16069
16070 /* Does the display element fit on the line? If we truncate
16071 lines, we should draw past the right edge of the window. If
16072 we don't truncate, we want to stop so that we can display the
16073 continuation glyph before the right margin. If lines are
16074 continued, there are two possible strategies for characters
16075 resulting in more than 1 glyph (e.g. tabs): Display as many
16076 glyphs as possible in this line and leave the rest for the
16077 continuation line, or display the whole element in the next
16078 line. Original redisplay did the former, so we do it also. */
16079 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
16080 hpos_before = it->hpos;
16081 x_before = x;
16082
16083 if (/* Not a newline. */
16084 nglyphs > 0
16085 /* Glyphs produced fit entirely in the line. */
16086 && it->current_x < it->last_visible_x)
16087 {
16088 it->hpos += nglyphs;
16089 row->ascent = max (row->ascent, it->max_ascent);
16090 row->height = max (row->height, it->max_ascent + it->max_descent);
16091 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16092 row->phys_height = max (row->phys_height,
16093 it->max_phys_ascent + it->max_phys_descent);
16094 row->extra_line_spacing = max (row->extra_line_spacing,
16095 it->max_extra_line_spacing);
16096 if (it->current_x - it->pixel_width < it->first_visible_x)
16097 row->x = x - it->first_visible_x;
16098 }
16099 else
16100 {
16101 int new_x;
16102 struct glyph *glyph;
16103
16104 for (i = 0; i < nglyphs; ++i, x = new_x)
16105 {
16106 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16107 new_x = x + glyph->pixel_width;
16108
16109 if (/* Lines are continued. */
16110 !it->truncate_lines_p
16111 && (/* Glyph doesn't fit on the line. */
16112 new_x > it->last_visible_x
16113 /* Or it fits exactly on a window system frame. */
16114 || (new_x == it->last_visible_x
16115 && FRAME_WINDOW_P (it->f))))
16116 {
16117 /* End of a continued line. */
16118
16119 if (it->hpos == 0
16120 || (new_x == it->last_visible_x
16121 && FRAME_WINDOW_P (it->f)))
16122 {
16123 /* Current glyph is the only one on the line or
16124 fits exactly on the line. We must continue
16125 the line because we can't draw the cursor
16126 after the glyph. */
16127 row->continued_p = 1;
16128 it->current_x = new_x;
16129 it->continuation_lines_width += new_x;
16130 ++it->hpos;
16131 if (i == nglyphs - 1)
16132 {
16133 set_iterator_to_next (it, 1);
16134 #ifdef HAVE_WINDOW_SYSTEM
16135 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16136 {
16137 if (!get_next_display_element (it))
16138 {
16139 row->exact_window_width_line_p = 1;
16140 it->continuation_lines_width = 0;
16141 row->continued_p = 0;
16142 row->ends_at_zv_p = 1;
16143 }
16144 else if (ITERATOR_AT_END_OF_LINE_P (it))
16145 {
16146 row->continued_p = 0;
16147 row->exact_window_width_line_p = 1;
16148 }
16149 }
16150 #endif /* HAVE_WINDOW_SYSTEM */
16151 }
16152 }
16153 else if (CHAR_GLYPH_PADDING_P (*glyph)
16154 && !FRAME_WINDOW_P (it->f))
16155 {
16156 /* A padding glyph that doesn't fit on this line.
16157 This means the whole character doesn't fit
16158 on the line. */
16159 row->used[TEXT_AREA] = n_glyphs_before;
16160
16161 /* Fill the rest of the row with continuation
16162 glyphs like in 20.x. */
16163 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
16164 < row->glyphs[1 + TEXT_AREA])
16165 produce_special_glyphs (it, IT_CONTINUATION);
16166
16167 row->continued_p = 1;
16168 it->current_x = x_before;
16169 it->continuation_lines_width += x_before;
16170
16171 /* Restore the height to what it was before the
16172 element not fitting on the line. */
16173 it->max_ascent = ascent;
16174 it->max_descent = descent;
16175 it->max_phys_ascent = phys_ascent;
16176 it->max_phys_descent = phys_descent;
16177 }
16178 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
16179 {
16180 /* A TAB that extends past the right edge of the
16181 window. This produces a single glyph on
16182 window system frames. We leave the glyph in
16183 this row and let it fill the row, but don't
16184 consume the TAB. */
16185 it->continuation_lines_width += it->last_visible_x;
16186 row->ends_in_middle_of_char_p = 1;
16187 row->continued_p = 1;
16188 glyph->pixel_width = it->last_visible_x - x;
16189 it->starts_in_middle_of_char_p = 1;
16190 }
16191 else
16192 {
16193 /* Something other than a TAB that draws past
16194 the right edge of the window. Restore
16195 positions to values before the element. */
16196 row->used[TEXT_AREA] = n_glyphs_before + i;
16197
16198 /* Display continuation glyphs. */
16199 if (!FRAME_WINDOW_P (it->f))
16200 produce_special_glyphs (it, IT_CONTINUATION);
16201 row->continued_p = 1;
16202
16203 it->current_x = x_before;
16204 it->continuation_lines_width += x;
16205 extend_face_to_end_of_line (it);
16206
16207 if (nglyphs > 1 && i > 0)
16208 {
16209 row->ends_in_middle_of_char_p = 1;
16210 it->starts_in_middle_of_char_p = 1;
16211 }
16212
16213 /* Restore the height to what it was before the
16214 element not fitting on the line. */
16215 it->max_ascent = ascent;
16216 it->max_descent = descent;
16217 it->max_phys_ascent = phys_ascent;
16218 it->max_phys_descent = phys_descent;
16219 }
16220
16221 break;
16222 }
16223 else if (new_x > it->first_visible_x)
16224 {
16225 /* Increment number of glyphs actually displayed. */
16226 ++it->hpos;
16227
16228 if (x < it->first_visible_x)
16229 /* Glyph is partially visible, i.e. row starts at
16230 negative X position. */
16231 row->x = x - it->first_visible_x;
16232 }
16233 else
16234 {
16235 /* Glyph is completely off the left margin of the
16236 window. This should not happen because of the
16237 move_it_in_display_line at the start of this
16238 function, unless the text display area of the
16239 window is empty. */
16240 xassert (it->first_visible_x <= it->last_visible_x);
16241 }
16242 }
16243
16244 row->ascent = max (row->ascent, it->max_ascent);
16245 row->height = max (row->height, it->max_ascent + it->max_descent);
16246 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16247 row->phys_height = max (row->phys_height,
16248 it->max_phys_ascent + it->max_phys_descent);
16249 row->extra_line_spacing = max (row->extra_line_spacing,
16250 it->max_extra_line_spacing);
16251
16252 /* End of this display line if row is continued. */
16253 if (row->continued_p || row->ends_at_zv_p)
16254 break;
16255 }
16256
16257 at_end_of_line:
16258 /* Is this a line end? If yes, we're also done, after making
16259 sure that a non-default face is extended up to the right
16260 margin of the window. */
16261 if (ITERATOR_AT_END_OF_LINE_P (it))
16262 {
16263 int used_before = row->used[TEXT_AREA];
16264
16265 row->ends_in_newline_from_string_p = STRINGP (it->object);
16266
16267 #ifdef HAVE_WINDOW_SYSTEM
16268 /* Add a space at the end of the line that is used to
16269 display the cursor there. */
16270 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16271 append_space_for_newline (it, 0);
16272 #endif /* HAVE_WINDOW_SYSTEM */
16273
16274 /* Extend the face to the end of the line. */
16275 extend_face_to_end_of_line (it);
16276
16277 /* Make sure we have the position. */
16278 if (used_before == 0)
16279 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
16280
16281 /* Consume the line end. This skips over invisible lines. */
16282 set_iterator_to_next (it, 1);
16283 it->continuation_lines_width = 0;
16284 break;
16285 }
16286
16287 /* Proceed with next display element. Note that this skips
16288 over lines invisible because of selective display. */
16289 set_iterator_to_next (it, 1);
16290
16291 /* If we truncate lines, we are done when the last displayed
16292 glyphs reach past the right margin of the window. */
16293 if (it->truncate_lines_p
16294 && (FRAME_WINDOW_P (it->f)
16295 ? (it->current_x >= it->last_visible_x)
16296 : (it->current_x > it->last_visible_x)))
16297 {
16298 /* Maybe add truncation glyphs. */
16299 if (!FRAME_WINDOW_P (it->f))
16300 {
16301 int i, n;
16302
16303 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16304 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16305 break;
16306
16307 for (n = row->used[TEXT_AREA]; i < n; ++i)
16308 {
16309 row->used[TEXT_AREA] = i;
16310 produce_special_glyphs (it, IT_TRUNCATION);
16311 }
16312 }
16313 #ifdef HAVE_WINDOW_SYSTEM
16314 else
16315 {
16316 /* Don't truncate if we can overflow newline into fringe. */
16317 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16318 {
16319 if (!get_next_display_element (it))
16320 {
16321 it->continuation_lines_width = 0;
16322 row->ends_at_zv_p = 1;
16323 row->exact_window_width_line_p = 1;
16324 break;
16325 }
16326 if (ITERATOR_AT_END_OF_LINE_P (it))
16327 {
16328 row->exact_window_width_line_p = 1;
16329 goto at_end_of_line;
16330 }
16331 }
16332 }
16333 #endif /* HAVE_WINDOW_SYSTEM */
16334
16335 row->truncated_on_right_p = 1;
16336 it->continuation_lines_width = 0;
16337 reseat_at_next_visible_line_start (it, 0);
16338 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
16339 it->hpos = hpos_before;
16340 it->current_x = x_before;
16341 break;
16342 }
16343 }
16344
16345 /* If line is not empty and hscrolled, maybe insert truncation glyphs
16346 at the left window margin. */
16347 if (it->first_visible_x
16348 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
16349 {
16350 if (!FRAME_WINDOW_P (it->f))
16351 insert_left_trunc_glyphs (it);
16352 row->truncated_on_left_p = 1;
16353 }
16354
16355 /* If the start of this line is the overlay arrow-position, then
16356 mark this glyph row as the one containing the overlay arrow.
16357 This is clearly a mess with variable size fonts. It would be
16358 better to let it be displayed like cursors under X. */
16359 if ((row->displays_text_p || !overlay_arrow_seen)
16360 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
16361 !NILP (overlay_arrow_string)))
16362 {
16363 /* Overlay arrow in window redisplay is a fringe bitmap. */
16364 if (STRINGP (overlay_arrow_string))
16365 {
16366 struct glyph_row *arrow_row
16367 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
16368 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
16369 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
16370 struct glyph *p = row->glyphs[TEXT_AREA];
16371 struct glyph *p2, *end;
16372
16373 /* Copy the arrow glyphs. */
16374 while (glyph < arrow_end)
16375 *p++ = *glyph++;
16376
16377 /* Throw away padding glyphs. */
16378 p2 = p;
16379 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16380 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
16381 ++p2;
16382 if (p2 > p)
16383 {
16384 while (p2 < end)
16385 *p++ = *p2++;
16386 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
16387 }
16388 }
16389 else
16390 {
16391 xassert (INTEGERP (overlay_arrow_string));
16392 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
16393 }
16394 overlay_arrow_seen = 1;
16395 }
16396
16397 /* Compute pixel dimensions of this line. */
16398 compute_line_metrics (it);
16399
16400 /* Remember the position at which this line ends. */
16401 row->end = it->current;
16402
16403 /* Record whether this row ends inside an ellipsis. */
16404 row->ends_in_ellipsis_p
16405 = (it->method == GET_FROM_DISPLAY_VECTOR
16406 && it->ellipsis_p);
16407
16408 /* Save fringe bitmaps in this row. */
16409 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
16410 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
16411 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
16412 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
16413
16414 it->left_user_fringe_bitmap = 0;
16415 it->left_user_fringe_face_id = 0;
16416 it->right_user_fringe_bitmap = 0;
16417 it->right_user_fringe_face_id = 0;
16418
16419 /* Maybe set the cursor. */
16420 if (it->w->cursor.vpos < 0
16421 && PT >= MATRIX_ROW_START_CHARPOS (row)
16422 && PT <= MATRIX_ROW_END_CHARPOS (row)
16423 && cursor_row_p (it->w, row))
16424 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
16425
16426 /* Highlight trailing whitespace. */
16427 if (!NILP (Vshow_trailing_whitespace))
16428 highlight_trailing_whitespace (it->f, it->glyph_row);
16429
16430 /* Prepare for the next line. This line starts horizontally at (X
16431 HPOS) = (0 0). Vertical positions are incremented. As a
16432 convenience for the caller, IT->glyph_row is set to the next
16433 row to be used. */
16434 it->current_x = it->hpos = 0;
16435 it->current_y += row->height;
16436 ++it->vpos;
16437 ++it->glyph_row;
16438 it->start = it->current;
16439 return row->displays_text_p;
16440 }
16441
16442
16443 \f
16444 /***********************************************************************
16445 Menu Bar
16446 ***********************************************************************/
16447
16448 /* Redisplay the menu bar in the frame for window W.
16449
16450 The menu bar of X frames that don't have X toolkit support is
16451 displayed in a special window W->frame->menu_bar_window.
16452
16453 The menu bar of terminal frames is treated specially as far as
16454 glyph matrices are concerned. Menu bar lines are not part of
16455 windows, so the update is done directly on the frame matrix rows
16456 for the menu bar. */
16457
16458 static void
16459 display_menu_bar (w)
16460 struct window *w;
16461 {
16462 struct frame *f = XFRAME (WINDOW_FRAME (w));
16463 struct it it;
16464 Lisp_Object items;
16465 int i;
16466
16467 /* Don't do all this for graphical frames. */
16468 #ifdef HAVE_NTGUI
16469 if (FRAME_W32_P (f))
16470 return;
16471 #endif
16472 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
16473 if (FRAME_X_P (f))
16474 return;
16475 #endif
16476 #ifdef MAC_OS
16477 if (FRAME_MAC_P (f))
16478 return;
16479 #endif
16480
16481 #ifdef USE_X_TOOLKIT
16482 xassert (!FRAME_WINDOW_P (f));
16483 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
16484 it.first_visible_x = 0;
16485 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16486 #else /* not USE_X_TOOLKIT */
16487 if (FRAME_WINDOW_P (f))
16488 {
16489 /* Menu bar lines are displayed in the desired matrix of the
16490 dummy window menu_bar_window. */
16491 struct window *menu_w;
16492 xassert (WINDOWP (f->menu_bar_window));
16493 menu_w = XWINDOW (f->menu_bar_window);
16494 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
16495 MENU_FACE_ID);
16496 it.first_visible_x = 0;
16497 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16498 }
16499 else
16500 {
16501 /* This is a TTY frame, i.e. character hpos/vpos are used as
16502 pixel x/y. */
16503 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
16504 MENU_FACE_ID);
16505 it.first_visible_x = 0;
16506 it.last_visible_x = FRAME_COLS (f);
16507 }
16508 #endif /* not USE_X_TOOLKIT */
16509
16510 if (! mode_line_inverse_video)
16511 /* Force the menu-bar to be displayed in the default face. */
16512 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16513
16514 /* Clear all rows of the menu bar. */
16515 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
16516 {
16517 struct glyph_row *row = it.glyph_row + i;
16518 clear_glyph_row (row);
16519 row->enabled_p = 1;
16520 row->full_width_p = 1;
16521 }
16522
16523 /* Display all items of the menu bar. */
16524 items = FRAME_MENU_BAR_ITEMS (it.f);
16525 for (i = 0; i < XVECTOR (items)->size; i += 4)
16526 {
16527 Lisp_Object string;
16528
16529 /* Stop at nil string. */
16530 string = AREF (items, i + 1);
16531 if (NILP (string))
16532 break;
16533
16534 /* Remember where item was displayed. */
16535 AREF (items, i + 3) = make_number (it.hpos);
16536
16537 /* Display the item, pad with one space. */
16538 if (it.current_x < it.last_visible_x)
16539 display_string (NULL, string, Qnil, 0, 0, &it,
16540 SCHARS (string) + 1, 0, 0, -1);
16541 }
16542
16543 /* Fill out the line with spaces. */
16544 if (it.current_x < it.last_visible_x)
16545 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
16546
16547 /* Compute the total height of the lines. */
16548 compute_line_metrics (&it);
16549 }
16550
16551
16552 \f
16553 /***********************************************************************
16554 Mode Line
16555 ***********************************************************************/
16556
16557 /* Redisplay mode lines in the window tree whose root is WINDOW. If
16558 FORCE is non-zero, redisplay mode lines unconditionally.
16559 Otherwise, redisplay only mode lines that are garbaged. Value is
16560 the number of windows whose mode lines were redisplayed. */
16561
16562 static int
16563 redisplay_mode_lines (window, force)
16564 Lisp_Object window;
16565 int force;
16566 {
16567 int nwindows = 0;
16568
16569 while (!NILP (window))
16570 {
16571 struct window *w = XWINDOW (window);
16572
16573 if (WINDOWP (w->hchild))
16574 nwindows += redisplay_mode_lines (w->hchild, force);
16575 else if (WINDOWP (w->vchild))
16576 nwindows += redisplay_mode_lines (w->vchild, force);
16577 else if (force
16578 || FRAME_GARBAGED_P (XFRAME (w->frame))
16579 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
16580 {
16581 struct text_pos lpoint;
16582 struct buffer *old = current_buffer;
16583
16584 /* Set the window's buffer for the mode line display. */
16585 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16586 set_buffer_internal_1 (XBUFFER (w->buffer));
16587
16588 /* Point refers normally to the selected window. For any
16589 other window, set up appropriate value. */
16590 if (!EQ (window, selected_window))
16591 {
16592 struct text_pos pt;
16593
16594 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
16595 if (CHARPOS (pt) < BEGV)
16596 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16597 else if (CHARPOS (pt) > (ZV - 1))
16598 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
16599 else
16600 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
16601 }
16602
16603 /* Display mode lines. */
16604 clear_glyph_matrix (w->desired_matrix);
16605 if (display_mode_lines (w))
16606 {
16607 ++nwindows;
16608 w->must_be_updated_p = 1;
16609 }
16610
16611 /* Restore old settings. */
16612 set_buffer_internal_1 (old);
16613 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16614 }
16615
16616 window = w->next;
16617 }
16618
16619 return nwindows;
16620 }
16621
16622
16623 /* Display the mode and/or top line of window W. Value is the number
16624 of mode lines displayed. */
16625
16626 static int
16627 display_mode_lines (w)
16628 struct window *w;
16629 {
16630 Lisp_Object old_selected_window, old_selected_frame;
16631 int n = 0;
16632
16633 old_selected_frame = selected_frame;
16634 selected_frame = w->frame;
16635 old_selected_window = selected_window;
16636 XSETWINDOW (selected_window, w);
16637
16638 /* These will be set while the mode line specs are processed. */
16639 line_number_displayed = 0;
16640 w->column_number_displayed = Qnil;
16641
16642 if (WINDOW_WANTS_MODELINE_P (w))
16643 {
16644 struct window *sel_w = XWINDOW (old_selected_window);
16645
16646 /* Select mode line face based on the real selected window. */
16647 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
16648 current_buffer->mode_line_format);
16649 ++n;
16650 }
16651
16652 if (WINDOW_WANTS_HEADER_LINE_P (w))
16653 {
16654 display_mode_line (w, HEADER_LINE_FACE_ID,
16655 current_buffer->header_line_format);
16656 ++n;
16657 }
16658
16659 selected_frame = old_selected_frame;
16660 selected_window = old_selected_window;
16661 return n;
16662 }
16663
16664
16665 /* Display mode or top line of window W. FACE_ID specifies which line
16666 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
16667 FORMAT is the mode line format to display. Value is the pixel
16668 height of the mode line displayed. */
16669
16670 static int
16671 display_mode_line (w, face_id, format)
16672 struct window *w;
16673 enum face_id face_id;
16674 Lisp_Object format;
16675 {
16676 struct it it;
16677 struct face *face;
16678 int count = SPECPDL_INDEX ();
16679
16680 init_iterator (&it, w, -1, -1, NULL, face_id);
16681 /* Don't extend on a previously drawn mode-line.
16682 This may happen if called from pos_visible_p. */
16683 it.glyph_row->enabled_p = 0;
16684 prepare_desired_row (it.glyph_row);
16685
16686 it.glyph_row->mode_line_p = 1;
16687
16688 if (! mode_line_inverse_video)
16689 /* Force the mode-line to be displayed in the default face. */
16690 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16691
16692 record_unwind_protect (unwind_format_mode_line,
16693 format_mode_line_unwind_data (NULL, 0));
16694
16695 mode_line_target = MODE_LINE_DISPLAY;
16696
16697 /* Temporarily make frame's keyboard the current kboard so that
16698 kboard-local variables in the mode_line_format will get the right
16699 values. */
16700 push_kboard (FRAME_KBOARD (it.f));
16701 record_unwind_save_match_data ();
16702 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16703 pop_kboard ();
16704
16705 unbind_to (count, Qnil);
16706
16707 /* Fill up with spaces. */
16708 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
16709
16710 compute_line_metrics (&it);
16711 it.glyph_row->full_width_p = 1;
16712 it.glyph_row->continued_p = 0;
16713 it.glyph_row->truncated_on_left_p = 0;
16714 it.glyph_row->truncated_on_right_p = 0;
16715
16716 /* Make a 3D mode-line have a shadow at its right end. */
16717 face = FACE_FROM_ID (it.f, face_id);
16718 extend_face_to_end_of_line (&it);
16719 if (face->box != FACE_NO_BOX)
16720 {
16721 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
16722 + it.glyph_row->used[TEXT_AREA] - 1);
16723 last->right_box_line_p = 1;
16724 }
16725
16726 return it.glyph_row->height;
16727 }
16728
16729 /* Move element ELT in LIST to the front of LIST.
16730 Return the updated list. */
16731
16732 static Lisp_Object
16733 move_elt_to_front (elt, list)
16734 Lisp_Object elt, list;
16735 {
16736 register Lisp_Object tail, prev;
16737 register Lisp_Object tem;
16738
16739 tail = list;
16740 prev = Qnil;
16741 while (CONSP (tail))
16742 {
16743 tem = XCAR (tail);
16744
16745 if (EQ (elt, tem))
16746 {
16747 /* Splice out the link TAIL. */
16748 if (NILP (prev))
16749 list = XCDR (tail);
16750 else
16751 Fsetcdr (prev, XCDR (tail));
16752
16753 /* Now make it the first. */
16754 Fsetcdr (tail, list);
16755 return tail;
16756 }
16757 else
16758 prev = tail;
16759 tail = XCDR (tail);
16760 QUIT;
16761 }
16762
16763 /* Not found--return unchanged LIST. */
16764 return list;
16765 }
16766
16767 /* Contribute ELT to the mode line for window IT->w. How it
16768 translates into text depends on its data type.
16769
16770 IT describes the display environment in which we display, as usual.
16771
16772 DEPTH is the depth in recursion. It is used to prevent
16773 infinite recursion here.
16774
16775 FIELD_WIDTH is the number of characters the display of ELT should
16776 occupy in the mode line, and PRECISION is the maximum number of
16777 characters to display from ELT's representation. See
16778 display_string for details.
16779
16780 Returns the hpos of the end of the text generated by ELT.
16781
16782 PROPS is a property list to add to any string we encounter.
16783
16784 If RISKY is nonzero, remove (disregard) any properties in any string
16785 we encounter, and ignore :eval and :propertize.
16786
16787 The global variable `mode_line_target' determines whether the
16788 output is passed to `store_mode_line_noprop',
16789 `store_mode_line_string', or `display_string'. */
16790
16791 static int
16792 display_mode_element (it, depth, field_width, precision, elt, props, risky)
16793 struct it *it;
16794 int depth;
16795 int field_width, precision;
16796 Lisp_Object elt, props;
16797 int risky;
16798 {
16799 int n = 0, field, prec;
16800 int literal = 0;
16801
16802 tail_recurse:
16803 if (depth > 100)
16804 elt = build_string ("*too-deep*");
16805
16806 depth++;
16807
16808 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
16809 {
16810 case Lisp_String:
16811 {
16812 /* A string: output it and check for %-constructs within it. */
16813 unsigned char c;
16814 int offset = 0;
16815
16816 if (SCHARS (elt) > 0
16817 && (!NILP (props) || risky))
16818 {
16819 Lisp_Object oprops, aelt;
16820 oprops = Ftext_properties_at (make_number (0), elt);
16821
16822 /* If the starting string's properties are not what
16823 we want, translate the string. Also, if the string
16824 is risky, do that anyway. */
16825
16826 if (NILP (Fequal (props, oprops)) || risky)
16827 {
16828 /* If the starting string has properties,
16829 merge the specified ones onto the existing ones. */
16830 if (! NILP (oprops) && !risky)
16831 {
16832 Lisp_Object tem;
16833
16834 oprops = Fcopy_sequence (oprops);
16835 tem = props;
16836 while (CONSP (tem))
16837 {
16838 oprops = Fplist_put (oprops, XCAR (tem),
16839 XCAR (XCDR (tem)));
16840 tem = XCDR (XCDR (tem));
16841 }
16842 props = oprops;
16843 }
16844
16845 aelt = Fassoc (elt, mode_line_proptrans_alist);
16846 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
16847 {
16848 /* AELT is what we want. Move it to the front
16849 without consing. */
16850 elt = XCAR (aelt);
16851 mode_line_proptrans_alist
16852 = move_elt_to_front (aelt, mode_line_proptrans_alist);
16853 }
16854 else
16855 {
16856 Lisp_Object tem;
16857
16858 /* If AELT has the wrong props, it is useless.
16859 so get rid of it. */
16860 if (! NILP (aelt))
16861 mode_line_proptrans_alist
16862 = Fdelq (aelt, mode_line_proptrans_alist);
16863
16864 elt = Fcopy_sequence (elt);
16865 Fset_text_properties (make_number (0), Flength (elt),
16866 props, elt);
16867 /* Add this item to mode_line_proptrans_alist. */
16868 mode_line_proptrans_alist
16869 = Fcons (Fcons (elt, props),
16870 mode_line_proptrans_alist);
16871 /* Truncate mode_line_proptrans_alist
16872 to at most 50 elements. */
16873 tem = Fnthcdr (make_number (50),
16874 mode_line_proptrans_alist);
16875 if (! NILP (tem))
16876 XSETCDR (tem, Qnil);
16877 }
16878 }
16879 }
16880
16881 offset = 0;
16882
16883 if (literal)
16884 {
16885 prec = precision - n;
16886 switch (mode_line_target)
16887 {
16888 case MODE_LINE_NOPROP:
16889 case MODE_LINE_TITLE:
16890 n += store_mode_line_noprop (SDATA (elt), -1, prec);
16891 break;
16892 case MODE_LINE_STRING:
16893 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
16894 break;
16895 case MODE_LINE_DISPLAY:
16896 n += display_string (NULL, elt, Qnil, 0, 0, it,
16897 0, prec, 0, STRING_MULTIBYTE (elt));
16898 break;
16899 }
16900
16901 break;
16902 }
16903
16904 /* Handle the non-literal case. */
16905
16906 while ((precision <= 0 || n < precision)
16907 && SREF (elt, offset) != 0
16908 && (mode_line_target != MODE_LINE_DISPLAY
16909 || it->current_x < it->last_visible_x))
16910 {
16911 int last_offset = offset;
16912
16913 /* Advance to end of string or next format specifier. */
16914 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
16915 ;
16916
16917 if (offset - 1 != last_offset)
16918 {
16919 int nchars, nbytes;
16920
16921 /* Output to end of string or up to '%'. Field width
16922 is length of string. Don't output more than
16923 PRECISION allows us. */
16924 offset--;
16925
16926 prec = c_string_width (SDATA (elt) + last_offset,
16927 offset - last_offset, precision - n,
16928 &nchars, &nbytes);
16929
16930 switch (mode_line_target)
16931 {
16932 case MODE_LINE_NOPROP:
16933 case MODE_LINE_TITLE:
16934 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
16935 break;
16936 case MODE_LINE_STRING:
16937 {
16938 int bytepos = last_offset;
16939 int charpos = string_byte_to_char (elt, bytepos);
16940 int endpos = (precision <= 0
16941 ? string_byte_to_char (elt, offset)
16942 : charpos + nchars);
16943
16944 n += store_mode_line_string (NULL,
16945 Fsubstring (elt, make_number (charpos),
16946 make_number (endpos)),
16947 0, 0, 0, Qnil);
16948 }
16949 break;
16950 case MODE_LINE_DISPLAY:
16951 {
16952 int bytepos = last_offset;
16953 int charpos = string_byte_to_char (elt, bytepos);
16954
16955 if (precision <= 0)
16956 nchars = string_byte_to_char (elt, offset) - charpos;
16957 n += display_string (NULL, elt, Qnil, 0, charpos,
16958 it, 0, nchars, 0,
16959 STRING_MULTIBYTE (elt));
16960 }
16961 break;
16962 }
16963 }
16964 else /* c == '%' */
16965 {
16966 int percent_position = offset;
16967
16968 /* Get the specified minimum width. Zero means
16969 don't pad. */
16970 field = 0;
16971 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
16972 field = field * 10 + c - '0';
16973
16974 /* Don't pad beyond the total padding allowed. */
16975 if (field_width - n > 0 && field > field_width - n)
16976 field = field_width - n;
16977
16978 /* Note that either PRECISION <= 0 or N < PRECISION. */
16979 prec = precision - n;
16980
16981 if (c == 'M')
16982 n += display_mode_element (it, depth, field, prec,
16983 Vglobal_mode_string, props,
16984 risky);
16985 else if (c != 0)
16986 {
16987 int multibyte;
16988 int bytepos, charpos;
16989 unsigned char *spec;
16990
16991 bytepos = percent_position;
16992 charpos = (STRING_MULTIBYTE (elt)
16993 ? string_byte_to_char (elt, bytepos)
16994 : bytepos);
16995
16996 spec
16997 = decode_mode_spec (it->w, c, field, prec, &multibyte);
16998
16999 switch (mode_line_target)
17000 {
17001 case MODE_LINE_NOPROP:
17002 case MODE_LINE_TITLE:
17003 n += store_mode_line_noprop (spec, field, prec);
17004 break;
17005 case MODE_LINE_STRING:
17006 {
17007 int len = strlen (spec);
17008 Lisp_Object tem = make_string (spec, len);
17009 props = Ftext_properties_at (make_number (charpos), elt);
17010 /* Should only keep face property in props */
17011 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
17012 }
17013 break;
17014 case MODE_LINE_DISPLAY:
17015 {
17016 int nglyphs_before, nwritten;
17017
17018 nglyphs_before = it->glyph_row->used[TEXT_AREA];
17019 nwritten = display_string (spec, Qnil, elt,
17020 charpos, 0, it,
17021 field, prec, 0,
17022 multibyte);
17023
17024 /* Assign to the glyphs written above the
17025 string where the `%x' came from, position
17026 of the `%'. */
17027 if (nwritten > 0)
17028 {
17029 struct glyph *glyph
17030 = (it->glyph_row->glyphs[TEXT_AREA]
17031 + nglyphs_before);
17032 int i;
17033
17034 for (i = 0; i < nwritten; ++i)
17035 {
17036 glyph[i].object = elt;
17037 glyph[i].charpos = charpos;
17038 }
17039
17040 n += nwritten;
17041 }
17042 }
17043 break;
17044 }
17045 }
17046 else /* c == 0 */
17047 break;
17048 }
17049 }
17050 }
17051 break;
17052
17053 case Lisp_Symbol:
17054 /* A symbol: process the value of the symbol recursively
17055 as if it appeared here directly. Avoid error if symbol void.
17056 Special case: if value of symbol is a string, output the string
17057 literally. */
17058 {
17059 register Lisp_Object tem;
17060
17061 /* If the variable is not marked as risky to set
17062 then its contents are risky to use. */
17063 if (NILP (Fget (elt, Qrisky_local_variable)))
17064 risky = 1;
17065
17066 tem = Fboundp (elt);
17067 if (!NILP (tem))
17068 {
17069 tem = Fsymbol_value (elt);
17070 /* If value is a string, output that string literally:
17071 don't check for % within it. */
17072 if (STRINGP (tem))
17073 literal = 1;
17074
17075 if (!EQ (tem, elt))
17076 {
17077 /* Give up right away for nil or t. */
17078 elt = tem;
17079 goto tail_recurse;
17080 }
17081 }
17082 }
17083 break;
17084
17085 case Lisp_Cons:
17086 {
17087 register Lisp_Object car, tem;
17088
17089 /* A cons cell: five distinct cases.
17090 If first element is :eval or :propertize, do something special.
17091 If first element is a string or a cons, process all the elements
17092 and effectively concatenate them.
17093 If first element is a negative number, truncate displaying cdr to
17094 at most that many characters. If positive, pad (with spaces)
17095 to at least that many characters.
17096 If first element is a symbol, process the cadr or caddr recursively
17097 according to whether the symbol's value is non-nil or nil. */
17098 car = XCAR (elt);
17099 if (EQ (car, QCeval))
17100 {
17101 /* An element of the form (:eval FORM) means evaluate FORM
17102 and use the result as mode line elements. */
17103
17104 if (risky)
17105 break;
17106
17107 if (CONSP (XCDR (elt)))
17108 {
17109 Lisp_Object spec;
17110 spec = safe_eval (XCAR (XCDR (elt)));
17111 n += display_mode_element (it, depth, field_width - n,
17112 precision - n, spec, props,
17113 risky);
17114 }
17115 }
17116 else if (EQ (car, QCpropertize))
17117 {
17118 /* An element of the form (:propertize ELT PROPS...)
17119 means display ELT but applying properties PROPS. */
17120
17121 if (risky)
17122 break;
17123
17124 if (CONSP (XCDR (elt)))
17125 n += display_mode_element (it, depth, field_width - n,
17126 precision - n, XCAR (XCDR (elt)),
17127 XCDR (XCDR (elt)), risky);
17128 }
17129 else if (SYMBOLP (car))
17130 {
17131 tem = Fboundp (car);
17132 elt = XCDR (elt);
17133 if (!CONSP (elt))
17134 goto invalid;
17135 /* elt is now the cdr, and we know it is a cons cell.
17136 Use its car if CAR has a non-nil value. */
17137 if (!NILP (tem))
17138 {
17139 tem = Fsymbol_value (car);
17140 if (!NILP (tem))
17141 {
17142 elt = XCAR (elt);
17143 goto tail_recurse;
17144 }
17145 }
17146 /* Symbol's value is nil (or symbol is unbound)
17147 Get the cddr of the original list
17148 and if possible find the caddr and use that. */
17149 elt = XCDR (elt);
17150 if (NILP (elt))
17151 break;
17152 else if (!CONSP (elt))
17153 goto invalid;
17154 elt = XCAR (elt);
17155 goto tail_recurse;
17156 }
17157 else if (INTEGERP (car))
17158 {
17159 register int lim = XINT (car);
17160 elt = XCDR (elt);
17161 if (lim < 0)
17162 {
17163 /* Negative int means reduce maximum width. */
17164 if (precision <= 0)
17165 precision = -lim;
17166 else
17167 precision = min (precision, -lim);
17168 }
17169 else if (lim > 0)
17170 {
17171 /* Padding specified. Don't let it be more than
17172 current maximum. */
17173 if (precision > 0)
17174 lim = min (precision, lim);
17175
17176 /* If that's more padding than already wanted, queue it.
17177 But don't reduce padding already specified even if
17178 that is beyond the current truncation point. */
17179 field_width = max (lim, field_width);
17180 }
17181 goto tail_recurse;
17182 }
17183 else if (STRINGP (car) || CONSP (car))
17184 {
17185 register int limit = 50;
17186 /* Limit is to protect against circular lists. */
17187 while (CONSP (elt)
17188 && --limit > 0
17189 && (precision <= 0 || n < precision))
17190 {
17191 n += display_mode_element (it, depth,
17192 /* Do padding only after the last
17193 element in the list. */
17194 (! CONSP (XCDR (elt))
17195 ? field_width - n
17196 : 0),
17197 precision - n, XCAR (elt),
17198 props, risky);
17199 elt = XCDR (elt);
17200 }
17201 }
17202 }
17203 break;
17204
17205 default:
17206 invalid:
17207 elt = build_string ("*invalid*");
17208 goto tail_recurse;
17209 }
17210
17211 /* Pad to FIELD_WIDTH. */
17212 if (field_width > 0 && n < field_width)
17213 {
17214 switch (mode_line_target)
17215 {
17216 case MODE_LINE_NOPROP:
17217 case MODE_LINE_TITLE:
17218 n += store_mode_line_noprop ("", field_width - n, 0);
17219 break;
17220 case MODE_LINE_STRING:
17221 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
17222 break;
17223 case MODE_LINE_DISPLAY:
17224 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
17225 0, 0, 0);
17226 break;
17227 }
17228 }
17229
17230 return n;
17231 }
17232
17233 /* Store a mode-line string element in mode_line_string_list.
17234
17235 If STRING is non-null, display that C string. Otherwise, the Lisp
17236 string LISP_STRING is displayed.
17237
17238 FIELD_WIDTH is the minimum number of output glyphs to produce.
17239 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17240 with spaces. FIELD_WIDTH <= 0 means don't pad.
17241
17242 PRECISION is the maximum number of characters to output from
17243 STRING. PRECISION <= 0 means don't truncate the string.
17244
17245 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
17246 properties to the string.
17247
17248 PROPS are the properties to add to the string.
17249 The mode_line_string_face face property is always added to the string.
17250 */
17251
17252 static int
17253 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
17254 char *string;
17255 Lisp_Object lisp_string;
17256 int copy_string;
17257 int field_width;
17258 int precision;
17259 Lisp_Object props;
17260 {
17261 int len;
17262 int n = 0;
17263
17264 if (string != NULL)
17265 {
17266 len = strlen (string);
17267 if (precision > 0 && len > precision)
17268 len = precision;
17269 lisp_string = make_string (string, len);
17270 if (NILP (props))
17271 props = mode_line_string_face_prop;
17272 else if (!NILP (mode_line_string_face))
17273 {
17274 Lisp_Object face = Fplist_get (props, Qface);
17275 props = Fcopy_sequence (props);
17276 if (NILP (face))
17277 face = mode_line_string_face;
17278 else
17279 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17280 props = Fplist_put (props, Qface, face);
17281 }
17282 Fadd_text_properties (make_number (0), make_number (len),
17283 props, lisp_string);
17284 }
17285 else
17286 {
17287 len = XFASTINT (Flength (lisp_string));
17288 if (precision > 0 && len > precision)
17289 {
17290 len = precision;
17291 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
17292 precision = -1;
17293 }
17294 if (!NILP (mode_line_string_face))
17295 {
17296 Lisp_Object face;
17297 if (NILP (props))
17298 props = Ftext_properties_at (make_number (0), lisp_string);
17299 face = Fplist_get (props, Qface);
17300 if (NILP (face))
17301 face = mode_line_string_face;
17302 else
17303 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17304 props = Fcons (Qface, Fcons (face, Qnil));
17305 if (copy_string)
17306 lisp_string = Fcopy_sequence (lisp_string);
17307 }
17308 if (!NILP (props))
17309 Fadd_text_properties (make_number (0), make_number (len),
17310 props, lisp_string);
17311 }
17312
17313 if (len > 0)
17314 {
17315 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17316 n += len;
17317 }
17318
17319 if (field_width > len)
17320 {
17321 field_width -= len;
17322 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
17323 if (!NILP (props))
17324 Fadd_text_properties (make_number (0), make_number (field_width),
17325 props, lisp_string);
17326 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17327 n += field_width;
17328 }
17329
17330 return n;
17331 }
17332
17333
17334 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
17335 1, 4, 0,
17336 doc: /* Format a string out of a mode line format specification.
17337 First arg FORMAT specifies the mode line format (see `mode-line-format'
17338 for details) to use.
17339
17340 Optional second arg FACE specifies the face property to put
17341 on all characters for which no face is specified.
17342 The value t means whatever face the window's mode line currently uses
17343 \(either `mode-line' or `mode-line-inactive', depending).
17344 A value of nil means the default is no face property.
17345 If FACE is an integer, the value string has no text properties.
17346
17347 Optional third and fourth args WINDOW and BUFFER specify the window
17348 and buffer to use as the context for the formatting (defaults
17349 are the selected window and the window's buffer). */)
17350 (format, face, window, buffer)
17351 Lisp_Object format, face, window, buffer;
17352 {
17353 struct it it;
17354 int len;
17355 struct window *w;
17356 struct buffer *old_buffer = NULL;
17357 int face_id = -1;
17358 int no_props = INTEGERP (face);
17359 int count = SPECPDL_INDEX ();
17360 Lisp_Object str;
17361 int string_start = 0;
17362
17363 if (NILP (window))
17364 window = selected_window;
17365 CHECK_WINDOW (window);
17366 w = XWINDOW (window);
17367
17368 if (NILP (buffer))
17369 buffer = w->buffer;
17370 CHECK_BUFFER (buffer);
17371
17372 if (NILP (format))
17373 return empty_unibyte_string;
17374
17375 if (no_props)
17376 face = Qnil;
17377
17378 if (!NILP (face))
17379 {
17380 if (EQ (face, Qt))
17381 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
17382 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
17383 }
17384
17385 if (face_id < 0)
17386 face_id = DEFAULT_FACE_ID;
17387
17388 if (XBUFFER (buffer) != current_buffer)
17389 old_buffer = current_buffer;
17390
17391 /* Save things including mode_line_proptrans_alist,
17392 and set that to nil so that we don't alter the outer value. */
17393 record_unwind_protect (unwind_format_mode_line,
17394 format_mode_line_unwind_data (old_buffer, 1));
17395 mode_line_proptrans_alist = Qnil;
17396
17397 if (old_buffer)
17398 set_buffer_internal_1 (XBUFFER (buffer));
17399
17400 init_iterator (&it, w, -1, -1, NULL, face_id);
17401
17402 if (no_props)
17403 {
17404 mode_line_target = MODE_LINE_NOPROP;
17405 mode_line_string_face_prop = Qnil;
17406 mode_line_string_list = Qnil;
17407 string_start = MODE_LINE_NOPROP_LEN (0);
17408 }
17409 else
17410 {
17411 mode_line_target = MODE_LINE_STRING;
17412 mode_line_string_list = Qnil;
17413 mode_line_string_face = face;
17414 mode_line_string_face_prop
17415 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
17416 }
17417
17418 push_kboard (FRAME_KBOARD (it.f));
17419 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
17420 pop_kboard ();
17421
17422 if (no_props)
17423 {
17424 len = MODE_LINE_NOPROP_LEN (string_start);
17425 str = make_string (mode_line_noprop_buf + string_start, len);
17426 }
17427 else
17428 {
17429 mode_line_string_list = Fnreverse (mode_line_string_list);
17430 str = Fmapconcat (intern ("identity"), mode_line_string_list,
17431 empty_unibyte_string);
17432 }
17433
17434 unbind_to (count, Qnil);
17435 return str;
17436 }
17437
17438 /* Write a null-terminated, right justified decimal representation of
17439 the positive integer D to BUF using a minimal field width WIDTH. */
17440
17441 static void
17442 pint2str (buf, width, d)
17443 register char *buf;
17444 register int width;
17445 register int d;
17446 {
17447 register char *p = buf;
17448
17449 if (d <= 0)
17450 *p++ = '0';
17451 else
17452 {
17453 while (d > 0)
17454 {
17455 *p++ = d % 10 + '0';
17456 d /= 10;
17457 }
17458 }
17459
17460 for (width -= (int) (p - buf); width > 0; --width)
17461 *p++ = ' ';
17462 *p-- = '\0';
17463 while (p > buf)
17464 {
17465 d = *buf;
17466 *buf++ = *p;
17467 *p-- = d;
17468 }
17469 }
17470
17471 /* Write a null-terminated, right justified decimal and "human
17472 readable" representation of the nonnegative integer D to BUF using
17473 a minimal field width WIDTH. D should be smaller than 999.5e24. */
17474
17475 static const char power_letter[] =
17476 {
17477 0, /* not used */
17478 'k', /* kilo */
17479 'M', /* mega */
17480 'G', /* giga */
17481 'T', /* tera */
17482 'P', /* peta */
17483 'E', /* exa */
17484 'Z', /* zetta */
17485 'Y' /* yotta */
17486 };
17487
17488 static void
17489 pint2hrstr (buf, width, d)
17490 char *buf;
17491 int width;
17492 int d;
17493 {
17494 /* We aim to represent the nonnegative integer D as
17495 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
17496 int quotient = d;
17497 int remainder = 0;
17498 /* -1 means: do not use TENTHS. */
17499 int tenths = -1;
17500 int exponent = 0;
17501
17502 /* Length of QUOTIENT.TENTHS as a string. */
17503 int length;
17504
17505 char * psuffix;
17506 char * p;
17507
17508 if (1000 <= quotient)
17509 {
17510 /* Scale to the appropriate EXPONENT. */
17511 do
17512 {
17513 remainder = quotient % 1000;
17514 quotient /= 1000;
17515 exponent++;
17516 }
17517 while (1000 <= quotient);
17518
17519 /* Round to nearest and decide whether to use TENTHS or not. */
17520 if (quotient <= 9)
17521 {
17522 tenths = remainder / 100;
17523 if (50 <= remainder % 100)
17524 {
17525 if (tenths < 9)
17526 tenths++;
17527 else
17528 {
17529 quotient++;
17530 if (quotient == 10)
17531 tenths = -1;
17532 else
17533 tenths = 0;
17534 }
17535 }
17536 }
17537 else
17538 if (500 <= remainder)
17539 {
17540 if (quotient < 999)
17541 quotient++;
17542 else
17543 {
17544 quotient = 1;
17545 exponent++;
17546 tenths = 0;
17547 }
17548 }
17549 }
17550
17551 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
17552 if (tenths == -1 && quotient <= 99)
17553 if (quotient <= 9)
17554 length = 1;
17555 else
17556 length = 2;
17557 else
17558 length = 3;
17559 p = psuffix = buf + max (width, length);
17560
17561 /* Print EXPONENT. */
17562 if (exponent)
17563 *psuffix++ = power_letter[exponent];
17564 *psuffix = '\0';
17565
17566 /* Print TENTHS. */
17567 if (tenths >= 0)
17568 {
17569 *--p = '0' + tenths;
17570 *--p = '.';
17571 }
17572
17573 /* Print QUOTIENT. */
17574 do
17575 {
17576 int digit = quotient % 10;
17577 *--p = '0' + digit;
17578 }
17579 while ((quotient /= 10) != 0);
17580
17581 /* Print leading spaces. */
17582 while (buf < p)
17583 *--p = ' ';
17584 }
17585
17586 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
17587 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
17588 type of CODING_SYSTEM. Return updated pointer into BUF. */
17589
17590 static unsigned char invalid_eol_type[] = "(*invalid*)";
17591
17592 static char *
17593 decode_mode_spec_coding (coding_system, buf, eol_flag)
17594 Lisp_Object coding_system;
17595 register char *buf;
17596 int eol_flag;
17597 {
17598 Lisp_Object val;
17599 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
17600 const unsigned char *eol_str;
17601 int eol_str_len;
17602 /* The EOL conversion we are using. */
17603 Lisp_Object eoltype;
17604
17605 val = Fget (coding_system, Qcoding_system);
17606 eoltype = Qnil;
17607
17608 if (!VECTORP (val)) /* Not yet decided. */
17609 {
17610 if (multibyte)
17611 *buf++ = '-';
17612 if (eol_flag)
17613 eoltype = eol_mnemonic_undecided;
17614 /* Don't mention EOL conversion if it isn't decided. */
17615 }
17616 else
17617 {
17618 Lisp_Object eolvalue;
17619
17620 eolvalue = Fget (coding_system, Qeol_type);
17621
17622 if (multibyte)
17623 *buf++ = XFASTINT (AREF (val, 1));
17624
17625 if (eol_flag)
17626 {
17627 /* The EOL conversion that is normal on this system. */
17628
17629 if (NILP (eolvalue)) /* Not yet decided. */
17630 eoltype = eol_mnemonic_undecided;
17631 else if (VECTORP (eolvalue)) /* Not yet decided. */
17632 eoltype = eol_mnemonic_undecided;
17633 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
17634 eoltype = (XFASTINT (eolvalue) == 0
17635 ? eol_mnemonic_unix
17636 : (XFASTINT (eolvalue) == 1
17637 ? eol_mnemonic_dos : eol_mnemonic_mac));
17638 }
17639 }
17640
17641 if (eol_flag)
17642 {
17643 /* Mention the EOL conversion if it is not the usual one. */
17644 if (STRINGP (eoltype))
17645 {
17646 eol_str = SDATA (eoltype);
17647 eol_str_len = SBYTES (eoltype);
17648 }
17649 else if (INTEGERP (eoltype)
17650 && CHAR_VALID_P (XINT (eoltype), 0))
17651 {
17652 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
17653 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
17654 eol_str = tmp;
17655 }
17656 else
17657 {
17658 eol_str = invalid_eol_type;
17659 eol_str_len = sizeof (invalid_eol_type) - 1;
17660 }
17661 bcopy (eol_str, buf, eol_str_len);
17662 buf += eol_str_len;
17663 }
17664
17665 return buf;
17666 }
17667
17668 /* Return a string for the output of a mode line %-spec for window W,
17669 generated by character C. PRECISION >= 0 means don't return a
17670 string longer than that value. FIELD_WIDTH > 0 means pad the
17671 string returned with spaces to that value. Return 1 in *MULTIBYTE
17672 if the result is multibyte text.
17673
17674 Note we operate on the current buffer for most purposes,
17675 the exception being w->base_line_pos. */
17676
17677 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
17678
17679 static char *
17680 decode_mode_spec (w, c, field_width, precision, multibyte)
17681 struct window *w;
17682 register int c;
17683 int field_width, precision;
17684 int *multibyte;
17685 {
17686 Lisp_Object obj;
17687 struct frame *f = XFRAME (WINDOW_FRAME (w));
17688 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
17689 struct buffer *b = current_buffer;
17690
17691 obj = Qnil;
17692 *multibyte = 0;
17693
17694 switch (c)
17695 {
17696 case '*':
17697 if (!NILP (b->read_only))
17698 return "%";
17699 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17700 return "*";
17701 return "-";
17702
17703 case '+':
17704 /* This differs from %* only for a modified read-only buffer. */
17705 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17706 return "*";
17707 if (!NILP (b->read_only))
17708 return "%";
17709 return "-";
17710
17711 case '&':
17712 /* This differs from %* in ignoring read-only-ness. */
17713 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17714 return "*";
17715 return "-";
17716
17717 case '%':
17718 return "%";
17719
17720 case '[':
17721 {
17722 int i;
17723 char *p;
17724
17725 if (command_loop_level > 5)
17726 return "[[[... ";
17727 p = decode_mode_spec_buf;
17728 for (i = 0; i < command_loop_level; i++)
17729 *p++ = '[';
17730 *p = 0;
17731 return decode_mode_spec_buf;
17732 }
17733
17734 case ']':
17735 {
17736 int i;
17737 char *p;
17738
17739 if (command_loop_level > 5)
17740 return " ...]]]";
17741 p = decode_mode_spec_buf;
17742 for (i = 0; i < command_loop_level; i++)
17743 *p++ = ']';
17744 *p = 0;
17745 return decode_mode_spec_buf;
17746 }
17747
17748 case '-':
17749 {
17750 register int i;
17751
17752 /* Let lots_of_dashes be a string of infinite length. */
17753 if (mode_line_target == MODE_LINE_NOPROP ||
17754 mode_line_target == MODE_LINE_STRING)
17755 return "--";
17756 if (field_width <= 0
17757 || field_width > sizeof (lots_of_dashes))
17758 {
17759 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
17760 decode_mode_spec_buf[i] = '-';
17761 decode_mode_spec_buf[i] = '\0';
17762 return decode_mode_spec_buf;
17763 }
17764 else
17765 return lots_of_dashes;
17766 }
17767
17768 case 'b':
17769 obj = b->name;
17770 break;
17771
17772 case 'c':
17773 /* %c and %l are ignored in `frame-title-format'.
17774 (In redisplay_internal, the frame title is drawn _before_ the
17775 windows are updated, so the stuff which depends on actual
17776 window contents (such as %l) may fail to render properly, or
17777 even crash emacs.) */
17778 if (mode_line_target == MODE_LINE_TITLE)
17779 return "";
17780 else
17781 {
17782 int col = (int) current_column (); /* iftc */
17783 w->column_number_displayed = make_number (col);
17784 pint2str (decode_mode_spec_buf, field_width, col);
17785 return decode_mode_spec_buf;
17786 }
17787
17788 case 'e':
17789 #ifndef SYSTEM_MALLOC
17790 {
17791 if (NILP (Vmemory_full))
17792 return "";
17793 else
17794 return "!MEM FULL! ";
17795 }
17796 #else
17797 return "";
17798 #endif
17799
17800 case 'F':
17801 /* %F displays the frame name. */
17802 if (!NILP (f->title))
17803 return (char *) SDATA (f->title);
17804 if (f->explicit_name || ! FRAME_WINDOW_P (f))
17805 return (char *) SDATA (f->name);
17806 return "Emacs";
17807
17808 case 'f':
17809 obj = b->filename;
17810 break;
17811
17812 case 'i':
17813 {
17814 int size = ZV - BEGV;
17815 pint2str (decode_mode_spec_buf, field_width, size);
17816 return decode_mode_spec_buf;
17817 }
17818
17819 case 'I':
17820 {
17821 int size = ZV - BEGV;
17822 pint2hrstr (decode_mode_spec_buf, field_width, size);
17823 return decode_mode_spec_buf;
17824 }
17825
17826 case 'l':
17827 {
17828 int startpos, startpos_byte, line, linepos, linepos_byte;
17829 int topline, nlines, junk, height;
17830
17831 /* %c and %l are ignored in `frame-title-format'. */
17832 if (mode_line_target == MODE_LINE_TITLE)
17833 return "";
17834
17835 startpos = XMARKER (w->start)->charpos;
17836 startpos_byte = marker_byte_position (w->start);
17837 height = WINDOW_TOTAL_LINES (w);
17838
17839 /* If we decided that this buffer isn't suitable for line numbers,
17840 don't forget that too fast. */
17841 if (EQ (w->base_line_pos, w->buffer))
17842 goto no_value;
17843 /* But do forget it, if the window shows a different buffer now. */
17844 else if (BUFFERP (w->base_line_pos))
17845 w->base_line_pos = Qnil;
17846
17847 /* If the buffer is very big, don't waste time. */
17848 if (INTEGERP (Vline_number_display_limit)
17849 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
17850 {
17851 w->base_line_pos = Qnil;
17852 w->base_line_number = Qnil;
17853 goto no_value;
17854 }
17855
17856 if (!NILP (w->base_line_number)
17857 && !NILP (w->base_line_pos)
17858 && XFASTINT (w->base_line_pos) <= startpos)
17859 {
17860 line = XFASTINT (w->base_line_number);
17861 linepos = XFASTINT (w->base_line_pos);
17862 linepos_byte = buf_charpos_to_bytepos (b, linepos);
17863 }
17864 else
17865 {
17866 line = 1;
17867 linepos = BUF_BEGV (b);
17868 linepos_byte = BUF_BEGV_BYTE (b);
17869 }
17870
17871 /* Count lines from base line to window start position. */
17872 nlines = display_count_lines (linepos, linepos_byte,
17873 startpos_byte,
17874 startpos, &junk);
17875
17876 topline = nlines + line;
17877
17878 /* Determine a new base line, if the old one is too close
17879 or too far away, or if we did not have one.
17880 "Too close" means it's plausible a scroll-down would
17881 go back past it. */
17882 if (startpos == BUF_BEGV (b))
17883 {
17884 w->base_line_number = make_number (topline);
17885 w->base_line_pos = make_number (BUF_BEGV (b));
17886 }
17887 else if (nlines < height + 25 || nlines > height * 3 + 50
17888 || linepos == BUF_BEGV (b))
17889 {
17890 int limit = BUF_BEGV (b);
17891 int limit_byte = BUF_BEGV_BYTE (b);
17892 int position;
17893 int distance = (height * 2 + 30) * line_number_display_limit_width;
17894
17895 if (startpos - distance > limit)
17896 {
17897 limit = startpos - distance;
17898 limit_byte = CHAR_TO_BYTE (limit);
17899 }
17900
17901 nlines = display_count_lines (startpos, startpos_byte,
17902 limit_byte,
17903 - (height * 2 + 30),
17904 &position);
17905 /* If we couldn't find the lines we wanted within
17906 line_number_display_limit_width chars per line,
17907 give up on line numbers for this window. */
17908 if (position == limit_byte && limit == startpos - distance)
17909 {
17910 w->base_line_pos = w->buffer;
17911 w->base_line_number = Qnil;
17912 goto no_value;
17913 }
17914
17915 w->base_line_number = make_number (topline - nlines);
17916 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
17917 }
17918
17919 /* Now count lines from the start pos to point. */
17920 nlines = display_count_lines (startpos, startpos_byte,
17921 PT_BYTE, PT, &junk);
17922
17923 /* Record that we did display the line number. */
17924 line_number_displayed = 1;
17925
17926 /* Make the string to show. */
17927 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
17928 return decode_mode_spec_buf;
17929 no_value:
17930 {
17931 char* p = decode_mode_spec_buf;
17932 int pad = field_width - 2;
17933 while (pad-- > 0)
17934 *p++ = ' ';
17935 *p++ = '?';
17936 *p++ = '?';
17937 *p = '\0';
17938 return decode_mode_spec_buf;
17939 }
17940 }
17941 break;
17942
17943 case 'm':
17944 obj = b->mode_name;
17945 break;
17946
17947 case 'n':
17948 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
17949 return " Narrow";
17950 break;
17951
17952 case 'p':
17953 {
17954 int pos = marker_position (w->start);
17955 int total = BUF_ZV (b) - BUF_BEGV (b);
17956
17957 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
17958 {
17959 if (pos <= BUF_BEGV (b))
17960 return "All";
17961 else
17962 return "Bottom";
17963 }
17964 else if (pos <= BUF_BEGV (b))
17965 return "Top";
17966 else
17967 {
17968 if (total > 1000000)
17969 /* Do it differently for a large value, to avoid overflow. */
17970 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
17971 else
17972 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
17973 /* We can't normally display a 3-digit number,
17974 so get us a 2-digit number that is close. */
17975 if (total == 100)
17976 total = 99;
17977 sprintf (decode_mode_spec_buf, "%2d%%", total);
17978 return decode_mode_spec_buf;
17979 }
17980 }
17981
17982 /* Display percentage of size above the bottom of the screen. */
17983 case 'P':
17984 {
17985 int toppos = marker_position (w->start);
17986 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
17987 int total = BUF_ZV (b) - BUF_BEGV (b);
17988
17989 if (botpos >= BUF_ZV (b))
17990 {
17991 if (toppos <= BUF_BEGV (b))
17992 return "All";
17993 else
17994 return "Bottom";
17995 }
17996 else
17997 {
17998 if (total > 1000000)
17999 /* Do it differently for a large value, to avoid overflow. */
18000 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18001 else
18002 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
18003 /* We can't normally display a 3-digit number,
18004 so get us a 2-digit number that is close. */
18005 if (total == 100)
18006 total = 99;
18007 if (toppos <= BUF_BEGV (b))
18008 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
18009 else
18010 sprintf (decode_mode_spec_buf, "%2d%%", total);
18011 return decode_mode_spec_buf;
18012 }
18013 }
18014
18015 case 's':
18016 /* status of process */
18017 obj = Fget_buffer_process (Fcurrent_buffer ());
18018 if (NILP (obj))
18019 return "no process";
18020 #ifdef subprocesses
18021 obj = Fsymbol_name (Fprocess_status (obj));
18022 #endif
18023 break;
18024
18025 case '@':
18026 {
18027 Lisp_Object val;
18028 val = call1 (intern ("file-remote-p"), current_buffer->directory);
18029 if (NILP (val))
18030 return "-";
18031 else
18032 return "@";
18033 }
18034
18035 case 't': /* indicate TEXT or BINARY */
18036 #ifdef MODE_LINE_BINARY_TEXT
18037 return MODE_LINE_BINARY_TEXT (b);
18038 #else
18039 return "T";
18040 #endif
18041
18042 case 'z':
18043 /* coding-system (not including end-of-line format) */
18044 case 'Z':
18045 /* coding-system (including end-of-line type) */
18046 {
18047 int eol_flag = (c == 'Z');
18048 char *p = decode_mode_spec_buf;
18049
18050 if (! FRAME_WINDOW_P (f))
18051 {
18052 /* No need to mention EOL here--the terminal never needs
18053 to do EOL conversion. */
18054 p = decode_mode_spec_coding (FRAME_KEYBOARD_CODING (f)->symbol, p, 0);
18055 p = decode_mode_spec_coding (FRAME_TERMINAL_CODING (f)->symbol, p, 0);
18056 }
18057 p = decode_mode_spec_coding (b->buffer_file_coding_system,
18058 p, eol_flag);
18059
18060 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
18061 #ifdef subprocesses
18062 obj = Fget_buffer_process (Fcurrent_buffer ());
18063 if (PROCESSP (obj))
18064 {
18065 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
18066 p, eol_flag);
18067 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
18068 p, eol_flag);
18069 }
18070 #endif /* subprocesses */
18071 #endif /* 0 */
18072 *p = 0;
18073 return decode_mode_spec_buf;
18074 }
18075 }
18076
18077 if (STRINGP (obj))
18078 {
18079 *multibyte = STRING_MULTIBYTE (obj);
18080 return (char *) SDATA (obj);
18081 }
18082 else
18083 return "";
18084 }
18085
18086
18087 /* Count up to COUNT lines starting from START / START_BYTE.
18088 But don't go beyond LIMIT_BYTE.
18089 Return the number of lines thus found (always nonnegative).
18090
18091 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
18092
18093 static int
18094 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
18095 int start, start_byte, limit_byte, count;
18096 int *byte_pos_ptr;
18097 {
18098 register unsigned char *cursor;
18099 unsigned char *base;
18100
18101 register int ceiling;
18102 register unsigned char *ceiling_addr;
18103 int orig_count = count;
18104
18105 /* If we are not in selective display mode,
18106 check only for newlines. */
18107 int selective_display = (!NILP (current_buffer->selective_display)
18108 && !INTEGERP (current_buffer->selective_display));
18109
18110 if (count > 0)
18111 {
18112 while (start_byte < limit_byte)
18113 {
18114 ceiling = BUFFER_CEILING_OF (start_byte);
18115 ceiling = min (limit_byte - 1, ceiling);
18116 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
18117 base = (cursor = BYTE_POS_ADDR (start_byte));
18118 while (1)
18119 {
18120 if (selective_display)
18121 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
18122 ;
18123 else
18124 while (*cursor != '\n' && ++cursor != ceiling_addr)
18125 ;
18126
18127 if (cursor != ceiling_addr)
18128 {
18129 if (--count == 0)
18130 {
18131 start_byte += cursor - base + 1;
18132 *byte_pos_ptr = start_byte;
18133 return orig_count;
18134 }
18135 else
18136 if (++cursor == ceiling_addr)
18137 break;
18138 }
18139 else
18140 break;
18141 }
18142 start_byte += cursor - base;
18143 }
18144 }
18145 else
18146 {
18147 while (start_byte > limit_byte)
18148 {
18149 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
18150 ceiling = max (limit_byte, ceiling);
18151 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
18152 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
18153 while (1)
18154 {
18155 if (selective_display)
18156 while (--cursor != ceiling_addr
18157 && *cursor != '\n' && *cursor != 015)
18158 ;
18159 else
18160 while (--cursor != ceiling_addr && *cursor != '\n')
18161 ;
18162
18163 if (cursor != ceiling_addr)
18164 {
18165 if (++count == 0)
18166 {
18167 start_byte += cursor - base + 1;
18168 *byte_pos_ptr = start_byte;
18169 /* When scanning backwards, we should
18170 not count the newline posterior to which we stop. */
18171 return - orig_count - 1;
18172 }
18173 }
18174 else
18175 break;
18176 }
18177 /* Here we add 1 to compensate for the last decrement
18178 of CURSOR, which took it past the valid range. */
18179 start_byte += cursor - base + 1;
18180 }
18181 }
18182
18183 *byte_pos_ptr = limit_byte;
18184
18185 if (count < 0)
18186 return - orig_count + count;
18187 return orig_count - count;
18188
18189 }
18190
18191
18192 \f
18193 /***********************************************************************
18194 Displaying strings
18195 ***********************************************************************/
18196
18197 /* Display a NUL-terminated string, starting with index START.
18198
18199 If STRING is non-null, display that C string. Otherwise, the Lisp
18200 string LISP_STRING is displayed.
18201
18202 If FACE_STRING is not nil, FACE_STRING_POS is a position in
18203 FACE_STRING. Display STRING or LISP_STRING with the face at
18204 FACE_STRING_POS in FACE_STRING:
18205
18206 Display the string in the environment given by IT, but use the
18207 standard display table, temporarily.
18208
18209 FIELD_WIDTH is the minimum number of output glyphs to produce.
18210 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18211 with spaces. If STRING has more characters, more than FIELD_WIDTH
18212 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
18213
18214 PRECISION is the maximum number of characters to output from
18215 STRING. PRECISION < 0 means don't truncate the string.
18216
18217 This is roughly equivalent to printf format specifiers:
18218
18219 FIELD_WIDTH PRECISION PRINTF
18220 ----------------------------------------
18221 -1 -1 %s
18222 -1 10 %.10s
18223 10 -1 %10s
18224 20 10 %20.10s
18225
18226 MULTIBYTE zero means do not display multibyte chars, > 0 means do
18227 display them, and < 0 means obey the current buffer's value of
18228 enable_multibyte_characters.
18229
18230 Value is the number of columns displayed. */
18231
18232 static int
18233 display_string (string, lisp_string, face_string, face_string_pos,
18234 start, it, field_width, precision, max_x, multibyte)
18235 unsigned char *string;
18236 Lisp_Object lisp_string;
18237 Lisp_Object face_string;
18238 int face_string_pos;
18239 int start;
18240 struct it *it;
18241 int field_width, precision, max_x;
18242 int multibyte;
18243 {
18244 int hpos_at_start = it->hpos;
18245 int saved_face_id = it->face_id;
18246 struct glyph_row *row = it->glyph_row;
18247
18248 /* Initialize the iterator IT for iteration over STRING beginning
18249 with index START. */
18250 reseat_to_string (it, string, lisp_string, start,
18251 precision, field_width, multibyte);
18252
18253 /* If displaying STRING, set up the face of the iterator
18254 from LISP_STRING, if that's given. */
18255 if (STRINGP (face_string))
18256 {
18257 int endptr;
18258 struct face *face;
18259
18260 it->face_id
18261 = face_at_string_position (it->w, face_string, face_string_pos,
18262 0, it->region_beg_charpos,
18263 it->region_end_charpos,
18264 &endptr, it->base_face_id, 0);
18265 face = FACE_FROM_ID (it->f, it->face_id);
18266 it->face_box_p = face->box != FACE_NO_BOX;
18267 }
18268
18269 /* Set max_x to the maximum allowed X position. Don't let it go
18270 beyond the right edge of the window. */
18271 if (max_x <= 0)
18272 max_x = it->last_visible_x;
18273 else
18274 max_x = min (max_x, it->last_visible_x);
18275
18276 /* Skip over display elements that are not visible. because IT->w is
18277 hscrolled. */
18278 if (it->current_x < it->first_visible_x)
18279 move_it_in_display_line_to (it, 100000, it->first_visible_x,
18280 MOVE_TO_POS | MOVE_TO_X);
18281
18282 row->ascent = it->max_ascent;
18283 row->height = it->max_ascent + it->max_descent;
18284 row->phys_ascent = it->max_phys_ascent;
18285 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18286 row->extra_line_spacing = it->max_extra_line_spacing;
18287
18288 /* This condition is for the case that we are called with current_x
18289 past last_visible_x. */
18290 while (it->current_x < max_x)
18291 {
18292 int x_before, x, n_glyphs_before, i, nglyphs;
18293
18294 /* Get the next display element. */
18295 if (!get_next_display_element (it))
18296 break;
18297
18298 /* Produce glyphs. */
18299 x_before = it->current_x;
18300 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
18301 PRODUCE_GLYPHS (it);
18302
18303 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
18304 i = 0;
18305 x = x_before;
18306 while (i < nglyphs)
18307 {
18308 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18309
18310 if (!it->truncate_lines_p
18311 && x + glyph->pixel_width > max_x)
18312 {
18313 /* End of continued line or max_x reached. */
18314 if (CHAR_GLYPH_PADDING_P (*glyph))
18315 {
18316 /* A wide character is unbreakable. */
18317 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
18318 it->current_x = x_before;
18319 }
18320 else
18321 {
18322 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
18323 it->current_x = x;
18324 }
18325 break;
18326 }
18327 else if (x + glyph->pixel_width > it->first_visible_x)
18328 {
18329 /* Glyph is at least partially visible. */
18330 ++it->hpos;
18331 if (x < it->first_visible_x)
18332 it->glyph_row->x = x - it->first_visible_x;
18333 }
18334 else
18335 {
18336 /* Glyph is off the left margin of the display area.
18337 Should not happen. */
18338 abort ();
18339 }
18340
18341 row->ascent = max (row->ascent, it->max_ascent);
18342 row->height = max (row->height, it->max_ascent + it->max_descent);
18343 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18344 row->phys_height = max (row->phys_height,
18345 it->max_phys_ascent + it->max_phys_descent);
18346 row->extra_line_spacing = max (row->extra_line_spacing,
18347 it->max_extra_line_spacing);
18348 x += glyph->pixel_width;
18349 ++i;
18350 }
18351
18352 /* Stop if max_x reached. */
18353 if (i < nglyphs)
18354 break;
18355
18356 /* Stop at line ends. */
18357 if (ITERATOR_AT_END_OF_LINE_P (it))
18358 {
18359 it->continuation_lines_width = 0;
18360 break;
18361 }
18362
18363 set_iterator_to_next (it, 1);
18364
18365 /* Stop if truncating at the right edge. */
18366 if (it->truncate_lines_p
18367 && it->current_x >= it->last_visible_x)
18368 {
18369 /* Add truncation mark, but don't do it if the line is
18370 truncated at a padding space. */
18371 if (IT_CHARPOS (*it) < it->string_nchars)
18372 {
18373 if (!FRAME_WINDOW_P (it->f))
18374 {
18375 int i, n;
18376
18377 if (it->current_x > it->last_visible_x)
18378 {
18379 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
18380 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18381 break;
18382 for (n = row->used[TEXT_AREA]; i < n; ++i)
18383 {
18384 row->used[TEXT_AREA] = i;
18385 produce_special_glyphs (it, IT_TRUNCATION);
18386 }
18387 }
18388 produce_special_glyphs (it, IT_TRUNCATION);
18389 }
18390 it->glyph_row->truncated_on_right_p = 1;
18391 }
18392 break;
18393 }
18394 }
18395
18396 /* Maybe insert a truncation at the left. */
18397 if (it->first_visible_x
18398 && IT_CHARPOS (*it) > 0)
18399 {
18400 if (!FRAME_WINDOW_P (it->f))
18401 insert_left_trunc_glyphs (it);
18402 it->glyph_row->truncated_on_left_p = 1;
18403 }
18404
18405 it->face_id = saved_face_id;
18406
18407 /* Value is number of columns displayed. */
18408 return it->hpos - hpos_at_start;
18409 }
18410
18411
18412 \f
18413 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
18414 appears as an element of LIST or as the car of an element of LIST.
18415 If PROPVAL is a list, compare each element against LIST in that
18416 way, and return 1/2 if any element of PROPVAL is found in LIST.
18417 Otherwise return 0. This function cannot quit.
18418 The return value is 2 if the text is invisible but with an ellipsis
18419 and 1 if it's invisible and without an ellipsis. */
18420
18421 int
18422 invisible_p (propval, list)
18423 register Lisp_Object propval;
18424 Lisp_Object list;
18425 {
18426 register Lisp_Object tail, proptail;
18427
18428 for (tail = list; CONSP (tail); tail = XCDR (tail))
18429 {
18430 register Lisp_Object tem;
18431 tem = XCAR (tail);
18432 if (EQ (propval, tem))
18433 return 1;
18434 if (CONSP (tem) && EQ (propval, XCAR (tem)))
18435 return NILP (XCDR (tem)) ? 1 : 2;
18436 }
18437
18438 if (CONSP (propval))
18439 {
18440 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
18441 {
18442 Lisp_Object propelt;
18443 propelt = XCAR (proptail);
18444 for (tail = list; CONSP (tail); tail = XCDR (tail))
18445 {
18446 register Lisp_Object tem;
18447 tem = XCAR (tail);
18448 if (EQ (propelt, tem))
18449 return 1;
18450 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
18451 return NILP (XCDR (tem)) ? 1 : 2;
18452 }
18453 }
18454 }
18455
18456 return 0;
18457 }
18458
18459 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
18460 doc: /* Non-nil if the property makes the text invisible.
18461 POS-OR-PROP can be a marker or number, in which case it is taken to be
18462 a position in the current buffer and the value of the `invisible' property
18463 is checked; or it can be some other value, which is then presumed to be the
18464 value of the `invisible' property of the text of interest.
18465 The non-nil value returned can be t for truly invisible text or something
18466 else if the text is replaced by an ellipsis. */)
18467 (pos_or_prop)
18468 Lisp_Object pos_or_prop;
18469 {
18470 Lisp_Object prop
18471 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
18472 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
18473 : pos_or_prop);
18474 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
18475 return (invis == 0 ? Qnil
18476 : invis == 1 ? Qt
18477 : make_number (invis));
18478 }
18479
18480 /* Calculate a width or height in pixels from a specification using
18481 the following elements:
18482
18483 SPEC ::=
18484 NUM - a (fractional) multiple of the default font width/height
18485 (NUM) - specifies exactly NUM pixels
18486 UNIT - a fixed number of pixels, see below.
18487 ELEMENT - size of a display element in pixels, see below.
18488 (NUM . SPEC) - equals NUM * SPEC
18489 (+ SPEC SPEC ...) - add pixel values
18490 (- SPEC SPEC ...) - subtract pixel values
18491 (- SPEC) - negate pixel value
18492
18493 NUM ::=
18494 INT or FLOAT - a number constant
18495 SYMBOL - use symbol's (buffer local) variable binding.
18496
18497 UNIT ::=
18498 in - pixels per inch *)
18499 mm - pixels per 1/1000 meter *)
18500 cm - pixels per 1/100 meter *)
18501 width - width of current font in pixels.
18502 height - height of current font in pixels.
18503
18504 *) using the ratio(s) defined in display-pixels-per-inch.
18505
18506 ELEMENT ::=
18507
18508 left-fringe - left fringe width in pixels
18509 right-fringe - right fringe width in pixels
18510
18511 left-margin - left margin width in pixels
18512 right-margin - right margin width in pixels
18513
18514 scroll-bar - scroll-bar area width in pixels
18515
18516 Examples:
18517
18518 Pixels corresponding to 5 inches:
18519 (5 . in)
18520
18521 Total width of non-text areas on left side of window (if scroll-bar is on left):
18522 '(space :width (+ left-fringe left-margin scroll-bar))
18523
18524 Align to first text column (in header line):
18525 '(space :align-to 0)
18526
18527 Align to middle of text area minus half the width of variable `my-image'
18528 containing a loaded image:
18529 '(space :align-to (0.5 . (- text my-image)))
18530
18531 Width of left margin minus width of 1 character in the default font:
18532 '(space :width (- left-margin 1))
18533
18534 Width of left margin minus width of 2 characters in the current font:
18535 '(space :width (- left-margin (2 . width)))
18536
18537 Center 1 character over left-margin (in header line):
18538 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
18539
18540 Different ways to express width of left fringe plus left margin minus one pixel:
18541 '(space :width (- (+ left-fringe left-margin) (1)))
18542 '(space :width (+ left-fringe left-margin (- (1))))
18543 '(space :width (+ left-fringe left-margin (-1)))
18544
18545 */
18546
18547 #define NUMVAL(X) \
18548 ((INTEGERP (X) || FLOATP (X)) \
18549 ? XFLOATINT (X) \
18550 : - 1)
18551
18552 int
18553 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
18554 double *res;
18555 struct it *it;
18556 Lisp_Object prop;
18557 void *font;
18558 int width_p, *align_to;
18559 {
18560 double pixels;
18561
18562 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
18563 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
18564
18565 if (NILP (prop))
18566 return OK_PIXELS (0);
18567
18568 xassert (FRAME_LIVE_P (it->f));
18569
18570 if (SYMBOLP (prop))
18571 {
18572 if (SCHARS (SYMBOL_NAME (prop)) == 2)
18573 {
18574 char *unit = SDATA (SYMBOL_NAME (prop));
18575
18576 if (unit[0] == 'i' && unit[1] == 'n')
18577 pixels = 1.0;
18578 else if (unit[0] == 'm' && unit[1] == 'm')
18579 pixels = 25.4;
18580 else if (unit[0] == 'c' && unit[1] == 'm')
18581 pixels = 2.54;
18582 else
18583 pixels = 0;
18584 if (pixels > 0)
18585 {
18586 double ppi;
18587 #ifdef HAVE_WINDOW_SYSTEM
18588 if (FRAME_WINDOW_P (it->f)
18589 && (ppi = (width_p
18590 ? FRAME_X_DISPLAY_INFO (it->f)->resx
18591 : FRAME_X_DISPLAY_INFO (it->f)->resy),
18592 ppi > 0))
18593 return OK_PIXELS (ppi / pixels);
18594 #endif
18595
18596 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
18597 || (CONSP (Vdisplay_pixels_per_inch)
18598 && (ppi = (width_p
18599 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
18600 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
18601 ppi > 0)))
18602 return OK_PIXELS (ppi / pixels);
18603
18604 return 0;
18605 }
18606 }
18607
18608 #ifdef HAVE_WINDOW_SYSTEM
18609 if (EQ (prop, Qheight))
18610 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
18611 if (EQ (prop, Qwidth))
18612 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
18613 #else
18614 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
18615 return OK_PIXELS (1);
18616 #endif
18617
18618 if (EQ (prop, Qtext))
18619 return OK_PIXELS (width_p
18620 ? window_box_width (it->w, TEXT_AREA)
18621 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
18622
18623 if (align_to && *align_to < 0)
18624 {
18625 *res = 0;
18626 if (EQ (prop, Qleft))
18627 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
18628 if (EQ (prop, Qright))
18629 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
18630 if (EQ (prop, Qcenter))
18631 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
18632 + window_box_width (it->w, TEXT_AREA) / 2);
18633 if (EQ (prop, Qleft_fringe))
18634 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18635 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
18636 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
18637 if (EQ (prop, Qright_fringe))
18638 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18639 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18640 : window_box_right_offset (it->w, TEXT_AREA));
18641 if (EQ (prop, Qleft_margin))
18642 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
18643 if (EQ (prop, Qright_margin))
18644 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
18645 if (EQ (prop, Qscroll_bar))
18646 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18647 ? 0
18648 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18649 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18650 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18651 : 0)));
18652 }
18653 else
18654 {
18655 if (EQ (prop, Qleft_fringe))
18656 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
18657 if (EQ (prop, Qright_fringe))
18658 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
18659 if (EQ (prop, Qleft_margin))
18660 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
18661 if (EQ (prop, Qright_margin))
18662 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
18663 if (EQ (prop, Qscroll_bar))
18664 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
18665 }
18666
18667 prop = Fbuffer_local_value (prop, it->w->buffer);
18668 }
18669
18670 if (INTEGERP (prop) || FLOATP (prop))
18671 {
18672 int base_unit = (width_p
18673 ? FRAME_COLUMN_WIDTH (it->f)
18674 : FRAME_LINE_HEIGHT (it->f));
18675 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18676 }
18677
18678 if (CONSP (prop))
18679 {
18680 Lisp_Object car = XCAR (prop);
18681 Lisp_Object cdr = XCDR (prop);
18682
18683 if (SYMBOLP (car))
18684 {
18685 #ifdef HAVE_WINDOW_SYSTEM
18686 if (FRAME_WINDOW_P (it->f)
18687 && valid_image_p (prop))
18688 {
18689 int id = lookup_image (it->f, prop);
18690 struct image *img = IMAGE_FROM_ID (it->f, id);
18691
18692 return OK_PIXELS (width_p ? img->width : img->height);
18693 }
18694 #endif
18695 if (EQ (car, Qplus) || EQ (car, Qminus))
18696 {
18697 int first = 1;
18698 double px;
18699
18700 pixels = 0;
18701 while (CONSP (cdr))
18702 {
18703 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
18704 font, width_p, align_to))
18705 return 0;
18706 if (first)
18707 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18708 else
18709 pixels += px;
18710 cdr = XCDR (cdr);
18711 }
18712 if (EQ (car, Qminus))
18713 pixels = -pixels;
18714 return OK_PIXELS (pixels);
18715 }
18716
18717 car = Fbuffer_local_value (car, it->w->buffer);
18718 }
18719
18720 if (INTEGERP (car) || FLOATP (car))
18721 {
18722 double fact;
18723 pixels = XFLOATINT (car);
18724 if (NILP (cdr))
18725 return OK_PIXELS (pixels);
18726 if (calc_pixel_width_or_height (&fact, it, cdr,
18727 font, width_p, align_to))
18728 return OK_PIXELS (pixels * fact);
18729 return 0;
18730 }
18731
18732 return 0;
18733 }
18734
18735 return 0;
18736 }
18737
18738 \f
18739 /***********************************************************************
18740 Glyph Display
18741 ***********************************************************************/
18742
18743 #ifdef HAVE_WINDOW_SYSTEM
18744
18745 #if GLYPH_DEBUG
18746
18747 void
18748 dump_glyph_string (s)
18749 struct glyph_string *s;
18750 {
18751 fprintf (stderr, "glyph string\n");
18752 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
18753 s->x, s->y, s->width, s->height);
18754 fprintf (stderr, " ybase = %d\n", s->ybase);
18755 fprintf (stderr, " hl = %d\n", s->hl);
18756 fprintf (stderr, " left overhang = %d, right = %d\n",
18757 s->left_overhang, s->right_overhang);
18758 fprintf (stderr, " nchars = %d\n", s->nchars);
18759 fprintf (stderr, " extends to end of line = %d\n",
18760 s->extends_to_end_of_line_p);
18761 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
18762 fprintf (stderr, " bg width = %d\n", s->background_width);
18763 }
18764
18765 #endif /* GLYPH_DEBUG */
18766
18767 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
18768 of XChar2b structures for S; it can't be allocated in
18769 init_glyph_string because it must be allocated via `alloca'. W
18770 is the window on which S is drawn. ROW and AREA are the glyph row
18771 and area within the row from which S is constructed. START is the
18772 index of the first glyph structure covered by S. HL is a
18773 face-override for drawing S. */
18774
18775 #ifdef HAVE_NTGUI
18776 #define OPTIONAL_HDC(hdc) hdc,
18777 #define DECLARE_HDC(hdc) HDC hdc;
18778 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
18779 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
18780 #endif
18781
18782 #ifndef OPTIONAL_HDC
18783 #define OPTIONAL_HDC(hdc)
18784 #define DECLARE_HDC(hdc)
18785 #define ALLOCATE_HDC(hdc, f)
18786 #define RELEASE_HDC(hdc, f)
18787 #endif
18788
18789 static void
18790 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
18791 struct glyph_string *s;
18792 DECLARE_HDC (hdc)
18793 XChar2b *char2b;
18794 struct window *w;
18795 struct glyph_row *row;
18796 enum glyph_row_area area;
18797 int start;
18798 enum draw_glyphs_face hl;
18799 {
18800 bzero (s, sizeof *s);
18801 s->w = w;
18802 s->f = XFRAME (w->frame);
18803 #ifdef HAVE_NTGUI
18804 s->hdc = hdc;
18805 #endif
18806 s->display = FRAME_X_DISPLAY (s->f);
18807 s->window = FRAME_X_WINDOW (s->f);
18808 s->char2b = char2b;
18809 s->hl = hl;
18810 s->row = row;
18811 s->area = area;
18812 s->first_glyph = row->glyphs[area] + start;
18813 s->height = row->height;
18814 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
18815
18816 /* Display the internal border below the tool-bar window. */
18817 if (WINDOWP (s->f->tool_bar_window)
18818 && s->w == XWINDOW (s->f->tool_bar_window))
18819 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
18820
18821 s->ybase = s->y + row->ascent;
18822 }
18823
18824
18825 /* Append the list of glyph strings with head H and tail T to the list
18826 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
18827
18828 static INLINE void
18829 append_glyph_string_lists (head, tail, h, t)
18830 struct glyph_string **head, **tail;
18831 struct glyph_string *h, *t;
18832 {
18833 if (h)
18834 {
18835 if (*head)
18836 (*tail)->next = h;
18837 else
18838 *head = h;
18839 h->prev = *tail;
18840 *tail = t;
18841 }
18842 }
18843
18844
18845 /* Prepend the list of glyph strings with head H and tail T to the
18846 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
18847 result. */
18848
18849 static INLINE void
18850 prepend_glyph_string_lists (head, tail, h, t)
18851 struct glyph_string **head, **tail;
18852 struct glyph_string *h, *t;
18853 {
18854 if (h)
18855 {
18856 if (*head)
18857 (*head)->prev = t;
18858 else
18859 *tail = t;
18860 t->next = *head;
18861 *head = h;
18862 }
18863 }
18864
18865
18866 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
18867 Set *HEAD and *TAIL to the resulting list. */
18868
18869 static INLINE void
18870 append_glyph_string (head, tail, s)
18871 struct glyph_string **head, **tail;
18872 struct glyph_string *s;
18873 {
18874 s->next = s->prev = NULL;
18875 append_glyph_string_lists (head, tail, s, s);
18876 }
18877
18878
18879 /* Get face and two-byte form of character glyph GLYPH on frame F.
18880 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
18881 a pointer to a realized face that is ready for display. */
18882
18883 static INLINE struct face *
18884 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
18885 struct frame *f;
18886 struct glyph *glyph;
18887 XChar2b *char2b;
18888 int *two_byte_p;
18889 {
18890 struct face *face;
18891
18892 xassert (glyph->type == CHAR_GLYPH);
18893 face = FACE_FROM_ID (f, glyph->face_id);
18894
18895 if (two_byte_p)
18896 *two_byte_p = 0;
18897
18898 if (!glyph->multibyte_p)
18899 {
18900 /* Unibyte case. We don't have to encode, but we have to make
18901 sure to use a face suitable for unibyte. */
18902 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
18903 }
18904 else if (glyph->u.ch < 128)
18905 {
18906 /* Case of ASCII in a face known to fit ASCII. */
18907 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
18908 }
18909 else
18910 {
18911 int c1, c2, charset;
18912
18913 /* Split characters into bytes. If c2 is -1 afterwards, C is
18914 really a one-byte character so that byte1 is zero. */
18915 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
18916 if (c2 > 0)
18917 STORE_XCHAR2B (char2b, c1, c2);
18918 else
18919 STORE_XCHAR2B (char2b, 0, c1);
18920
18921 /* Maybe encode the character in *CHAR2B. */
18922 if (charset != CHARSET_ASCII)
18923 {
18924 struct font_info *font_info
18925 = FONT_INFO_FROM_ID (f, face->font_info_id);
18926 if (font_info)
18927 glyph->font_type
18928 = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
18929 }
18930 }
18931
18932 /* Make sure X resources of the face are allocated. */
18933 xassert (face != NULL);
18934 PREPARE_FACE_FOR_DISPLAY (f, face);
18935 return face;
18936 }
18937
18938
18939 /* Fill glyph string S with composition components specified by S->cmp.
18940
18941 FACES is an array of faces for all components of this composition.
18942 S->gidx is the index of the first component for S.
18943
18944 OVERLAPS non-zero means S should draw the foreground only, and use
18945 its physical height for clipping. See also draw_glyphs.
18946
18947 Value is the index of a component not in S. */
18948
18949 static int
18950 fill_composite_glyph_string (s, faces, overlaps)
18951 struct glyph_string *s;
18952 struct face **faces;
18953 int overlaps;
18954 {
18955 int i;
18956
18957 xassert (s);
18958
18959 s->for_overlaps = overlaps;
18960
18961 s->face = faces[s->gidx];
18962 s->font = s->face->font;
18963 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18964
18965 /* For all glyphs of this composition, starting at the offset
18966 S->gidx, until we reach the end of the definition or encounter a
18967 glyph that requires the different face, add it to S. */
18968 ++s->nchars;
18969 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
18970 ++s->nchars;
18971
18972 /* All glyph strings for the same composition has the same width,
18973 i.e. the width set for the first component of the composition. */
18974
18975 s->width = s->first_glyph->pixel_width;
18976
18977 /* If the specified font could not be loaded, use the frame's
18978 default font, but record the fact that we couldn't load it in
18979 the glyph string so that we can draw rectangles for the
18980 characters of the glyph string. */
18981 if (s->font == NULL)
18982 {
18983 s->font_not_found_p = 1;
18984 s->font = FRAME_FONT (s->f);
18985 }
18986
18987 /* Adjust base line for subscript/superscript text. */
18988 s->ybase += s->first_glyph->voffset;
18989
18990 xassert (s->face && s->face->gc);
18991
18992 /* This glyph string must always be drawn with 16-bit functions. */
18993 s->two_byte_p = 1;
18994
18995 return s->gidx + s->nchars;
18996 }
18997
18998
18999 /* Fill glyph string S from a sequence of character glyphs.
19000
19001 FACE_ID is the face id of the string. START is the index of the
19002 first glyph to consider, END is the index of the last + 1.
19003 OVERLAPS non-zero means S should draw the foreground only, and use
19004 its physical height for clipping. See also draw_glyphs.
19005
19006 Value is the index of the first glyph not in S. */
19007
19008 static int
19009 fill_glyph_string (s, face_id, start, end, overlaps)
19010 struct glyph_string *s;
19011 int face_id;
19012 int start, end, overlaps;
19013 {
19014 struct glyph *glyph, *last;
19015 int voffset;
19016 int glyph_not_available_p;
19017
19018 xassert (s->f == XFRAME (s->w->frame));
19019 xassert (s->nchars == 0);
19020 xassert (start >= 0 && end > start);
19021
19022 s->for_overlaps = overlaps,
19023 glyph = s->row->glyphs[s->area] + start;
19024 last = s->row->glyphs[s->area] + end;
19025 voffset = glyph->voffset;
19026
19027 glyph_not_available_p = glyph->glyph_not_available_p;
19028
19029 while (glyph < last
19030 && glyph->type == CHAR_GLYPH
19031 && glyph->voffset == voffset
19032 /* Same face id implies same font, nowadays. */
19033 && glyph->face_id == face_id
19034 && glyph->glyph_not_available_p == glyph_not_available_p)
19035 {
19036 int two_byte_p;
19037
19038 s->face = get_glyph_face_and_encoding (s->f, glyph,
19039 s->char2b + s->nchars,
19040 &two_byte_p);
19041 s->two_byte_p = two_byte_p;
19042 ++s->nchars;
19043 xassert (s->nchars <= end - start);
19044 s->width += glyph->pixel_width;
19045 ++glyph;
19046 }
19047
19048 s->font = s->face->font;
19049 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
19050
19051 /* If the specified font could not be loaded, use the frame's font,
19052 but record the fact that we couldn't load it in
19053 S->font_not_found_p so that we can draw rectangles for the
19054 characters of the glyph string. */
19055 if (s->font == NULL || glyph_not_available_p)
19056 {
19057 s->font_not_found_p = 1;
19058 s->font = FRAME_FONT (s->f);
19059 }
19060
19061 /* Adjust base line for subscript/superscript text. */
19062 s->ybase += voffset;
19063
19064 xassert (s->face && s->face->gc);
19065 return glyph - s->row->glyphs[s->area];
19066 }
19067
19068
19069 /* Fill glyph string S from image glyph S->first_glyph. */
19070
19071 static void
19072 fill_image_glyph_string (s)
19073 struct glyph_string *s;
19074 {
19075 xassert (s->first_glyph->type == IMAGE_GLYPH);
19076 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
19077 xassert (s->img);
19078 s->slice = s->first_glyph->slice;
19079 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
19080 s->font = s->face->font;
19081 s->width = s->first_glyph->pixel_width;
19082
19083 /* Adjust base line for subscript/superscript text. */
19084 s->ybase += s->first_glyph->voffset;
19085 }
19086
19087
19088 /* Fill glyph string S from a sequence of stretch glyphs.
19089
19090 ROW is the glyph row in which the glyphs are found, AREA is the
19091 area within the row. START is the index of the first glyph to
19092 consider, END is the index of the last + 1.
19093
19094 Value is the index of the first glyph not in S. */
19095
19096 static int
19097 fill_stretch_glyph_string (s, row, area, start, end)
19098 struct glyph_string *s;
19099 struct glyph_row *row;
19100 enum glyph_row_area area;
19101 int start, end;
19102 {
19103 struct glyph *glyph, *last;
19104 int voffset, face_id;
19105
19106 xassert (s->first_glyph->type == STRETCH_GLYPH);
19107
19108 glyph = s->row->glyphs[s->area] + start;
19109 last = s->row->glyphs[s->area] + end;
19110 face_id = glyph->face_id;
19111 s->face = FACE_FROM_ID (s->f, face_id);
19112 s->font = s->face->font;
19113 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
19114 s->width = glyph->pixel_width;
19115 s->nchars = 1;
19116 voffset = glyph->voffset;
19117
19118 for (++glyph;
19119 (glyph < last
19120 && glyph->type == STRETCH_GLYPH
19121 && glyph->voffset == voffset
19122 && glyph->face_id == face_id);
19123 ++glyph)
19124 s->width += glyph->pixel_width;
19125
19126 /* Adjust base line for subscript/superscript text. */
19127 s->ybase += voffset;
19128
19129 /* The case that face->gc == 0 is handled when drawing the glyph
19130 string by calling PREPARE_FACE_FOR_DISPLAY. */
19131 xassert (s->face);
19132 return glyph - s->row->glyphs[s->area];
19133 }
19134
19135
19136 /* EXPORT for RIF:
19137 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
19138 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
19139 assumed to be zero. */
19140
19141 void
19142 x_get_glyph_overhangs (glyph, f, left, right)
19143 struct glyph *glyph;
19144 struct frame *f;
19145 int *left, *right;
19146 {
19147 *left = *right = 0;
19148
19149 if (glyph->type == CHAR_GLYPH)
19150 {
19151 XFontStruct *font;
19152 struct face *face;
19153 struct font_info *font_info;
19154 XChar2b char2b;
19155 XCharStruct *pcm;
19156
19157 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
19158 font = face->font;
19159 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
19160 if (font /* ++KFS: Should this be font_info ? */
19161 && (pcm = FRAME_RIF (f)->per_char_metric (font, &char2b, glyph->font_type)))
19162 {
19163 if (pcm->rbearing > pcm->width)
19164 *right = pcm->rbearing - pcm->width;
19165 if (pcm->lbearing < 0)
19166 *left = -pcm->lbearing;
19167 }
19168 }
19169 }
19170
19171
19172 /* Return the index of the first glyph preceding glyph string S that
19173 is overwritten by S because of S's left overhang. Value is -1
19174 if no glyphs are overwritten. */
19175
19176 static int
19177 left_overwritten (s)
19178 struct glyph_string *s;
19179 {
19180 int k;
19181
19182 if (s->left_overhang)
19183 {
19184 int x = 0, i;
19185 struct glyph *glyphs = s->row->glyphs[s->area];
19186 int first = s->first_glyph - glyphs;
19187
19188 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
19189 x -= glyphs[i].pixel_width;
19190
19191 k = i + 1;
19192 }
19193 else
19194 k = -1;
19195
19196 return k;
19197 }
19198
19199
19200 /* Return the index of the first glyph preceding glyph string S that
19201 is overwriting S because of its right overhang. Value is -1 if no
19202 glyph in front of S overwrites S. */
19203
19204 static int
19205 left_overwriting (s)
19206 struct glyph_string *s;
19207 {
19208 int i, k, x;
19209 struct glyph *glyphs = s->row->glyphs[s->area];
19210 int first = s->first_glyph - glyphs;
19211
19212 k = -1;
19213 x = 0;
19214 for (i = first - 1; i >= 0; --i)
19215 {
19216 int left, right;
19217 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19218 if (x + right > 0)
19219 k = i;
19220 x -= glyphs[i].pixel_width;
19221 }
19222
19223 return k;
19224 }
19225
19226
19227 /* Return the index of the last glyph following glyph string S that is
19228 not overwritten by S because of S's right overhang. Value is -1 if
19229 no such glyph is found. */
19230
19231 static int
19232 right_overwritten (s)
19233 struct glyph_string *s;
19234 {
19235 int k = -1;
19236
19237 if (s->right_overhang)
19238 {
19239 int x = 0, i;
19240 struct glyph *glyphs = s->row->glyphs[s->area];
19241 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19242 int end = s->row->used[s->area];
19243
19244 for (i = first; i < end && s->right_overhang > x; ++i)
19245 x += glyphs[i].pixel_width;
19246
19247 k = i;
19248 }
19249
19250 return k;
19251 }
19252
19253
19254 /* Return the index of the last glyph following glyph string S that
19255 overwrites S because of its left overhang. Value is negative
19256 if no such glyph is found. */
19257
19258 static int
19259 right_overwriting (s)
19260 struct glyph_string *s;
19261 {
19262 int i, k, x;
19263 int end = s->row->used[s->area];
19264 struct glyph *glyphs = s->row->glyphs[s->area];
19265 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19266
19267 k = -1;
19268 x = 0;
19269 for (i = first; i < end; ++i)
19270 {
19271 int left, right;
19272 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19273 if (x - left < 0)
19274 k = i;
19275 x += glyphs[i].pixel_width;
19276 }
19277
19278 return k;
19279 }
19280
19281
19282 /* Get face and two-byte form of character C in face FACE_ID on frame
19283 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
19284 means we want to display multibyte text. DISPLAY_P non-zero means
19285 make sure that X resources for the face returned are allocated.
19286 Value is a pointer to a realized face that is ready for display if
19287 DISPLAY_P is non-zero. */
19288
19289 static INLINE struct face *
19290 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
19291 struct frame *f;
19292 int c, face_id;
19293 XChar2b *char2b;
19294 int multibyte_p, display_p;
19295 {
19296 struct face *face = FACE_FROM_ID (f, face_id);
19297
19298 if (!multibyte_p)
19299 {
19300 /* Unibyte case. We don't have to encode, but we have to make
19301 sure to use a face suitable for unibyte. */
19302 STORE_XCHAR2B (char2b, 0, c);
19303 face_id = FACE_FOR_CHAR (f, face, c);
19304 face = FACE_FROM_ID (f, face_id);
19305 }
19306 else if (c < 128)
19307 {
19308 /* Case of ASCII in a face known to fit ASCII. */
19309 STORE_XCHAR2B (char2b, 0, c);
19310 }
19311 else
19312 {
19313 int c1, c2, charset;
19314
19315 /* Split characters into bytes. If c2 is -1 afterwards, C is
19316 really a one-byte character so that byte1 is zero. */
19317 SPLIT_CHAR (c, charset, c1, c2);
19318 if (c2 > 0)
19319 STORE_XCHAR2B (char2b, c1, c2);
19320 else
19321 STORE_XCHAR2B (char2b, 0, c1);
19322
19323 /* Maybe encode the character in *CHAR2B. */
19324 if (face->font != NULL)
19325 {
19326 struct font_info *font_info
19327 = FONT_INFO_FROM_ID (f, face->font_info_id);
19328 if (font_info)
19329 FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
19330 }
19331 }
19332
19333 /* Make sure X resources of the face are allocated. */
19334 #ifdef HAVE_X_WINDOWS
19335 if (display_p)
19336 #endif
19337 {
19338 xassert (face != NULL);
19339 PREPARE_FACE_FOR_DISPLAY (f, face);
19340 }
19341
19342 return face;
19343 }
19344
19345
19346 /* Set background width of glyph string S. START is the index of the
19347 first glyph following S. LAST_X is the right-most x-position + 1
19348 in the drawing area. */
19349
19350 static INLINE void
19351 set_glyph_string_background_width (s, start, last_x)
19352 struct glyph_string *s;
19353 int start;
19354 int last_x;
19355 {
19356 /* If the face of this glyph string has to be drawn to the end of
19357 the drawing area, set S->extends_to_end_of_line_p. */
19358
19359 if (start == s->row->used[s->area]
19360 && s->area == TEXT_AREA
19361 && ((s->row->fill_line_p
19362 && (s->hl == DRAW_NORMAL_TEXT
19363 || s->hl == DRAW_IMAGE_RAISED
19364 || s->hl == DRAW_IMAGE_SUNKEN))
19365 || s->hl == DRAW_MOUSE_FACE))
19366 s->extends_to_end_of_line_p = 1;
19367
19368 /* If S extends its face to the end of the line, set its
19369 background_width to the distance to the right edge of the drawing
19370 area. */
19371 if (s->extends_to_end_of_line_p)
19372 s->background_width = last_x - s->x + 1;
19373 else
19374 s->background_width = s->width;
19375 }
19376
19377
19378 /* Compute overhangs and x-positions for glyph string S and its
19379 predecessors, or successors. X is the starting x-position for S.
19380 BACKWARD_P non-zero means process predecessors. */
19381
19382 static void
19383 compute_overhangs_and_x (s, x, backward_p)
19384 struct glyph_string *s;
19385 int x;
19386 int backward_p;
19387 {
19388 if (backward_p)
19389 {
19390 while (s)
19391 {
19392 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
19393 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
19394 x -= s->width;
19395 s->x = x;
19396 s = s->prev;
19397 }
19398 }
19399 else
19400 {
19401 while (s)
19402 {
19403 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
19404 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
19405 s->x = x;
19406 x += s->width;
19407 s = s->next;
19408 }
19409 }
19410 }
19411
19412
19413
19414 /* The following macros are only called from draw_glyphs below.
19415 They reference the following parameters of that function directly:
19416 `w', `row', `area', and `overlap_p'
19417 as well as the following local variables:
19418 `s', `f', and `hdc' (in W32) */
19419
19420 #ifdef HAVE_NTGUI
19421 /* On W32, silently add local `hdc' variable to argument list of
19422 init_glyph_string. */
19423 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19424 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
19425 #else
19426 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19427 init_glyph_string (s, char2b, w, row, area, start, hl)
19428 #endif
19429
19430 /* Add a glyph string for a stretch glyph to the list of strings
19431 between HEAD and TAIL. START is the index of the stretch glyph in
19432 row area AREA of glyph row ROW. END is the index of the last glyph
19433 in that glyph row area. X is the current output position assigned
19434 to the new glyph string constructed. HL overrides that face of the
19435 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19436 is the right-most x-position of the drawing area. */
19437
19438 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
19439 and below -- keep them on one line. */
19440 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19441 do \
19442 { \
19443 s = (struct glyph_string *) alloca (sizeof *s); \
19444 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19445 START = fill_stretch_glyph_string (s, row, area, START, END); \
19446 append_glyph_string (&HEAD, &TAIL, s); \
19447 s->x = (X); \
19448 } \
19449 while (0)
19450
19451
19452 /* Add a glyph string for an image glyph to the list of strings
19453 between HEAD and TAIL. START is the index of the image glyph in
19454 row area AREA of glyph row ROW. END is the index of the last glyph
19455 in that glyph row area. X is the current output position assigned
19456 to the new glyph string constructed. HL overrides that face of the
19457 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19458 is the right-most x-position of the drawing area. */
19459
19460 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19461 do \
19462 { \
19463 s = (struct glyph_string *) alloca (sizeof *s); \
19464 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19465 fill_image_glyph_string (s); \
19466 append_glyph_string (&HEAD, &TAIL, s); \
19467 ++START; \
19468 s->x = (X); \
19469 } \
19470 while (0)
19471
19472
19473 /* Add a glyph string for a sequence of character glyphs to the list
19474 of strings between HEAD and TAIL. START is the index of the first
19475 glyph in row area AREA of glyph row ROW that is part of the new
19476 glyph string. END is the index of the last glyph in that glyph row
19477 area. X is the current output position assigned to the new glyph
19478 string constructed. HL overrides that face of the glyph; e.g. it
19479 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
19480 right-most x-position of the drawing area. */
19481
19482 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19483 do \
19484 { \
19485 int c, face_id; \
19486 XChar2b *char2b; \
19487 \
19488 c = (row)->glyphs[area][START].u.ch; \
19489 face_id = (row)->glyphs[area][START].face_id; \
19490 \
19491 s = (struct glyph_string *) alloca (sizeof *s); \
19492 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
19493 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
19494 append_glyph_string (&HEAD, &TAIL, s); \
19495 s->x = (X); \
19496 START = fill_glyph_string (s, face_id, START, END, overlaps); \
19497 } \
19498 while (0)
19499
19500
19501 /* Add a glyph string for a composite sequence to the list of strings
19502 between HEAD and TAIL. START is the index of the first glyph in
19503 row area AREA of glyph row ROW that is part of the new glyph
19504 string. END is the index of the last glyph in that glyph row area.
19505 X is the current output position assigned to the new glyph string
19506 constructed. HL overrides that face of the glyph; e.g. it is
19507 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
19508 x-position of the drawing area. */
19509
19510 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19511 do { \
19512 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
19513 int face_id = (row)->glyphs[area][START].face_id; \
19514 struct face *base_face = FACE_FROM_ID (f, face_id); \
19515 struct composition *cmp = composition_table[cmp_id]; \
19516 int glyph_len = cmp->glyph_len; \
19517 XChar2b *char2b; \
19518 struct face **faces; \
19519 struct glyph_string *first_s = NULL; \
19520 int n; \
19521 \
19522 base_face = base_face->ascii_face; \
19523 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
19524 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
19525 /* At first, fill in `char2b' and `faces'. */ \
19526 for (n = 0; n < glyph_len; n++) \
19527 { \
19528 int c = COMPOSITION_GLYPH (cmp, n); \
19529 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
19530 faces[n] = FACE_FROM_ID (f, this_face_id); \
19531 get_char_face_and_encoding (f, c, this_face_id, \
19532 char2b + n, 1, 1); \
19533 } \
19534 \
19535 /* Make glyph_strings for each glyph sequence that is drawable by \
19536 the same face, and append them to HEAD/TAIL. */ \
19537 for (n = 0; n < cmp->glyph_len;) \
19538 { \
19539 s = (struct glyph_string *) alloca (sizeof *s); \
19540 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
19541 append_glyph_string (&(HEAD), &(TAIL), s); \
19542 s->cmp = cmp; \
19543 s->gidx = n; \
19544 s->x = (X); \
19545 \
19546 if (n == 0) \
19547 first_s = s; \
19548 \
19549 n = fill_composite_glyph_string (s, faces, overlaps); \
19550 } \
19551 \
19552 ++START; \
19553 s = first_s; \
19554 } while (0)
19555
19556
19557 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
19558 of AREA of glyph row ROW on window W between indices START and END.
19559 HL overrides the face for drawing glyph strings, e.g. it is
19560 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
19561 x-positions of the drawing area.
19562
19563 This is an ugly monster macro construct because we must use alloca
19564 to allocate glyph strings (because draw_glyphs can be called
19565 asynchronously). */
19566
19567 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19568 do \
19569 { \
19570 HEAD = TAIL = NULL; \
19571 while (START < END) \
19572 { \
19573 struct glyph *first_glyph = (row)->glyphs[area] + START; \
19574 switch (first_glyph->type) \
19575 { \
19576 case CHAR_GLYPH: \
19577 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
19578 HL, X, LAST_X); \
19579 break; \
19580 \
19581 case COMPOSITE_GLYPH: \
19582 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
19583 HL, X, LAST_X); \
19584 break; \
19585 \
19586 case STRETCH_GLYPH: \
19587 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
19588 HL, X, LAST_X); \
19589 break; \
19590 \
19591 case IMAGE_GLYPH: \
19592 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
19593 HL, X, LAST_X); \
19594 break; \
19595 \
19596 default: \
19597 abort (); \
19598 } \
19599 \
19600 set_glyph_string_background_width (s, START, LAST_X); \
19601 (X) += s->width; \
19602 } \
19603 } \
19604 while (0)
19605
19606
19607 /* Draw glyphs between START and END in AREA of ROW on window W,
19608 starting at x-position X. X is relative to AREA in W. HL is a
19609 face-override with the following meaning:
19610
19611 DRAW_NORMAL_TEXT draw normally
19612 DRAW_CURSOR draw in cursor face
19613 DRAW_MOUSE_FACE draw in mouse face.
19614 DRAW_INVERSE_VIDEO draw in mode line face
19615 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
19616 DRAW_IMAGE_RAISED draw an image with a raised relief around it
19617
19618 If OVERLAPS is non-zero, draw only the foreground of characters and
19619 clip to the physical height of ROW. Non-zero value also defines
19620 the overlapping part to be drawn:
19621
19622 OVERLAPS_PRED overlap with preceding rows
19623 OVERLAPS_SUCC overlap with succeeding rows
19624 OVERLAPS_BOTH overlap with both preceding/succeeding rows
19625 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
19626
19627 Value is the x-position reached, relative to AREA of W. */
19628
19629 static int
19630 draw_glyphs (w, x, row, area, start, end, hl, overlaps)
19631 struct window *w;
19632 int x;
19633 struct glyph_row *row;
19634 enum glyph_row_area area;
19635 int start, end;
19636 enum draw_glyphs_face hl;
19637 int overlaps;
19638 {
19639 struct glyph_string *head, *tail;
19640 struct glyph_string *s;
19641 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
19642 int last_x, area_width;
19643 int x_reached;
19644 int i, j;
19645 struct frame *f = XFRAME (WINDOW_FRAME (w));
19646 DECLARE_HDC (hdc);
19647
19648 ALLOCATE_HDC (hdc, f);
19649
19650 /* Let's rather be paranoid than getting a SEGV. */
19651 end = min (end, row->used[area]);
19652 start = max (0, start);
19653 start = min (end, start);
19654
19655 /* Translate X to frame coordinates. Set last_x to the right
19656 end of the drawing area. */
19657 if (row->full_width_p)
19658 {
19659 /* X is relative to the left edge of W, without scroll bars
19660 or fringes. */
19661 x += WINDOW_LEFT_EDGE_X (w);
19662 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
19663 }
19664 else
19665 {
19666 int area_left = window_box_left (w, area);
19667 x += area_left;
19668 area_width = window_box_width (w, area);
19669 last_x = area_left + area_width;
19670 }
19671
19672 /* Build a doubly-linked list of glyph_string structures between
19673 head and tail from what we have to draw. Note that the macro
19674 BUILD_GLYPH_STRINGS will modify its start parameter. That's
19675 the reason we use a separate variable `i'. */
19676 i = start;
19677 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
19678 if (tail)
19679 x_reached = tail->x + tail->background_width;
19680 else
19681 x_reached = x;
19682
19683 /* If there are any glyphs with lbearing < 0 or rbearing > width in
19684 the row, redraw some glyphs in front or following the glyph
19685 strings built above. */
19686 if (head && !overlaps && row->contains_overlapping_glyphs_p)
19687 {
19688 int dummy_x = 0;
19689 struct glyph_string *h, *t;
19690
19691 /* Compute overhangs for all glyph strings. */
19692 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
19693 for (s = head; s; s = s->next)
19694 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
19695
19696 /* Prepend glyph strings for glyphs in front of the first glyph
19697 string that are overwritten because of the first glyph
19698 string's left overhang. The background of all strings
19699 prepended must be drawn because the first glyph string
19700 draws over it. */
19701 i = left_overwritten (head);
19702 if (i >= 0)
19703 {
19704 j = i;
19705 BUILD_GLYPH_STRINGS (j, start, h, t,
19706 DRAW_NORMAL_TEXT, dummy_x, last_x);
19707 start = i;
19708 compute_overhangs_and_x (t, head->x, 1);
19709 prepend_glyph_string_lists (&head, &tail, h, t);
19710 clip_head = head;
19711 }
19712
19713 /* Prepend glyph strings for glyphs in front of the first glyph
19714 string that overwrite that glyph string because of their
19715 right overhang. For these strings, only the foreground must
19716 be drawn, because it draws over the glyph string at `head'.
19717 The background must not be drawn because this would overwrite
19718 right overhangs of preceding glyphs for which no glyph
19719 strings exist. */
19720 i = left_overwriting (head);
19721 if (i >= 0)
19722 {
19723 clip_head = head;
19724 BUILD_GLYPH_STRINGS (i, start, h, t,
19725 DRAW_NORMAL_TEXT, dummy_x, last_x);
19726 for (s = h; s; s = s->next)
19727 s->background_filled_p = 1;
19728 compute_overhangs_and_x (t, head->x, 1);
19729 prepend_glyph_string_lists (&head, &tail, h, t);
19730 }
19731
19732 /* Append glyphs strings for glyphs following the last glyph
19733 string tail that are overwritten by tail. The background of
19734 these strings has to be drawn because tail's foreground draws
19735 over it. */
19736 i = right_overwritten (tail);
19737 if (i >= 0)
19738 {
19739 BUILD_GLYPH_STRINGS (end, i, h, t,
19740 DRAW_NORMAL_TEXT, x, last_x);
19741 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19742 append_glyph_string_lists (&head, &tail, h, t);
19743 clip_tail = tail;
19744 }
19745
19746 /* Append glyph strings for glyphs following the last glyph
19747 string tail that overwrite tail. The foreground of such
19748 glyphs has to be drawn because it writes into the background
19749 of tail. The background must not be drawn because it could
19750 paint over the foreground of following glyphs. */
19751 i = right_overwriting (tail);
19752 if (i >= 0)
19753 {
19754 clip_tail = tail;
19755 BUILD_GLYPH_STRINGS (end, i, h, t,
19756 DRAW_NORMAL_TEXT, x, last_x);
19757 for (s = h; s; s = s->next)
19758 s->background_filled_p = 1;
19759 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19760 append_glyph_string_lists (&head, &tail, h, t);
19761 }
19762 if (clip_head || clip_tail)
19763 for (s = head; s; s = s->next)
19764 {
19765 s->clip_head = clip_head;
19766 s->clip_tail = clip_tail;
19767 }
19768 }
19769
19770 /* Draw all strings. */
19771 for (s = head; s; s = s->next)
19772 FRAME_RIF (f)->draw_glyph_string (s);
19773
19774 if (area == TEXT_AREA
19775 && !row->full_width_p
19776 /* When drawing overlapping rows, only the glyph strings'
19777 foreground is drawn, which doesn't erase a cursor
19778 completely. */
19779 && !overlaps)
19780 {
19781 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
19782 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
19783 : (tail ? tail->x + tail->background_width : x));
19784
19785 int text_left = window_box_left (w, TEXT_AREA);
19786 x0 -= text_left;
19787 x1 -= text_left;
19788
19789 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
19790 row->y, MATRIX_ROW_BOTTOM_Y (row));
19791 }
19792
19793 /* Value is the x-position up to which drawn, relative to AREA of W.
19794 This doesn't include parts drawn because of overhangs. */
19795 if (row->full_width_p)
19796 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
19797 else
19798 x_reached -= window_box_left (w, area);
19799
19800 RELEASE_HDC (hdc, f);
19801
19802 return x_reached;
19803 }
19804
19805 /* Expand row matrix if too narrow. Don't expand if area
19806 is not present. */
19807
19808 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
19809 { \
19810 if (!fonts_changed_p \
19811 && (it->glyph_row->glyphs[area] \
19812 < it->glyph_row->glyphs[area + 1])) \
19813 { \
19814 it->w->ncols_scale_factor++; \
19815 fonts_changed_p = 1; \
19816 } \
19817 }
19818
19819 /* Store one glyph for IT->char_to_display in IT->glyph_row.
19820 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19821
19822 static INLINE void
19823 append_glyph (it)
19824 struct it *it;
19825 {
19826 struct glyph *glyph;
19827 enum glyph_row_area area = it->area;
19828
19829 xassert (it->glyph_row);
19830 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
19831
19832 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19833 if (glyph < it->glyph_row->glyphs[area + 1])
19834 {
19835 glyph->charpos = CHARPOS (it->position);
19836 glyph->object = it->object;
19837 glyph->pixel_width = it->pixel_width;
19838 glyph->ascent = it->ascent;
19839 glyph->descent = it->descent;
19840 glyph->voffset = it->voffset;
19841 glyph->type = CHAR_GLYPH;
19842 glyph->multibyte_p = it->multibyte_p;
19843 glyph->left_box_line_p = it->start_of_box_run_p;
19844 glyph->right_box_line_p = it->end_of_box_run_p;
19845 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
19846 || it->phys_descent > it->descent);
19847 glyph->padding_p = 0;
19848 glyph->glyph_not_available_p = it->glyph_not_available_p;
19849 glyph->face_id = it->face_id;
19850 glyph->u.ch = it->char_to_display;
19851 glyph->slice = null_glyph_slice;
19852 glyph->font_type = FONT_TYPE_UNKNOWN;
19853 ++it->glyph_row->used[area];
19854 }
19855 else
19856 IT_EXPAND_MATRIX_WIDTH (it, area);
19857 }
19858
19859 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
19860 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19861
19862 static INLINE void
19863 append_composite_glyph (it)
19864 struct it *it;
19865 {
19866 struct glyph *glyph;
19867 enum glyph_row_area area = it->area;
19868
19869 xassert (it->glyph_row);
19870
19871 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19872 if (glyph < it->glyph_row->glyphs[area + 1])
19873 {
19874 glyph->charpos = CHARPOS (it->position);
19875 glyph->object = it->object;
19876 glyph->pixel_width = it->pixel_width;
19877 glyph->ascent = it->ascent;
19878 glyph->descent = it->descent;
19879 glyph->voffset = it->voffset;
19880 glyph->type = COMPOSITE_GLYPH;
19881 glyph->multibyte_p = it->multibyte_p;
19882 glyph->left_box_line_p = it->start_of_box_run_p;
19883 glyph->right_box_line_p = it->end_of_box_run_p;
19884 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
19885 || it->phys_descent > it->descent);
19886 glyph->padding_p = 0;
19887 glyph->glyph_not_available_p = 0;
19888 glyph->face_id = it->face_id;
19889 glyph->u.cmp_id = it->cmp_id;
19890 glyph->slice = null_glyph_slice;
19891 glyph->font_type = FONT_TYPE_UNKNOWN;
19892 ++it->glyph_row->used[area];
19893 }
19894 else
19895 IT_EXPAND_MATRIX_WIDTH (it, area);
19896 }
19897
19898
19899 /* Change IT->ascent and IT->height according to the setting of
19900 IT->voffset. */
19901
19902 static INLINE void
19903 take_vertical_position_into_account (it)
19904 struct it *it;
19905 {
19906 if (it->voffset)
19907 {
19908 if (it->voffset < 0)
19909 /* Increase the ascent so that we can display the text higher
19910 in the line. */
19911 it->ascent -= it->voffset;
19912 else
19913 /* Increase the descent so that we can display the text lower
19914 in the line. */
19915 it->descent += it->voffset;
19916 }
19917 }
19918
19919
19920 /* Produce glyphs/get display metrics for the image IT is loaded with.
19921 See the description of struct display_iterator in dispextern.h for
19922 an overview of struct display_iterator. */
19923
19924 static void
19925 produce_image_glyph (it)
19926 struct it *it;
19927 {
19928 struct image *img;
19929 struct face *face;
19930 int glyph_ascent, crop;
19931 struct glyph_slice slice;
19932
19933 xassert (it->what == IT_IMAGE);
19934
19935 face = FACE_FROM_ID (it->f, it->face_id);
19936 xassert (face);
19937 /* Make sure X resources of the face is loaded. */
19938 PREPARE_FACE_FOR_DISPLAY (it->f, face);
19939
19940 if (it->image_id < 0)
19941 {
19942 /* Fringe bitmap. */
19943 it->ascent = it->phys_ascent = 0;
19944 it->descent = it->phys_descent = 0;
19945 it->pixel_width = 0;
19946 it->nglyphs = 0;
19947 return;
19948 }
19949
19950 img = IMAGE_FROM_ID (it->f, it->image_id);
19951 xassert (img);
19952 /* Make sure X resources of the image is loaded. */
19953 prepare_image_for_display (it->f, img);
19954
19955 slice.x = slice.y = 0;
19956 slice.width = img->width;
19957 slice.height = img->height;
19958
19959 if (INTEGERP (it->slice.x))
19960 slice.x = XINT (it->slice.x);
19961 else if (FLOATP (it->slice.x))
19962 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
19963
19964 if (INTEGERP (it->slice.y))
19965 slice.y = XINT (it->slice.y);
19966 else if (FLOATP (it->slice.y))
19967 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
19968
19969 if (INTEGERP (it->slice.width))
19970 slice.width = XINT (it->slice.width);
19971 else if (FLOATP (it->slice.width))
19972 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
19973
19974 if (INTEGERP (it->slice.height))
19975 slice.height = XINT (it->slice.height);
19976 else if (FLOATP (it->slice.height))
19977 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
19978
19979 if (slice.x >= img->width)
19980 slice.x = img->width;
19981 if (slice.y >= img->height)
19982 slice.y = img->height;
19983 if (slice.x + slice.width >= img->width)
19984 slice.width = img->width - slice.x;
19985 if (slice.y + slice.height > img->height)
19986 slice.height = img->height - slice.y;
19987
19988 if (slice.width == 0 || slice.height == 0)
19989 return;
19990
19991 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
19992
19993 it->descent = slice.height - glyph_ascent;
19994 if (slice.y == 0)
19995 it->descent += img->vmargin;
19996 if (slice.y + slice.height == img->height)
19997 it->descent += img->vmargin;
19998 it->phys_descent = it->descent;
19999
20000 it->pixel_width = slice.width;
20001 if (slice.x == 0)
20002 it->pixel_width += img->hmargin;
20003 if (slice.x + slice.width == img->width)
20004 it->pixel_width += img->hmargin;
20005
20006 /* It's quite possible for images to have an ascent greater than
20007 their height, so don't get confused in that case. */
20008 if (it->descent < 0)
20009 it->descent = 0;
20010
20011 #if 0 /* this breaks image tiling */
20012 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
20013 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
20014 if (face_ascent > it->ascent)
20015 it->ascent = it->phys_ascent = face_ascent;
20016 #endif
20017
20018 it->nglyphs = 1;
20019
20020 if (face->box != FACE_NO_BOX)
20021 {
20022 if (face->box_line_width > 0)
20023 {
20024 if (slice.y == 0)
20025 it->ascent += face->box_line_width;
20026 if (slice.y + slice.height == img->height)
20027 it->descent += face->box_line_width;
20028 }
20029
20030 if (it->start_of_box_run_p && slice.x == 0)
20031 it->pixel_width += abs (face->box_line_width);
20032 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
20033 it->pixel_width += abs (face->box_line_width);
20034 }
20035
20036 take_vertical_position_into_account (it);
20037
20038 /* Automatically crop wide image glyphs at right edge so we can
20039 draw the cursor on same display row. */
20040 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
20041 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
20042 {
20043 it->pixel_width -= crop;
20044 slice.width -= crop;
20045 }
20046
20047 if (it->glyph_row)
20048 {
20049 struct glyph *glyph;
20050 enum glyph_row_area area = it->area;
20051
20052 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20053 if (glyph < it->glyph_row->glyphs[area + 1])
20054 {
20055 glyph->charpos = CHARPOS (it->position);
20056 glyph->object = it->object;
20057 glyph->pixel_width = it->pixel_width;
20058 glyph->ascent = glyph_ascent;
20059 glyph->descent = it->descent;
20060 glyph->voffset = it->voffset;
20061 glyph->type = IMAGE_GLYPH;
20062 glyph->multibyte_p = it->multibyte_p;
20063 glyph->left_box_line_p = it->start_of_box_run_p;
20064 glyph->right_box_line_p = it->end_of_box_run_p;
20065 glyph->overlaps_vertically_p = 0;
20066 glyph->padding_p = 0;
20067 glyph->glyph_not_available_p = 0;
20068 glyph->face_id = it->face_id;
20069 glyph->u.img_id = img->id;
20070 glyph->slice = slice;
20071 glyph->font_type = FONT_TYPE_UNKNOWN;
20072 ++it->glyph_row->used[area];
20073 }
20074 else
20075 IT_EXPAND_MATRIX_WIDTH (it, area);
20076 }
20077 }
20078
20079
20080 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
20081 of the glyph, WIDTH and HEIGHT are the width and height of the
20082 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
20083
20084 static void
20085 append_stretch_glyph (it, object, width, height, ascent)
20086 struct it *it;
20087 Lisp_Object object;
20088 int width, height;
20089 int ascent;
20090 {
20091 struct glyph *glyph;
20092 enum glyph_row_area area = it->area;
20093
20094 xassert (ascent >= 0 && ascent <= height);
20095
20096 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20097 if (glyph < it->glyph_row->glyphs[area + 1])
20098 {
20099 glyph->charpos = CHARPOS (it->position);
20100 glyph->object = object;
20101 glyph->pixel_width = width;
20102 glyph->ascent = ascent;
20103 glyph->descent = height - ascent;
20104 glyph->voffset = it->voffset;
20105 glyph->type = STRETCH_GLYPH;
20106 glyph->multibyte_p = it->multibyte_p;
20107 glyph->left_box_line_p = it->start_of_box_run_p;
20108 glyph->right_box_line_p = it->end_of_box_run_p;
20109 glyph->overlaps_vertically_p = 0;
20110 glyph->padding_p = 0;
20111 glyph->glyph_not_available_p = 0;
20112 glyph->face_id = it->face_id;
20113 glyph->u.stretch.ascent = ascent;
20114 glyph->u.stretch.height = height;
20115 glyph->slice = null_glyph_slice;
20116 glyph->font_type = FONT_TYPE_UNKNOWN;
20117 ++it->glyph_row->used[area];
20118 }
20119 else
20120 IT_EXPAND_MATRIX_WIDTH (it, area);
20121 }
20122
20123
20124 /* Produce a stretch glyph for iterator IT. IT->object is the value
20125 of the glyph property displayed. The value must be a list
20126 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
20127 being recognized:
20128
20129 1. `:width WIDTH' specifies that the space should be WIDTH *
20130 canonical char width wide. WIDTH may be an integer or floating
20131 point number.
20132
20133 2. `:relative-width FACTOR' specifies that the width of the stretch
20134 should be computed from the width of the first character having the
20135 `glyph' property, and should be FACTOR times that width.
20136
20137 3. `:align-to HPOS' specifies that the space should be wide enough
20138 to reach HPOS, a value in canonical character units.
20139
20140 Exactly one of the above pairs must be present.
20141
20142 4. `:height HEIGHT' specifies that the height of the stretch produced
20143 should be HEIGHT, measured in canonical character units.
20144
20145 5. `:relative-height FACTOR' specifies that the height of the
20146 stretch should be FACTOR times the height of the characters having
20147 the glyph property.
20148
20149 Either none or exactly one of 4 or 5 must be present.
20150
20151 6. `:ascent ASCENT' specifies that ASCENT percent of the height
20152 of the stretch should be used for the ascent of the stretch.
20153 ASCENT must be in the range 0 <= ASCENT <= 100. */
20154
20155 static void
20156 produce_stretch_glyph (it)
20157 struct it *it;
20158 {
20159 /* (space :width WIDTH :height HEIGHT ...) */
20160 Lisp_Object prop, plist;
20161 int width = 0, height = 0, align_to = -1;
20162 int zero_width_ok_p = 0, zero_height_ok_p = 0;
20163 int ascent = 0;
20164 double tem;
20165 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20166 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
20167
20168 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20169
20170 /* List should start with `space'. */
20171 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
20172 plist = XCDR (it->object);
20173
20174 /* Compute the width of the stretch. */
20175 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
20176 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
20177 {
20178 /* Absolute width `:width WIDTH' specified and valid. */
20179 zero_width_ok_p = 1;
20180 width = (int)tem;
20181 }
20182 else if (prop = Fplist_get (plist, QCrelative_width),
20183 NUMVAL (prop) > 0)
20184 {
20185 /* Relative width `:relative-width FACTOR' specified and valid.
20186 Compute the width of the characters having the `glyph'
20187 property. */
20188 struct it it2;
20189 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
20190
20191 it2 = *it;
20192 if (it->multibyte_p)
20193 {
20194 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
20195 - IT_BYTEPOS (*it));
20196 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
20197 }
20198 else
20199 it2.c = *p, it2.len = 1;
20200
20201 it2.glyph_row = NULL;
20202 it2.what = IT_CHARACTER;
20203 x_produce_glyphs (&it2);
20204 width = NUMVAL (prop) * it2.pixel_width;
20205 }
20206 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
20207 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
20208 {
20209 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
20210 align_to = (align_to < 0
20211 ? 0
20212 : align_to - window_box_left_offset (it->w, TEXT_AREA));
20213 else if (align_to < 0)
20214 align_to = window_box_left_offset (it->w, TEXT_AREA);
20215 width = max (0, (int)tem + align_to - it->current_x);
20216 zero_width_ok_p = 1;
20217 }
20218 else
20219 /* Nothing specified -> width defaults to canonical char width. */
20220 width = FRAME_COLUMN_WIDTH (it->f);
20221
20222 if (width <= 0 && (width < 0 || !zero_width_ok_p))
20223 width = 1;
20224
20225 /* Compute height. */
20226 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
20227 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20228 {
20229 height = (int)tem;
20230 zero_height_ok_p = 1;
20231 }
20232 else if (prop = Fplist_get (plist, QCrelative_height),
20233 NUMVAL (prop) > 0)
20234 height = FONT_HEIGHT (font) * NUMVAL (prop);
20235 else
20236 height = FONT_HEIGHT (font);
20237
20238 if (height <= 0 && (height < 0 || !zero_height_ok_p))
20239 height = 1;
20240
20241 /* Compute percentage of height used for ascent. If
20242 `:ascent ASCENT' is present and valid, use that. Otherwise,
20243 derive the ascent from the font in use. */
20244 if (prop = Fplist_get (plist, QCascent),
20245 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
20246 ascent = height * NUMVAL (prop) / 100.0;
20247 else if (!NILP (prop)
20248 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20249 ascent = min (max (0, (int)tem), height);
20250 else
20251 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
20252
20253 if (width > 0 && !it->truncate_lines_p
20254 && it->current_x + width > it->last_visible_x)
20255 width = it->last_visible_x - it->current_x - 1;
20256
20257 if (width > 0 && height > 0 && it->glyph_row)
20258 {
20259 Lisp_Object object = it->stack[it->sp - 1].string;
20260 if (!STRINGP (object))
20261 object = it->w->buffer;
20262 append_stretch_glyph (it, object, width, height, ascent);
20263 }
20264
20265 it->pixel_width = width;
20266 it->ascent = it->phys_ascent = ascent;
20267 it->descent = it->phys_descent = height - it->ascent;
20268 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
20269
20270 take_vertical_position_into_account (it);
20271 }
20272
20273 /* Get line-height and line-spacing property at point.
20274 If line-height has format (HEIGHT TOTAL), return TOTAL
20275 in TOTAL_HEIGHT. */
20276
20277 static Lisp_Object
20278 get_line_height_property (it, prop)
20279 struct it *it;
20280 Lisp_Object prop;
20281 {
20282 Lisp_Object position;
20283
20284 if (STRINGP (it->object))
20285 position = make_number (IT_STRING_CHARPOS (*it));
20286 else if (BUFFERP (it->object))
20287 position = make_number (IT_CHARPOS (*it));
20288 else
20289 return Qnil;
20290
20291 return Fget_char_property (position, prop, it->object);
20292 }
20293
20294 /* Calculate line-height and line-spacing properties.
20295 An integer value specifies explicit pixel value.
20296 A float value specifies relative value to current face height.
20297 A cons (float . face-name) specifies relative value to
20298 height of specified face font.
20299
20300 Returns height in pixels, or nil. */
20301
20302
20303 static Lisp_Object
20304 calc_line_height_property (it, val, font, boff, override)
20305 struct it *it;
20306 Lisp_Object val;
20307 XFontStruct *font;
20308 int boff, override;
20309 {
20310 Lisp_Object face_name = Qnil;
20311 int ascent, descent, height;
20312
20313 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
20314 return val;
20315
20316 if (CONSP (val))
20317 {
20318 face_name = XCAR (val);
20319 val = XCDR (val);
20320 if (!NUMBERP (val))
20321 val = make_number (1);
20322 if (NILP (face_name))
20323 {
20324 height = it->ascent + it->descent;
20325 goto scale;
20326 }
20327 }
20328
20329 if (NILP (face_name))
20330 {
20331 font = FRAME_FONT (it->f);
20332 boff = FRAME_BASELINE_OFFSET (it->f);
20333 }
20334 else if (EQ (face_name, Qt))
20335 {
20336 override = 0;
20337 }
20338 else
20339 {
20340 int face_id;
20341 struct face *face;
20342 struct font_info *font_info;
20343
20344 face_id = lookup_named_face (it->f, face_name, ' ', 0);
20345 if (face_id < 0)
20346 return make_number (-1);
20347
20348 face = FACE_FROM_ID (it->f, face_id);
20349 font = face->font;
20350 if (font == NULL)
20351 return make_number (-1);
20352
20353 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20354 boff = font_info->baseline_offset;
20355 if (font_info->vertical_centering)
20356 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20357 }
20358
20359 ascent = FONT_BASE (font) + boff;
20360 descent = FONT_DESCENT (font) - boff;
20361
20362 if (override)
20363 {
20364 it->override_ascent = ascent;
20365 it->override_descent = descent;
20366 it->override_boff = boff;
20367 }
20368
20369 height = ascent + descent;
20370
20371 scale:
20372 if (FLOATP (val))
20373 height = (int)(XFLOAT_DATA (val) * height);
20374 else if (INTEGERP (val))
20375 height *= XINT (val);
20376
20377 return make_number (height);
20378 }
20379
20380
20381 /* RIF:
20382 Produce glyphs/get display metrics for the display element IT is
20383 loaded with. See the description of struct it in dispextern.h
20384 for an overview of struct it. */
20385
20386 void
20387 x_produce_glyphs (it)
20388 struct it *it;
20389 {
20390 int extra_line_spacing = it->extra_line_spacing;
20391
20392 it->glyph_not_available_p = 0;
20393
20394 if (it->what == IT_CHARACTER)
20395 {
20396 XChar2b char2b;
20397 XFontStruct *font;
20398 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20399 XCharStruct *pcm;
20400 int font_not_found_p;
20401 struct font_info *font_info;
20402 int boff; /* baseline offset */
20403 /* We may change it->multibyte_p upon unibyte<->multibyte
20404 conversion. So, save the current value now and restore it
20405 later.
20406
20407 Note: It seems that we don't have to record multibyte_p in
20408 struct glyph because the character code itself tells if or
20409 not the character is multibyte. Thus, in the future, we must
20410 consider eliminating the field `multibyte_p' in the struct
20411 glyph. */
20412 int saved_multibyte_p = it->multibyte_p;
20413
20414 /* Maybe translate single-byte characters to multibyte, or the
20415 other way. */
20416 it->char_to_display = it->c;
20417 if (!ASCII_BYTE_P (it->c))
20418 {
20419 if (unibyte_display_via_language_environment
20420 && SINGLE_BYTE_CHAR_P (it->c)
20421 && (it->c >= 0240
20422 || !NILP (Vnonascii_translation_table)))
20423 {
20424 it->char_to_display = unibyte_char_to_multibyte (it->c);
20425 it->multibyte_p = 1;
20426 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20427 face = FACE_FROM_ID (it->f, it->face_id);
20428 }
20429 else if (!SINGLE_BYTE_CHAR_P (it->c)
20430 && !it->multibyte_p)
20431 {
20432 it->multibyte_p = 1;
20433 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20434 face = FACE_FROM_ID (it->f, it->face_id);
20435 }
20436 }
20437
20438 /* Get font to use. Encode IT->char_to_display. */
20439 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20440 &char2b, it->multibyte_p, 0);
20441 font = face->font;
20442
20443 /* When no suitable font found, use the default font. */
20444 font_not_found_p = font == NULL;
20445 if (font_not_found_p)
20446 {
20447 font = FRAME_FONT (it->f);
20448 boff = FRAME_BASELINE_OFFSET (it->f);
20449 font_info = NULL;
20450 }
20451 else
20452 {
20453 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20454 boff = font_info->baseline_offset;
20455 if (font_info->vertical_centering)
20456 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20457 }
20458
20459 if (it->char_to_display >= ' '
20460 && (!it->multibyte_p || it->char_to_display < 128))
20461 {
20462 /* Either unibyte or ASCII. */
20463 int stretched_p;
20464
20465 it->nglyphs = 1;
20466
20467 pcm = FRAME_RIF (it->f)->per_char_metric
20468 (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
20469
20470 if (it->override_ascent >= 0)
20471 {
20472 it->ascent = it->override_ascent;
20473 it->descent = it->override_descent;
20474 boff = it->override_boff;
20475 }
20476 else
20477 {
20478 it->ascent = FONT_BASE (font) + boff;
20479 it->descent = FONT_DESCENT (font) - boff;
20480 }
20481
20482 if (pcm)
20483 {
20484 it->phys_ascent = pcm->ascent + boff;
20485 it->phys_descent = pcm->descent - boff;
20486 it->pixel_width = pcm->width;
20487 }
20488 else
20489 {
20490 it->glyph_not_available_p = 1;
20491 it->phys_ascent = it->ascent;
20492 it->phys_descent = it->descent;
20493 it->pixel_width = FONT_WIDTH (font);
20494 }
20495
20496 if (it->constrain_row_ascent_descent_p)
20497 {
20498 if (it->descent > it->max_descent)
20499 {
20500 it->ascent += it->descent - it->max_descent;
20501 it->descent = it->max_descent;
20502 }
20503 if (it->ascent > it->max_ascent)
20504 {
20505 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20506 it->ascent = it->max_ascent;
20507 }
20508 it->phys_ascent = min (it->phys_ascent, it->ascent);
20509 it->phys_descent = min (it->phys_descent, it->descent);
20510 extra_line_spacing = 0;
20511 }
20512
20513 /* If this is a space inside a region of text with
20514 `space-width' property, change its width. */
20515 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
20516 if (stretched_p)
20517 it->pixel_width *= XFLOATINT (it->space_width);
20518
20519 /* If face has a box, add the box thickness to the character
20520 height. If character has a box line to the left and/or
20521 right, add the box line width to the character's width. */
20522 if (face->box != FACE_NO_BOX)
20523 {
20524 int thick = face->box_line_width;
20525
20526 if (thick > 0)
20527 {
20528 it->ascent += thick;
20529 it->descent += thick;
20530 }
20531 else
20532 thick = -thick;
20533
20534 if (it->start_of_box_run_p)
20535 it->pixel_width += thick;
20536 if (it->end_of_box_run_p)
20537 it->pixel_width += thick;
20538 }
20539
20540 /* If face has an overline, add the height of the overline
20541 (1 pixel) and a 1 pixel margin to the character height. */
20542 if (face->overline_p)
20543 it->ascent += overline_margin;
20544
20545 if (it->constrain_row_ascent_descent_p)
20546 {
20547 if (it->ascent > it->max_ascent)
20548 it->ascent = it->max_ascent;
20549 if (it->descent > it->max_descent)
20550 it->descent = it->max_descent;
20551 }
20552
20553 take_vertical_position_into_account (it);
20554
20555 /* If we have to actually produce glyphs, do it. */
20556 if (it->glyph_row)
20557 {
20558 if (stretched_p)
20559 {
20560 /* Translate a space with a `space-width' property
20561 into a stretch glyph. */
20562 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
20563 / FONT_HEIGHT (font));
20564 append_stretch_glyph (it, it->object, it->pixel_width,
20565 it->ascent + it->descent, ascent);
20566 }
20567 else
20568 append_glyph (it);
20569
20570 /* If characters with lbearing or rbearing are displayed
20571 in this line, record that fact in a flag of the
20572 glyph row. This is used to optimize X output code. */
20573 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
20574 it->glyph_row->contains_overlapping_glyphs_p = 1;
20575 }
20576 }
20577 else if (it->char_to_display == '\n')
20578 {
20579 /* A newline has no width but we need the height of the line.
20580 But if previous part of the line set a height, don't
20581 increase that height */
20582
20583 Lisp_Object height;
20584 Lisp_Object total_height = Qnil;
20585
20586 it->override_ascent = -1;
20587 it->pixel_width = 0;
20588 it->nglyphs = 0;
20589
20590 height = get_line_height_property(it, Qline_height);
20591 /* Split (line-height total-height) list */
20592 if (CONSP (height)
20593 && CONSP (XCDR (height))
20594 && NILP (XCDR (XCDR (height))))
20595 {
20596 total_height = XCAR (XCDR (height));
20597 height = XCAR (height);
20598 }
20599 height = calc_line_height_property(it, height, font, boff, 1);
20600
20601 if (it->override_ascent >= 0)
20602 {
20603 it->ascent = it->override_ascent;
20604 it->descent = it->override_descent;
20605 boff = it->override_boff;
20606 }
20607 else
20608 {
20609 it->ascent = FONT_BASE (font) + boff;
20610 it->descent = FONT_DESCENT (font) - boff;
20611 }
20612
20613 if (EQ (height, Qt))
20614 {
20615 if (it->descent > it->max_descent)
20616 {
20617 it->ascent += it->descent - it->max_descent;
20618 it->descent = it->max_descent;
20619 }
20620 if (it->ascent > it->max_ascent)
20621 {
20622 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20623 it->ascent = it->max_ascent;
20624 }
20625 it->phys_ascent = min (it->phys_ascent, it->ascent);
20626 it->phys_descent = min (it->phys_descent, it->descent);
20627 it->constrain_row_ascent_descent_p = 1;
20628 extra_line_spacing = 0;
20629 }
20630 else
20631 {
20632 Lisp_Object spacing;
20633
20634 it->phys_ascent = it->ascent;
20635 it->phys_descent = it->descent;
20636
20637 if ((it->max_ascent > 0 || it->max_descent > 0)
20638 && face->box != FACE_NO_BOX
20639 && face->box_line_width > 0)
20640 {
20641 it->ascent += face->box_line_width;
20642 it->descent += face->box_line_width;
20643 }
20644 if (!NILP (height)
20645 && XINT (height) > it->ascent + it->descent)
20646 it->ascent = XINT (height) - it->descent;
20647
20648 if (!NILP (total_height))
20649 spacing = calc_line_height_property(it, total_height, font, boff, 0);
20650 else
20651 {
20652 spacing = get_line_height_property(it, Qline_spacing);
20653 spacing = calc_line_height_property(it, spacing, font, boff, 0);
20654 }
20655 if (INTEGERP (spacing))
20656 {
20657 extra_line_spacing = XINT (spacing);
20658 if (!NILP (total_height))
20659 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20660 }
20661 }
20662 }
20663 else if (it->char_to_display == '\t')
20664 {
20665 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
20666 int x = it->current_x + it->continuation_lines_width;
20667 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
20668
20669 /* If the distance from the current position to the next tab
20670 stop is less than a space character width, use the
20671 tab stop after that. */
20672 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
20673 next_tab_x += tab_width;
20674
20675 it->pixel_width = next_tab_x - x;
20676 it->nglyphs = 1;
20677 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
20678 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
20679
20680 if (it->glyph_row)
20681 {
20682 append_stretch_glyph (it, it->object, it->pixel_width,
20683 it->ascent + it->descent, it->ascent);
20684 }
20685 }
20686 else
20687 {
20688 /* A multi-byte character. Assume that the display width of the
20689 character is the width of the character multiplied by the
20690 width of the font. */
20691
20692 /* If we found a font, this font should give us the right
20693 metrics. If we didn't find a font, use the frame's
20694 default font and calculate the width of the character
20695 from the charset width; this is what old redisplay code
20696 did. */
20697
20698 pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
20699 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
20700
20701 if (font_not_found_p || !pcm)
20702 {
20703 int charset = CHAR_CHARSET (it->char_to_display);
20704
20705 it->glyph_not_available_p = 1;
20706 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
20707 * CHARSET_WIDTH (charset));
20708 it->phys_ascent = FONT_BASE (font) + boff;
20709 it->phys_descent = FONT_DESCENT (font) - boff;
20710 }
20711 else
20712 {
20713 it->pixel_width = pcm->width;
20714 it->phys_ascent = pcm->ascent + boff;
20715 it->phys_descent = pcm->descent - boff;
20716 if (it->glyph_row
20717 && (pcm->lbearing < 0
20718 || pcm->rbearing > pcm->width))
20719 it->glyph_row->contains_overlapping_glyphs_p = 1;
20720 }
20721 it->nglyphs = 1;
20722 it->ascent = FONT_BASE (font) + boff;
20723 it->descent = FONT_DESCENT (font) - boff;
20724 if (face->box != FACE_NO_BOX)
20725 {
20726 int thick = face->box_line_width;
20727
20728 if (thick > 0)
20729 {
20730 it->ascent += thick;
20731 it->descent += thick;
20732 }
20733 else
20734 thick = - thick;
20735
20736 if (it->start_of_box_run_p)
20737 it->pixel_width += thick;
20738 if (it->end_of_box_run_p)
20739 it->pixel_width += thick;
20740 }
20741
20742 /* If face has an overline, add the height of the overline
20743 (1 pixel) and a 1 pixel margin to the character height. */
20744 if (face->overline_p)
20745 it->ascent += overline_margin;
20746
20747 take_vertical_position_into_account (it);
20748
20749 if (it->glyph_row)
20750 append_glyph (it);
20751 }
20752 it->multibyte_p = saved_multibyte_p;
20753 }
20754 else if (it->what == IT_COMPOSITION)
20755 {
20756 /* Note: A composition is represented as one glyph in the
20757 glyph matrix. There are no padding glyphs. */
20758 XChar2b char2b;
20759 XFontStruct *font;
20760 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20761 XCharStruct *pcm;
20762 int font_not_found_p;
20763 struct font_info *font_info;
20764 int boff; /* baseline offset */
20765 struct composition *cmp = composition_table[it->cmp_id];
20766
20767 /* Maybe translate single-byte characters to multibyte. */
20768 it->char_to_display = it->c;
20769 if (unibyte_display_via_language_environment
20770 && SINGLE_BYTE_CHAR_P (it->c)
20771 && (it->c >= 0240
20772 || (it->c >= 0200
20773 && !NILP (Vnonascii_translation_table))))
20774 {
20775 it->char_to_display = unibyte_char_to_multibyte (it->c);
20776 }
20777
20778 /* Get face and font to use. Encode IT->char_to_display. */
20779 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20780 face = FACE_FROM_ID (it->f, it->face_id);
20781 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20782 &char2b, it->multibyte_p, 0);
20783 font = face->font;
20784
20785 /* When no suitable font found, use the default font. */
20786 font_not_found_p = font == NULL;
20787 if (font_not_found_p)
20788 {
20789 font = FRAME_FONT (it->f);
20790 boff = FRAME_BASELINE_OFFSET (it->f);
20791 font_info = NULL;
20792 }
20793 else
20794 {
20795 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20796 boff = font_info->baseline_offset;
20797 if (font_info->vertical_centering)
20798 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20799 }
20800
20801 /* There are no padding glyphs, so there is only one glyph to
20802 produce for the composition. Important is that pixel_width,
20803 ascent and descent are the values of what is drawn by
20804 draw_glyphs (i.e. the values of the overall glyphs composed). */
20805 it->nglyphs = 1;
20806
20807 /* If we have not yet calculated pixel size data of glyphs of
20808 the composition for the current face font, calculate them
20809 now. Theoretically, we have to check all fonts for the
20810 glyphs, but that requires much time and memory space. So,
20811 here we check only the font of the first glyph. This leads
20812 to incorrect display very rarely, and C-l (recenter) can
20813 correct the display anyway. */
20814 if (cmp->font != (void *) font)
20815 {
20816 /* Ascent and descent of the font of the first character of
20817 this composition (adjusted by baseline offset). Ascent
20818 and descent of overall glyphs should not be less than
20819 them respectively. */
20820 int font_ascent = FONT_BASE (font) + boff;
20821 int font_descent = FONT_DESCENT (font) - boff;
20822 /* Bounding box of the overall glyphs. */
20823 int leftmost, rightmost, lowest, highest;
20824 int i, width, ascent, descent;
20825
20826 cmp->font = (void *) font;
20827
20828 /* Initialize the bounding box. */
20829 if (font_info
20830 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
20831 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
20832 {
20833 width = pcm->width;
20834 ascent = pcm->ascent;
20835 descent = pcm->descent;
20836 }
20837 else
20838 {
20839 width = FONT_WIDTH (font);
20840 ascent = FONT_BASE (font);
20841 descent = FONT_DESCENT (font);
20842 }
20843
20844 rightmost = width;
20845 lowest = - descent + boff;
20846 highest = ascent + boff;
20847 leftmost = 0;
20848
20849 if (font_info
20850 && font_info->default_ascent
20851 && CHAR_TABLE_P (Vuse_default_ascent)
20852 && !NILP (Faref (Vuse_default_ascent,
20853 make_number (it->char_to_display))))
20854 highest = font_info->default_ascent + boff;
20855
20856 /* Draw the first glyph at the normal position. It may be
20857 shifted to right later if some other glyphs are drawn at
20858 the left. */
20859 cmp->offsets[0] = 0;
20860 cmp->offsets[1] = boff;
20861
20862 /* Set cmp->offsets for the remaining glyphs. */
20863 for (i = 1; i < cmp->glyph_len; i++)
20864 {
20865 int left, right, btm, top;
20866 int ch = COMPOSITION_GLYPH (cmp, i);
20867 int face_id = FACE_FOR_CHAR (it->f, face, ch);
20868
20869 face = FACE_FROM_ID (it->f, face_id);
20870 get_char_face_and_encoding (it->f, ch, face->id,
20871 &char2b, it->multibyte_p, 0);
20872 font = face->font;
20873 if (font == NULL)
20874 {
20875 font = FRAME_FONT (it->f);
20876 boff = FRAME_BASELINE_OFFSET (it->f);
20877 font_info = NULL;
20878 }
20879 else
20880 {
20881 font_info
20882 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20883 boff = font_info->baseline_offset;
20884 if (font_info->vertical_centering)
20885 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20886 }
20887
20888 if (font_info
20889 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
20890 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
20891 {
20892 width = pcm->width;
20893 ascent = pcm->ascent;
20894 descent = pcm->descent;
20895 }
20896 else
20897 {
20898 width = FONT_WIDTH (font);
20899 ascent = 1;
20900 descent = 0;
20901 }
20902
20903 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
20904 {
20905 /* Relative composition with or without
20906 alternate chars. */
20907 left = (leftmost + rightmost - width) / 2;
20908 btm = - descent + boff;
20909 if (font_info && font_info->relative_compose
20910 && (! CHAR_TABLE_P (Vignore_relative_composition)
20911 || NILP (Faref (Vignore_relative_composition,
20912 make_number (ch)))))
20913 {
20914
20915 if (- descent >= font_info->relative_compose)
20916 /* One extra pixel between two glyphs. */
20917 btm = highest + 1;
20918 else if (ascent <= 0)
20919 /* One extra pixel between two glyphs. */
20920 btm = lowest - 1 - ascent - descent;
20921 }
20922 }
20923 else
20924 {
20925 /* A composition rule is specified by an integer
20926 value that encodes global and new reference
20927 points (GREF and NREF). GREF and NREF are
20928 specified by numbers as below:
20929
20930 0---1---2 -- ascent
20931 | |
20932 | |
20933 | |
20934 9--10--11 -- center
20935 | |
20936 ---3---4---5--- baseline
20937 | |
20938 6---7---8 -- descent
20939 */
20940 int rule = COMPOSITION_RULE (cmp, i);
20941 int gref, nref, grefx, grefy, nrefx, nrefy;
20942
20943 COMPOSITION_DECODE_RULE (rule, gref, nref);
20944 grefx = gref % 3, nrefx = nref % 3;
20945 grefy = gref / 3, nrefy = nref / 3;
20946
20947 left = (leftmost
20948 + grefx * (rightmost - leftmost) / 2
20949 - nrefx * width / 2);
20950 btm = ((grefy == 0 ? highest
20951 : grefy == 1 ? 0
20952 : grefy == 2 ? lowest
20953 : (highest + lowest) / 2)
20954 - (nrefy == 0 ? ascent + descent
20955 : nrefy == 1 ? descent - boff
20956 : nrefy == 2 ? 0
20957 : (ascent + descent) / 2));
20958 }
20959
20960 cmp->offsets[i * 2] = left;
20961 cmp->offsets[i * 2 + 1] = btm + descent;
20962
20963 /* Update the bounding box of the overall glyphs. */
20964 right = left + width;
20965 top = btm + descent + ascent;
20966 if (left < leftmost)
20967 leftmost = left;
20968 if (right > rightmost)
20969 rightmost = right;
20970 if (top > highest)
20971 highest = top;
20972 if (btm < lowest)
20973 lowest = btm;
20974 }
20975
20976 /* If there are glyphs whose x-offsets are negative,
20977 shift all glyphs to the right and make all x-offsets
20978 non-negative. */
20979 if (leftmost < 0)
20980 {
20981 for (i = 0; i < cmp->glyph_len; i++)
20982 cmp->offsets[i * 2] -= leftmost;
20983 rightmost -= leftmost;
20984 }
20985
20986 cmp->pixel_width = rightmost;
20987 cmp->ascent = highest;
20988 cmp->descent = - lowest;
20989 if (cmp->ascent < font_ascent)
20990 cmp->ascent = font_ascent;
20991 if (cmp->descent < font_descent)
20992 cmp->descent = font_descent;
20993 }
20994
20995 it->pixel_width = cmp->pixel_width;
20996 it->ascent = it->phys_ascent = cmp->ascent;
20997 it->descent = it->phys_descent = cmp->descent;
20998
20999 if (face->box != FACE_NO_BOX)
21000 {
21001 int thick = face->box_line_width;
21002
21003 if (thick > 0)
21004 {
21005 it->ascent += thick;
21006 it->descent += thick;
21007 }
21008 else
21009 thick = - thick;
21010
21011 if (it->start_of_box_run_p)
21012 it->pixel_width += thick;
21013 if (it->end_of_box_run_p)
21014 it->pixel_width += thick;
21015 }
21016
21017 /* If face has an overline, add the height of the overline
21018 (1 pixel) and a 1 pixel margin to the character height. */
21019 if (face->overline_p)
21020 it->ascent += overline_margin;
21021
21022 take_vertical_position_into_account (it);
21023
21024 if (it->glyph_row)
21025 append_composite_glyph (it);
21026 }
21027 else if (it->what == IT_IMAGE)
21028 produce_image_glyph (it);
21029 else if (it->what == IT_STRETCH)
21030 produce_stretch_glyph (it);
21031
21032 /* Accumulate dimensions. Note: can't assume that it->descent > 0
21033 because this isn't true for images with `:ascent 100'. */
21034 xassert (it->ascent >= 0 && it->descent >= 0);
21035 if (it->area == TEXT_AREA)
21036 it->current_x += it->pixel_width;
21037
21038 if (extra_line_spacing > 0)
21039 {
21040 it->descent += extra_line_spacing;
21041 if (extra_line_spacing > it->max_extra_line_spacing)
21042 it->max_extra_line_spacing = extra_line_spacing;
21043 }
21044
21045 it->max_ascent = max (it->max_ascent, it->ascent);
21046 it->max_descent = max (it->max_descent, it->descent);
21047 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
21048 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
21049 }
21050
21051 /* EXPORT for RIF:
21052 Output LEN glyphs starting at START at the nominal cursor position.
21053 Advance the nominal cursor over the text. The global variable
21054 updated_window contains the window being updated, updated_row is
21055 the glyph row being updated, and updated_area is the area of that
21056 row being updated. */
21057
21058 void
21059 x_write_glyphs (start, len)
21060 struct glyph *start;
21061 int len;
21062 {
21063 int x, hpos;
21064
21065 xassert (updated_window && updated_row);
21066 BLOCK_INPUT;
21067
21068 /* Write glyphs. */
21069
21070 hpos = start - updated_row->glyphs[updated_area];
21071 x = draw_glyphs (updated_window, output_cursor.x,
21072 updated_row, updated_area,
21073 hpos, hpos + len,
21074 DRAW_NORMAL_TEXT, 0);
21075
21076 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
21077 if (updated_area == TEXT_AREA
21078 && updated_window->phys_cursor_on_p
21079 && updated_window->phys_cursor.vpos == output_cursor.vpos
21080 && updated_window->phys_cursor.hpos >= hpos
21081 && updated_window->phys_cursor.hpos < hpos + len)
21082 updated_window->phys_cursor_on_p = 0;
21083
21084 UNBLOCK_INPUT;
21085
21086 /* Advance the output cursor. */
21087 output_cursor.hpos += len;
21088 output_cursor.x = x;
21089 }
21090
21091
21092 /* EXPORT for RIF:
21093 Insert LEN glyphs from START at the nominal cursor position. */
21094
21095 void
21096 x_insert_glyphs (start, len)
21097 struct glyph *start;
21098 int len;
21099 {
21100 struct frame *f;
21101 struct window *w;
21102 int line_height, shift_by_width, shifted_region_width;
21103 struct glyph_row *row;
21104 struct glyph *glyph;
21105 int frame_x, frame_y, hpos;
21106
21107 xassert (updated_window && updated_row);
21108 BLOCK_INPUT;
21109 w = updated_window;
21110 f = XFRAME (WINDOW_FRAME (w));
21111
21112 /* Get the height of the line we are in. */
21113 row = updated_row;
21114 line_height = row->height;
21115
21116 /* Get the width of the glyphs to insert. */
21117 shift_by_width = 0;
21118 for (glyph = start; glyph < start + len; ++glyph)
21119 shift_by_width += glyph->pixel_width;
21120
21121 /* Get the width of the region to shift right. */
21122 shifted_region_width = (window_box_width (w, updated_area)
21123 - output_cursor.x
21124 - shift_by_width);
21125
21126 /* Shift right. */
21127 frame_x = window_box_left (w, updated_area) + output_cursor.x;
21128 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
21129
21130 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
21131 line_height, shift_by_width);
21132
21133 /* Write the glyphs. */
21134 hpos = start - row->glyphs[updated_area];
21135 draw_glyphs (w, output_cursor.x, row, updated_area,
21136 hpos, hpos + len,
21137 DRAW_NORMAL_TEXT, 0);
21138
21139 /* Advance the output cursor. */
21140 output_cursor.hpos += len;
21141 output_cursor.x += shift_by_width;
21142 UNBLOCK_INPUT;
21143 }
21144
21145
21146 /* EXPORT for RIF:
21147 Erase the current text line from the nominal cursor position
21148 (inclusive) to pixel column TO_X (exclusive). The idea is that
21149 everything from TO_X onward is already erased.
21150
21151 TO_X is a pixel position relative to updated_area of
21152 updated_window. TO_X == -1 means clear to the end of this area. */
21153
21154 void
21155 x_clear_end_of_line (to_x)
21156 int to_x;
21157 {
21158 struct frame *f;
21159 struct window *w = updated_window;
21160 int max_x, min_y, max_y;
21161 int from_x, from_y, to_y;
21162
21163 xassert (updated_window && updated_row);
21164 f = XFRAME (w->frame);
21165
21166 if (updated_row->full_width_p)
21167 max_x = WINDOW_TOTAL_WIDTH (w);
21168 else
21169 max_x = window_box_width (w, updated_area);
21170 max_y = window_text_bottom_y (w);
21171
21172 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
21173 of window. For TO_X > 0, truncate to end of drawing area. */
21174 if (to_x == 0)
21175 return;
21176 else if (to_x < 0)
21177 to_x = max_x;
21178 else
21179 to_x = min (to_x, max_x);
21180
21181 to_y = min (max_y, output_cursor.y + updated_row->height);
21182
21183 /* Notice if the cursor will be cleared by this operation. */
21184 if (!updated_row->full_width_p)
21185 notice_overwritten_cursor (w, updated_area,
21186 output_cursor.x, -1,
21187 updated_row->y,
21188 MATRIX_ROW_BOTTOM_Y (updated_row));
21189
21190 from_x = output_cursor.x;
21191
21192 /* Translate to frame coordinates. */
21193 if (updated_row->full_width_p)
21194 {
21195 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
21196 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
21197 }
21198 else
21199 {
21200 int area_left = window_box_left (w, updated_area);
21201 from_x += area_left;
21202 to_x += area_left;
21203 }
21204
21205 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
21206 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
21207 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
21208
21209 /* Prevent inadvertently clearing to end of the X window. */
21210 if (to_x > from_x && to_y > from_y)
21211 {
21212 BLOCK_INPUT;
21213 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
21214 to_x - from_x, to_y - from_y);
21215 UNBLOCK_INPUT;
21216 }
21217 }
21218
21219 #endif /* HAVE_WINDOW_SYSTEM */
21220
21221
21222 \f
21223 /***********************************************************************
21224 Cursor types
21225 ***********************************************************************/
21226
21227 /* Value is the internal representation of the specified cursor type
21228 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
21229 of the bar cursor. */
21230
21231 static enum text_cursor_kinds
21232 get_specified_cursor_type (arg, width)
21233 Lisp_Object arg;
21234 int *width;
21235 {
21236 enum text_cursor_kinds type;
21237
21238 if (NILP (arg))
21239 return NO_CURSOR;
21240
21241 if (EQ (arg, Qbox))
21242 return FILLED_BOX_CURSOR;
21243
21244 if (EQ (arg, Qhollow))
21245 return HOLLOW_BOX_CURSOR;
21246
21247 if (EQ (arg, Qbar))
21248 {
21249 *width = 2;
21250 return BAR_CURSOR;
21251 }
21252
21253 if (CONSP (arg)
21254 && EQ (XCAR (arg), Qbar)
21255 && INTEGERP (XCDR (arg))
21256 && XINT (XCDR (arg)) >= 0)
21257 {
21258 *width = XINT (XCDR (arg));
21259 return BAR_CURSOR;
21260 }
21261
21262 if (EQ (arg, Qhbar))
21263 {
21264 *width = 2;
21265 return HBAR_CURSOR;
21266 }
21267
21268 if (CONSP (arg)
21269 && EQ (XCAR (arg), Qhbar)
21270 && INTEGERP (XCDR (arg))
21271 && XINT (XCDR (arg)) >= 0)
21272 {
21273 *width = XINT (XCDR (arg));
21274 return HBAR_CURSOR;
21275 }
21276
21277 /* Treat anything unknown as "hollow box cursor".
21278 It was bad to signal an error; people have trouble fixing
21279 .Xdefaults with Emacs, when it has something bad in it. */
21280 type = HOLLOW_BOX_CURSOR;
21281
21282 return type;
21283 }
21284
21285 /* Set the default cursor types for specified frame. */
21286 void
21287 set_frame_cursor_types (f, arg)
21288 struct frame *f;
21289 Lisp_Object arg;
21290 {
21291 int width;
21292 Lisp_Object tem;
21293
21294 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
21295 FRAME_CURSOR_WIDTH (f) = width;
21296
21297 /* By default, set up the blink-off state depending on the on-state. */
21298
21299 tem = Fassoc (arg, Vblink_cursor_alist);
21300 if (!NILP (tem))
21301 {
21302 FRAME_BLINK_OFF_CURSOR (f)
21303 = get_specified_cursor_type (XCDR (tem), &width);
21304 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
21305 }
21306 else
21307 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
21308 }
21309
21310
21311 /* Return the cursor we want to be displayed in window W. Return
21312 width of bar/hbar cursor through WIDTH arg. Return with
21313 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
21314 (i.e. if the `system caret' should track this cursor).
21315
21316 In a mini-buffer window, we want the cursor only to appear if we
21317 are reading input from this window. For the selected window, we
21318 want the cursor type given by the frame parameter or buffer local
21319 setting of cursor-type. If explicitly marked off, draw no cursor.
21320 In all other cases, we want a hollow box cursor. */
21321
21322 static enum text_cursor_kinds
21323 get_window_cursor_type (w, glyph, width, active_cursor)
21324 struct window *w;
21325 struct glyph *glyph;
21326 int *width;
21327 int *active_cursor;
21328 {
21329 struct frame *f = XFRAME (w->frame);
21330 struct buffer *b = XBUFFER (w->buffer);
21331 int cursor_type = DEFAULT_CURSOR;
21332 Lisp_Object alt_cursor;
21333 int non_selected = 0;
21334
21335 *active_cursor = 1;
21336
21337 /* Echo area */
21338 if (cursor_in_echo_area
21339 && FRAME_HAS_MINIBUF_P (f)
21340 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
21341 {
21342 if (w == XWINDOW (echo_area_window))
21343 {
21344 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
21345 {
21346 *width = FRAME_CURSOR_WIDTH (f);
21347 return FRAME_DESIRED_CURSOR (f);
21348 }
21349 else
21350 return get_specified_cursor_type (b->cursor_type, width);
21351 }
21352
21353 *active_cursor = 0;
21354 non_selected = 1;
21355 }
21356
21357 /* Nonselected window or nonselected frame. */
21358 else if (w != XWINDOW (f->selected_window)
21359 #ifdef HAVE_WINDOW_SYSTEM
21360 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
21361 #endif
21362 )
21363 {
21364 *active_cursor = 0;
21365
21366 if (MINI_WINDOW_P (w) && minibuf_level == 0)
21367 return NO_CURSOR;
21368
21369 non_selected = 1;
21370 }
21371
21372 /* Never display a cursor in a window in which cursor-type is nil. */
21373 if (NILP (b->cursor_type))
21374 return NO_CURSOR;
21375
21376 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
21377 if (non_selected)
21378 {
21379 alt_cursor = b->cursor_in_non_selected_windows;
21380 return get_specified_cursor_type (alt_cursor, width);
21381 }
21382
21383 /* Get the normal cursor type for this window. */
21384 if (EQ (b->cursor_type, Qt))
21385 {
21386 cursor_type = FRAME_DESIRED_CURSOR (f);
21387 *width = FRAME_CURSOR_WIDTH (f);
21388 }
21389 else
21390 cursor_type = get_specified_cursor_type (b->cursor_type, width);
21391
21392 /* Use normal cursor if not blinked off. */
21393 if (!w->cursor_off_p)
21394 {
21395 #ifdef HAVE_WINDOW_SYSTEM
21396 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21397 {
21398 if (cursor_type == FILLED_BOX_CURSOR)
21399 {
21400 /* Using a block cursor on large images can be very annoying.
21401 So use a hollow cursor for "large" images.
21402 If image is not transparent (no mask), also use hollow cursor. */
21403 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21404 if (img != NULL && IMAGEP (img->spec))
21405 {
21406 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
21407 where N = size of default frame font size.
21408 This should cover most of the "tiny" icons people may use. */
21409 if (!img->mask
21410 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
21411 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
21412 cursor_type = HOLLOW_BOX_CURSOR;
21413 }
21414 }
21415 else if (cursor_type != NO_CURSOR)
21416 {
21417 /* Display current only supports BOX and HOLLOW cursors for images.
21418 So for now, unconditionally use a HOLLOW cursor when cursor is
21419 not a solid box cursor. */
21420 cursor_type = HOLLOW_BOX_CURSOR;
21421 }
21422 }
21423 #endif
21424 return cursor_type;
21425 }
21426
21427 /* Cursor is blinked off, so determine how to "toggle" it. */
21428
21429 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
21430 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
21431 return get_specified_cursor_type (XCDR (alt_cursor), width);
21432
21433 /* Then see if frame has specified a specific blink off cursor type. */
21434 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
21435 {
21436 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
21437 return FRAME_BLINK_OFF_CURSOR (f);
21438 }
21439
21440 #if 0
21441 /* Some people liked having a permanently visible blinking cursor,
21442 while others had very strong opinions against it. So it was
21443 decided to remove it. KFS 2003-09-03 */
21444
21445 /* Finally perform built-in cursor blinking:
21446 filled box <-> hollow box
21447 wide [h]bar <-> narrow [h]bar
21448 narrow [h]bar <-> no cursor
21449 other type <-> no cursor */
21450
21451 if (cursor_type == FILLED_BOX_CURSOR)
21452 return HOLLOW_BOX_CURSOR;
21453
21454 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
21455 {
21456 *width = 1;
21457 return cursor_type;
21458 }
21459 #endif
21460
21461 return NO_CURSOR;
21462 }
21463
21464
21465 #ifdef HAVE_WINDOW_SYSTEM
21466
21467 /* Notice when the text cursor of window W has been completely
21468 overwritten by a drawing operation that outputs glyphs in AREA
21469 starting at X0 and ending at X1 in the line starting at Y0 and
21470 ending at Y1. X coordinates are area-relative. X1 < 0 means all
21471 the rest of the line after X0 has been written. Y coordinates
21472 are window-relative. */
21473
21474 static void
21475 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
21476 struct window *w;
21477 enum glyph_row_area area;
21478 int x0, y0, x1, y1;
21479 {
21480 int cx0, cx1, cy0, cy1;
21481 struct glyph_row *row;
21482
21483 if (!w->phys_cursor_on_p)
21484 return;
21485 if (area != TEXT_AREA)
21486 return;
21487
21488 if (w->phys_cursor.vpos < 0
21489 || w->phys_cursor.vpos >= w->current_matrix->nrows
21490 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
21491 !(row->enabled_p && row->displays_text_p)))
21492 return;
21493
21494 if (row->cursor_in_fringe_p)
21495 {
21496 row->cursor_in_fringe_p = 0;
21497 draw_fringe_bitmap (w, row, 0);
21498 w->phys_cursor_on_p = 0;
21499 return;
21500 }
21501
21502 cx0 = w->phys_cursor.x;
21503 cx1 = cx0 + w->phys_cursor_width;
21504 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
21505 return;
21506
21507 /* The cursor image will be completely removed from the
21508 screen if the output area intersects the cursor area in
21509 y-direction. When we draw in [y0 y1[, and some part of
21510 the cursor is at y < y0, that part must have been drawn
21511 before. When scrolling, the cursor is erased before
21512 actually scrolling, so we don't come here. When not
21513 scrolling, the rows above the old cursor row must have
21514 changed, and in this case these rows must have written
21515 over the cursor image.
21516
21517 Likewise if part of the cursor is below y1, with the
21518 exception of the cursor being in the first blank row at
21519 the buffer and window end because update_text_area
21520 doesn't draw that row. (Except when it does, but
21521 that's handled in update_text_area.) */
21522
21523 cy0 = w->phys_cursor.y;
21524 cy1 = cy0 + w->phys_cursor_height;
21525 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
21526 return;
21527
21528 w->phys_cursor_on_p = 0;
21529 }
21530
21531 #endif /* HAVE_WINDOW_SYSTEM */
21532
21533 \f
21534 /************************************************************************
21535 Mouse Face
21536 ************************************************************************/
21537
21538 #ifdef HAVE_WINDOW_SYSTEM
21539
21540 /* EXPORT for RIF:
21541 Fix the display of area AREA of overlapping row ROW in window W
21542 with respect to the overlapping part OVERLAPS. */
21543
21544 void
21545 x_fix_overlapping_area (w, row, area, overlaps)
21546 struct window *w;
21547 struct glyph_row *row;
21548 enum glyph_row_area area;
21549 int overlaps;
21550 {
21551 int i, x;
21552
21553 BLOCK_INPUT;
21554
21555 x = 0;
21556 for (i = 0; i < row->used[area];)
21557 {
21558 if (row->glyphs[area][i].overlaps_vertically_p)
21559 {
21560 int start = i, start_x = x;
21561
21562 do
21563 {
21564 x += row->glyphs[area][i].pixel_width;
21565 ++i;
21566 }
21567 while (i < row->used[area]
21568 && row->glyphs[area][i].overlaps_vertically_p);
21569
21570 draw_glyphs (w, start_x, row, area,
21571 start, i,
21572 DRAW_NORMAL_TEXT, overlaps);
21573 }
21574 else
21575 {
21576 x += row->glyphs[area][i].pixel_width;
21577 ++i;
21578 }
21579 }
21580
21581 UNBLOCK_INPUT;
21582 }
21583
21584
21585 /* EXPORT:
21586 Draw the cursor glyph of window W in glyph row ROW. See the
21587 comment of draw_glyphs for the meaning of HL. */
21588
21589 void
21590 draw_phys_cursor_glyph (w, row, hl)
21591 struct window *w;
21592 struct glyph_row *row;
21593 enum draw_glyphs_face hl;
21594 {
21595 /* If cursor hpos is out of bounds, don't draw garbage. This can
21596 happen in mini-buffer windows when switching between echo area
21597 glyphs and mini-buffer. */
21598 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
21599 {
21600 int on_p = w->phys_cursor_on_p;
21601 int x1;
21602 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
21603 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
21604 hl, 0);
21605 w->phys_cursor_on_p = on_p;
21606
21607 if (hl == DRAW_CURSOR)
21608 w->phys_cursor_width = x1 - w->phys_cursor.x;
21609 /* When we erase the cursor, and ROW is overlapped by other
21610 rows, make sure that these overlapping parts of other rows
21611 are redrawn. */
21612 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
21613 {
21614 w->phys_cursor_width = x1 - w->phys_cursor.x;
21615
21616 if (row > w->current_matrix->rows
21617 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
21618 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
21619 OVERLAPS_ERASED_CURSOR);
21620
21621 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
21622 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
21623 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
21624 OVERLAPS_ERASED_CURSOR);
21625 }
21626 }
21627 }
21628
21629
21630 /* EXPORT:
21631 Erase the image of a cursor of window W from the screen. */
21632
21633 void
21634 erase_phys_cursor (w)
21635 struct window *w;
21636 {
21637 struct frame *f = XFRAME (w->frame);
21638 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21639 int hpos = w->phys_cursor.hpos;
21640 int vpos = w->phys_cursor.vpos;
21641 int mouse_face_here_p = 0;
21642 struct glyph_matrix *active_glyphs = w->current_matrix;
21643 struct glyph_row *cursor_row;
21644 struct glyph *cursor_glyph;
21645 enum draw_glyphs_face hl;
21646
21647 /* No cursor displayed or row invalidated => nothing to do on the
21648 screen. */
21649 if (w->phys_cursor_type == NO_CURSOR)
21650 goto mark_cursor_off;
21651
21652 /* VPOS >= active_glyphs->nrows means that window has been resized.
21653 Don't bother to erase the cursor. */
21654 if (vpos >= active_glyphs->nrows)
21655 goto mark_cursor_off;
21656
21657 /* If row containing cursor is marked invalid, there is nothing we
21658 can do. */
21659 cursor_row = MATRIX_ROW (active_glyphs, vpos);
21660 if (!cursor_row->enabled_p)
21661 goto mark_cursor_off;
21662
21663 /* If line spacing is > 0, old cursor may only be partially visible in
21664 window after split-window. So adjust visible height. */
21665 cursor_row->visible_height = min (cursor_row->visible_height,
21666 window_text_bottom_y (w) - cursor_row->y);
21667
21668 /* If row is completely invisible, don't attempt to delete a cursor which
21669 isn't there. This can happen if cursor is at top of a window, and
21670 we switch to a buffer with a header line in that window. */
21671 if (cursor_row->visible_height <= 0)
21672 goto mark_cursor_off;
21673
21674 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
21675 if (cursor_row->cursor_in_fringe_p)
21676 {
21677 cursor_row->cursor_in_fringe_p = 0;
21678 draw_fringe_bitmap (w, cursor_row, 0);
21679 goto mark_cursor_off;
21680 }
21681
21682 /* This can happen when the new row is shorter than the old one.
21683 In this case, either draw_glyphs or clear_end_of_line
21684 should have cleared the cursor. Note that we wouldn't be
21685 able to erase the cursor in this case because we don't have a
21686 cursor glyph at hand. */
21687 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
21688 goto mark_cursor_off;
21689
21690 /* If the cursor is in the mouse face area, redisplay that when
21691 we clear the cursor. */
21692 if (! NILP (dpyinfo->mouse_face_window)
21693 && w == XWINDOW (dpyinfo->mouse_face_window)
21694 && (vpos > dpyinfo->mouse_face_beg_row
21695 || (vpos == dpyinfo->mouse_face_beg_row
21696 && hpos >= dpyinfo->mouse_face_beg_col))
21697 && (vpos < dpyinfo->mouse_face_end_row
21698 || (vpos == dpyinfo->mouse_face_end_row
21699 && hpos < dpyinfo->mouse_face_end_col))
21700 /* Don't redraw the cursor's spot in mouse face if it is at the
21701 end of a line (on a newline). The cursor appears there, but
21702 mouse highlighting does not. */
21703 && cursor_row->used[TEXT_AREA] > hpos)
21704 mouse_face_here_p = 1;
21705
21706 /* Maybe clear the display under the cursor. */
21707 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
21708 {
21709 int x, y, left_x;
21710 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
21711 int width;
21712
21713 cursor_glyph = get_phys_cursor_glyph (w);
21714 if (cursor_glyph == NULL)
21715 goto mark_cursor_off;
21716
21717 width = cursor_glyph->pixel_width;
21718 left_x = window_box_left_offset (w, TEXT_AREA);
21719 x = w->phys_cursor.x;
21720 if (x < left_x)
21721 width -= left_x - x;
21722 width = min (width, window_box_width (w, TEXT_AREA) - x);
21723 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
21724 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
21725
21726 if (width > 0)
21727 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
21728 }
21729
21730 /* Erase the cursor by redrawing the character underneath it. */
21731 if (mouse_face_here_p)
21732 hl = DRAW_MOUSE_FACE;
21733 else
21734 hl = DRAW_NORMAL_TEXT;
21735 draw_phys_cursor_glyph (w, cursor_row, hl);
21736
21737 mark_cursor_off:
21738 w->phys_cursor_on_p = 0;
21739 w->phys_cursor_type = NO_CURSOR;
21740 }
21741
21742
21743 /* EXPORT:
21744 Display or clear cursor of window W. If ON is zero, clear the
21745 cursor. If it is non-zero, display the cursor. If ON is nonzero,
21746 where to put the cursor is specified by HPOS, VPOS, X and Y. */
21747
21748 void
21749 display_and_set_cursor (w, on, hpos, vpos, x, y)
21750 struct window *w;
21751 int on, hpos, vpos, x, y;
21752 {
21753 struct frame *f = XFRAME (w->frame);
21754 int new_cursor_type;
21755 int new_cursor_width;
21756 int active_cursor;
21757 struct glyph_row *glyph_row;
21758 struct glyph *glyph;
21759
21760 /* This is pointless on invisible frames, and dangerous on garbaged
21761 windows and frames; in the latter case, the frame or window may
21762 be in the midst of changing its size, and x and y may be off the
21763 window. */
21764 if (! FRAME_VISIBLE_P (f)
21765 || FRAME_GARBAGED_P (f)
21766 || vpos >= w->current_matrix->nrows
21767 || hpos >= w->current_matrix->matrix_w)
21768 return;
21769
21770 /* If cursor is off and we want it off, return quickly. */
21771 if (!on && !w->phys_cursor_on_p)
21772 return;
21773
21774 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
21775 /* If cursor row is not enabled, we don't really know where to
21776 display the cursor. */
21777 if (!glyph_row->enabled_p)
21778 {
21779 w->phys_cursor_on_p = 0;
21780 return;
21781 }
21782
21783 glyph = NULL;
21784 if (!glyph_row->exact_window_width_line_p
21785 || hpos < glyph_row->used[TEXT_AREA])
21786 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
21787
21788 xassert (interrupt_input_blocked);
21789
21790 /* Set new_cursor_type to the cursor we want to be displayed. */
21791 new_cursor_type = get_window_cursor_type (w, glyph,
21792 &new_cursor_width, &active_cursor);
21793
21794 /* If cursor is currently being shown and we don't want it to be or
21795 it is in the wrong place, or the cursor type is not what we want,
21796 erase it. */
21797 if (w->phys_cursor_on_p
21798 && (!on
21799 || w->phys_cursor.x != x
21800 || w->phys_cursor.y != y
21801 || new_cursor_type != w->phys_cursor_type
21802 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
21803 && new_cursor_width != w->phys_cursor_width)))
21804 erase_phys_cursor (w);
21805
21806 /* Don't check phys_cursor_on_p here because that flag is only set
21807 to zero in some cases where we know that the cursor has been
21808 completely erased, to avoid the extra work of erasing the cursor
21809 twice. In other words, phys_cursor_on_p can be 1 and the cursor
21810 still not be visible, or it has only been partly erased. */
21811 if (on)
21812 {
21813 w->phys_cursor_ascent = glyph_row->ascent;
21814 w->phys_cursor_height = glyph_row->height;
21815
21816 /* Set phys_cursor_.* before x_draw_.* is called because some
21817 of them may need the information. */
21818 w->phys_cursor.x = x;
21819 w->phys_cursor.y = glyph_row->y;
21820 w->phys_cursor.hpos = hpos;
21821 w->phys_cursor.vpos = vpos;
21822 }
21823
21824 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
21825 new_cursor_type, new_cursor_width,
21826 on, active_cursor);
21827 }
21828
21829
21830 /* Switch the display of W's cursor on or off, according to the value
21831 of ON. */
21832
21833 static void
21834 update_window_cursor (w, on)
21835 struct window *w;
21836 int on;
21837 {
21838 /* Don't update cursor in windows whose frame is in the process
21839 of being deleted. */
21840 if (w->current_matrix)
21841 {
21842 BLOCK_INPUT;
21843 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
21844 w->phys_cursor.x, w->phys_cursor.y);
21845 UNBLOCK_INPUT;
21846 }
21847 }
21848
21849
21850 /* Call update_window_cursor with parameter ON_P on all leaf windows
21851 in the window tree rooted at W. */
21852
21853 static void
21854 update_cursor_in_window_tree (w, on_p)
21855 struct window *w;
21856 int on_p;
21857 {
21858 while (w)
21859 {
21860 if (!NILP (w->hchild))
21861 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
21862 else if (!NILP (w->vchild))
21863 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
21864 else
21865 update_window_cursor (w, on_p);
21866
21867 w = NILP (w->next) ? 0 : XWINDOW (w->next);
21868 }
21869 }
21870
21871
21872 /* EXPORT:
21873 Display the cursor on window W, or clear it, according to ON_P.
21874 Don't change the cursor's position. */
21875
21876 void
21877 x_update_cursor (f, on_p)
21878 struct frame *f;
21879 int on_p;
21880 {
21881 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
21882 }
21883
21884
21885 /* EXPORT:
21886 Clear the cursor of window W to background color, and mark the
21887 cursor as not shown. This is used when the text where the cursor
21888 is is about to be rewritten. */
21889
21890 void
21891 x_clear_cursor (w)
21892 struct window *w;
21893 {
21894 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
21895 update_window_cursor (w, 0);
21896 }
21897
21898
21899 /* EXPORT:
21900 Display the active region described by mouse_face_* according to DRAW. */
21901
21902 void
21903 show_mouse_face (dpyinfo, draw)
21904 Display_Info *dpyinfo;
21905 enum draw_glyphs_face draw;
21906 {
21907 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
21908 struct frame *f = XFRAME (WINDOW_FRAME (w));
21909
21910 if (/* If window is in the process of being destroyed, don't bother
21911 to do anything. */
21912 w->current_matrix != NULL
21913 /* Don't update mouse highlight if hidden */
21914 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
21915 /* Recognize when we are called to operate on rows that don't exist
21916 anymore. This can happen when a window is split. */
21917 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
21918 {
21919 int phys_cursor_on_p = w->phys_cursor_on_p;
21920 struct glyph_row *row, *first, *last;
21921
21922 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
21923 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
21924
21925 for (row = first; row <= last && row->enabled_p; ++row)
21926 {
21927 int start_hpos, end_hpos, start_x;
21928
21929 /* For all but the first row, the highlight starts at column 0. */
21930 if (row == first)
21931 {
21932 start_hpos = dpyinfo->mouse_face_beg_col;
21933 start_x = dpyinfo->mouse_face_beg_x;
21934 }
21935 else
21936 {
21937 start_hpos = 0;
21938 start_x = 0;
21939 }
21940
21941 if (row == last)
21942 end_hpos = dpyinfo->mouse_face_end_col;
21943 else
21944 {
21945 end_hpos = row->used[TEXT_AREA];
21946 if (draw == DRAW_NORMAL_TEXT)
21947 row->fill_line_p = 1; /* Clear to end of line */
21948 }
21949
21950 if (end_hpos > start_hpos)
21951 {
21952 draw_glyphs (w, start_x, row, TEXT_AREA,
21953 start_hpos, end_hpos,
21954 draw, 0);
21955
21956 row->mouse_face_p
21957 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
21958 }
21959 }
21960
21961 /* When we've written over the cursor, arrange for it to
21962 be displayed again. */
21963 if (phys_cursor_on_p && !w->phys_cursor_on_p)
21964 {
21965 BLOCK_INPUT;
21966 display_and_set_cursor (w, 1,
21967 w->phys_cursor.hpos, w->phys_cursor.vpos,
21968 w->phys_cursor.x, w->phys_cursor.y);
21969 UNBLOCK_INPUT;
21970 }
21971 }
21972
21973 /* Change the mouse cursor. */
21974 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
21975 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
21976 else if (draw == DRAW_MOUSE_FACE)
21977 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
21978 else
21979 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
21980 }
21981
21982 /* EXPORT:
21983 Clear out the mouse-highlighted active region.
21984 Redraw it un-highlighted first. Value is non-zero if mouse
21985 face was actually drawn unhighlighted. */
21986
21987 int
21988 clear_mouse_face (dpyinfo)
21989 Display_Info *dpyinfo;
21990 {
21991 int cleared = 0;
21992
21993 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
21994 {
21995 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
21996 cleared = 1;
21997 }
21998
21999 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
22000 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
22001 dpyinfo->mouse_face_window = Qnil;
22002 dpyinfo->mouse_face_overlay = Qnil;
22003 return cleared;
22004 }
22005
22006
22007 /* EXPORT:
22008 Non-zero if physical cursor of window W is within mouse face. */
22009
22010 int
22011 cursor_in_mouse_face_p (w)
22012 struct window *w;
22013 {
22014 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
22015 int in_mouse_face = 0;
22016
22017 if (WINDOWP (dpyinfo->mouse_face_window)
22018 && XWINDOW (dpyinfo->mouse_face_window) == w)
22019 {
22020 int hpos = w->phys_cursor.hpos;
22021 int vpos = w->phys_cursor.vpos;
22022
22023 if (vpos >= dpyinfo->mouse_face_beg_row
22024 && vpos <= dpyinfo->mouse_face_end_row
22025 && (vpos > dpyinfo->mouse_face_beg_row
22026 || hpos >= dpyinfo->mouse_face_beg_col)
22027 && (vpos < dpyinfo->mouse_face_end_row
22028 || hpos < dpyinfo->mouse_face_end_col
22029 || dpyinfo->mouse_face_past_end))
22030 in_mouse_face = 1;
22031 }
22032
22033 return in_mouse_face;
22034 }
22035
22036
22037
22038 \f
22039 /* Find the glyph matrix position of buffer position CHARPOS in window
22040 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
22041 current glyphs must be up to date. If CHARPOS is above window
22042 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
22043 of last line in W. In the row containing CHARPOS, stop before glyphs
22044 having STOP as object. */
22045
22046 #if 1 /* This is a version of fast_find_position that's more correct
22047 in the presence of hscrolling, for example. I didn't install
22048 it right away because the problem fixed is minor, it failed
22049 in 20.x as well, and I think it's too risky to install
22050 so near the release of 21.1. 2001-09-25 gerd. */
22051
22052 static int
22053 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
22054 struct window *w;
22055 int charpos;
22056 int *hpos, *vpos, *x, *y;
22057 Lisp_Object stop;
22058 {
22059 struct glyph_row *row, *first;
22060 struct glyph *glyph, *end;
22061 int past_end = 0;
22062
22063 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22064 if (charpos < MATRIX_ROW_START_CHARPOS (first))
22065 {
22066 *x = first->x;
22067 *y = first->y;
22068 *hpos = 0;
22069 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
22070 return 1;
22071 }
22072
22073 row = row_containing_pos (w, charpos, first, NULL, 0);
22074 if (row == NULL)
22075 {
22076 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22077 past_end = 1;
22078 }
22079
22080 /* If whole rows or last part of a row came from a display overlay,
22081 row_containing_pos will skip over such rows because their end pos
22082 equals the start pos of the overlay or interval.
22083
22084 Move back if we have a STOP object and previous row's
22085 end glyph came from STOP. */
22086 if (!NILP (stop))
22087 {
22088 struct glyph_row *prev;
22089 while ((prev = row - 1, prev >= first)
22090 && MATRIX_ROW_END_CHARPOS (prev) == charpos
22091 && prev->used[TEXT_AREA] > 0)
22092 {
22093 struct glyph *beg = prev->glyphs[TEXT_AREA];
22094 glyph = beg + prev->used[TEXT_AREA];
22095 while (--glyph >= beg
22096 && INTEGERP (glyph->object));
22097 if (glyph < beg
22098 || !EQ (stop, glyph->object))
22099 break;
22100 row = prev;
22101 }
22102 }
22103
22104 *x = row->x;
22105 *y = row->y;
22106 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22107
22108 glyph = row->glyphs[TEXT_AREA];
22109 end = glyph + row->used[TEXT_AREA];
22110
22111 /* Skip over glyphs not having an object at the start of the row.
22112 These are special glyphs like truncation marks on terminal
22113 frames. */
22114 if (row->displays_text_p)
22115 while (glyph < end
22116 && INTEGERP (glyph->object)
22117 && !EQ (stop, glyph->object)
22118 && glyph->charpos < 0)
22119 {
22120 *x += glyph->pixel_width;
22121 ++glyph;
22122 }
22123
22124 while (glyph < end
22125 && !INTEGERP (glyph->object)
22126 && !EQ (stop, glyph->object)
22127 && (!BUFFERP (glyph->object)
22128 || glyph->charpos < charpos))
22129 {
22130 *x += glyph->pixel_width;
22131 ++glyph;
22132 }
22133
22134 *hpos = glyph - row->glyphs[TEXT_AREA];
22135 return !past_end;
22136 }
22137
22138 #else /* not 1 */
22139
22140 static int
22141 fast_find_position (w, pos, hpos, vpos, x, y, stop)
22142 struct window *w;
22143 int pos;
22144 int *hpos, *vpos, *x, *y;
22145 Lisp_Object stop;
22146 {
22147 int i;
22148 int lastcol;
22149 int maybe_next_line_p = 0;
22150 int line_start_position;
22151 int yb = window_text_bottom_y (w);
22152 struct glyph_row *row, *best_row;
22153 int row_vpos, best_row_vpos;
22154 int current_x;
22155
22156 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22157 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22158
22159 while (row->y < yb)
22160 {
22161 if (row->used[TEXT_AREA])
22162 line_start_position = row->glyphs[TEXT_AREA]->charpos;
22163 else
22164 line_start_position = 0;
22165
22166 if (line_start_position > pos)
22167 break;
22168 /* If the position sought is the end of the buffer,
22169 don't include the blank lines at the bottom of the window. */
22170 else if (line_start_position == pos
22171 && pos == BUF_ZV (XBUFFER (w->buffer)))
22172 {
22173 maybe_next_line_p = 1;
22174 break;
22175 }
22176 else if (line_start_position > 0)
22177 {
22178 best_row = row;
22179 best_row_vpos = row_vpos;
22180 }
22181
22182 if (row->y + row->height >= yb)
22183 break;
22184
22185 ++row;
22186 ++row_vpos;
22187 }
22188
22189 /* Find the right column within BEST_ROW. */
22190 lastcol = 0;
22191 current_x = best_row->x;
22192 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
22193 {
22194 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
22195 int charpos = glyph->charpos;
22196
22197 if (BUFFERP (glyph->object))
22198 {
22199 if (charpos == pos)
22200 {
22201 *hpos = i;
22202 *vpos = best_row_vpos;
22203 *x = current_x;
22204 *y = best_row->y;
22205 return 1;
22206 }
22207 else if (charpos > pos)
22208 break;
22209 }
22210 else if (EQ (glyph->object, stop))
22211 break;
22212
22213 if (charpos > 0)
22214 lastcol = i;
22215 current_x += glyph->pixel_width;
22216 }
22217
22218 /* If we're looking for the end of the buffer,
22219 and we didn't find it in the line we scanned,
22220 use the start of the following line. */
22221 if (maybe_next_line_p)
22222 {
22223 ++best_row;
22224 ++best_row_vpos;
22225 lastcol = 0;
22226 current_x = best_row->x;
22227 }
22228
22229 *vpos = best_row_vpos;
22230 *hpos = lastcol + 1;
22231 *x = current_x;
22232 *y = best_row->y;
22233 return 0;
22234 }
22235
22236 #endif /* not 1 */
22237
22238
22239 /* Find the position of the glyph for position POS in OBJECT in
22240 window W's current matrix, and return in *X, *Y the pixel
22241 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
22242
22243 RIGHT_P non-zero means return the position of the right edge of the
22244 glyph, RIGHT_P zero means return the left edge position.
22245
22246 If no glyph for POS exists in the matrix, return the position of
22247 the glyph with the next smaller position that is in the matrix, if
22248 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
22249 exists in the matrix, return the position of the glyph with the
22250 next larger position in OBJECT.
22251
22252 Value is non-zero if a glyph was found. */
22253
22254 static int
22255 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
22256 struct window *w;
22257 int pos;
22258 Lisp_Object object;
22259 int *hpos, *vpos, *x, *y;
22260 int right_p;
22261 {
22262 int yb = window_text_bottom_y (w);
22263 struct glyph_row *r;
22264 struct glyph *best_glyph = NULL;
22265 struct glyph_row *best_row = NULL;
22266 int best_x = 0;
22267
22268 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22269 r->enabled_p && r->y < yb;
22270 ++r)
22271 {
22272 struct glyph *g = r->glyphs[TEXT_AREA];
22273 struct glyph *e = g + r->used[TEXT_AREA];
22274 int gx;
22275
22276 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
22277 if (EQ (g->object, object))
22278 {
22279 if (g->charpos == pos)
22280 {
22281 best_glyph = g;
22282 best_x = gx;
22283 best_row = r;
22284 goto found;
22285 }
22286 else if (best_glyph == NULL
22287 || ((abs (g->charpos - pos)
22288 < abs (best_glyph->charpos - pos))
22289 && (right_p
22290 ? g->charpos < pos
22291 : g->charpos > pos)))
22292 {
22293 best_glyph = g;
22294 best_x = gx;
22295 best_row = r;
22296 }
22297 }
22298 }
22299
22300 found:
22301
22302 if (best_glyph)
22303 {
22304 *x = best_x;
22305 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
22306
22307 if (right_p)
22308 {
22309 *x += best_glyph->pixel_width;
22310 ++*hpos;
22311 }
22312
22313 *y = best_row->y;
22314 *vpos = best_row - w->current_matrix->rows;
22315 }
22316
22317 return best_glyph != NULL;
22318 }
22319
22320
22321 /* See if position X, Y is within a hot-spot of an image. */
22322
22323 static int
22324 on_hot_spot_p (hot_spot, x, y)
22325 Lisp_Object hot_spot;
22326 int x, y;
22327 {
22328 if (!CONSP (hot_spot))
22329 return 0;
22330
22331 if (EQ (XCAR (hot_spot), Qrect))
22332 {
22333 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
22334 Lisp_Object rect = XCDR (hot_spot);
22335 Lisp_Object tem;
22336 if (!CONSP (rect))
22337 return 0;
22338 if (!CONSP (XCAR (rect)))
22339 return 0;
22340 if (!CONSP (XCDR (rect)))
22341 return 0;
22342 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
22343 return 0;
22344 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
22345 return 0;
22346 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
22347 return 0;
22348 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
22349 return 0;
22350 return 1;
22351 }
22352 else if (EQ (XCAR (hot_spot), Qcircle))
22353 {
22354 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
22355 Lisp_Object circ = XCDR (hot_spot);
22356 Lisp_Object lr, lx0, ly0;
22357 if (CONSP (circ)
22358 && CONSP (XCAR (circ))
22359 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
22360 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
22361 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
22362 {
22363 double r = XFLOATINT (lr);
22364 double dx = XINT (lx0) - x;
22365 double dy = XINT (ly0) - y;
22366 return (dx * dx + dy * dy <= r * r);
22367 }
22368 }
22369 else if (EQ (XCAR (hot_spot), Qpoly))
22370 {
22371 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
22372 if (VECTORP (XCDR (hot_spot)))
22373 {
22374 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
22375 Lisp_Object *poly = v->contents;
22376 int n = v->size;
22377 int i;
22378 int inside = 0;
22379 Lisp_Object lx, ly;
22380 int x0, y0;
22381
22382 /* Need an even number of coordinates, and at least 3 edges. */
22383 if (n < 6 || n & 1)
22384 return 0;
22385
22386 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
22387 If count is odd, we are inside polygon. Pixels on edges
22388 may or may not be included depending on actual geometry of the
22389 polygon. */
22390 if ((lx = poly[n-2], !INTEGERP (lx))
22391 || (ly = poly[n-1], !INTEGERP (lx)))
22392 return 0;
22393 x0 = XINT (lx), y0 = XINT (ly);
22394 for (i = 0; i < n; i += 2)
22395 {
22396 int x1 = x0, y1 = y0;
22397 if ((lx = poly[i], !INTEGERP (lx))
22398 || (ly = poly[i+1], !INTEGERP (ly)))
22399 return 0;
22400 x0 = XINT (lx), y0 = XINT (ly);
22401
22402 /* Does this segment cross the X line? */
22403 if (x0 >= x)
22404 {
22405 if (x1 >= x)
22406 continue;
22407 }
22408 else if (x1 < x)
22409 continue;
22410 if (y > y0 && y > y1)
22411 continue;
22412 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
22413 inside = !inside;
22414 }
22415 return inside;
22416 }
22417 }
22418 return 0;
22419 }
22420
22421 Lisp_Object
22422 find_hot_spot (map, x, y)
22423 Lisp_Object map;
22424 int x, y;
22425 {
22426 while (CONSP (map))
22427 {
22428 if (CONSP (XCAR (map))
22429 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
22430 return XCAR (map);
22431 map = XCDR (map);
22432 }
22433
22434 return Qnil;
22435 }
22436
22437 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
22438 3, 3, 0,
22439 doc: /* Lookup in image map MAP coordinates X and Y.
22440 An image map is an alist where each element has the format (AREA ID PLIST).
22441 An AREA is specified as either a rectangle, a circle, or a polygon:
22442 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
22443 pixel coordinates of the upper left and bottom right corners.
22444 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
22445 and the radius of the circle; r may be a float or integer.
22446 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
22447 vector describes one corner in the polygon.
22448 Returns the alist element for the first matching AREA in MAP. */)
22449 (map, x, y)
22450 Lisp_Object map;
22451 Lisp_Object x, y;
22452 {
22453 if (NILP (map))
22454 return Qnil;
22455
22456 CHECK_NUMBER (x);
22457 CHECK_NUMBER (y);
22458
22459 return find_hot_spot (map, XINT (x), XINT (y));
22460 }
22461
22462
22463 /* Display frame CURSOR, optionally using shape defined by POINTER. */
22464 static void
22465 define_frame_cursor1 (f, cursor, pointer)
22466 struct frame *f;
22467 Cursor cursor;
22468 Lisp_Object pointer;
22469 {
22470 /* Do not change cursor shape while dragging mouse. */
22471 if (!NILP (do_mouse_tracking))
22472 return;
22473
22474 if (!NILP (pointer))
22475 {
22476 if (EQ (pointer, Qarrow))
22477 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22478 else if (EQ (pointer, Qhand))
22479 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
22480 else if (EQ (pointer, Qtext))
22481 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22482 else if (EQ (pointer, intern ("hdrag")))
22483 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22484 #ifdef HAVE_X_WINDOWS
22485 else if (EQ (pointer, intern ("vdrag")))
22486 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
22487 #endif
22488 else if (EQ (pointer, intern ("hourglass")))
22489 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
22490 else if (EQ (pointer, Qmodeline))
22491 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
22492 else
22493 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22494 }
22495
22496 if (cursor != No_Cursor)
22497 FRAME_RIF (f)->define_frame_cursor (f, cursor);
22498 }
22499
22500 /* Take proper action when mouse has moved to the mode or header line
22501 or marginal area AREA of window W, x-position X and y-position Y.
22502 X is relative to the start of the text display area of W, so the
22503 width of bitmap areas and scroll bars must be subtracted to get a
22504 position relative to the start of the mode line. */
22505
22506 static void
22507 note_mode_line_or_margin_highlight (window, x, y, area)
22508 Lisp_Object window;
22509 int x, y;
22510 enum window_part area;
22511 {
22512 struct window *w = XWINDOW (window);
22513 struct frame *f = XFRAME (w->frame);
22514 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22515 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22516 Lisp_Object pointer = Qnil;
22517 int charpos, dx, dy, width, height;
22518 Lisp_Object string, object = Qnil;
22519 Lisp_Object pos, help;
22520
22521 Lisp_Object mouse_face;
22522 int original_x_pixel = x;
22523 struct glyph * glyph = NULL, * row_start_glyph = NULL;
22524 struct glyph_row *row;
22525
22526 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
22527 {
22528 int x0;
22529 struct glyph *end;
22530
22531 string = mode_line_string (w, area, &x, &y, &charpos,
22532 &object, &dx, &dy, &width, &height);
22533
22534 row = (area == ON_MODE_LINE
22535 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
22536 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
22537
22538 /* Find glyph */
22539 if (row->mode_line_p && row->enabled_p)
22540 {
22541 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
22542 end = glyph + row->used[TEXT_AREA];
22543
22544 for (x0 = original_x_pixel;
22545 glyph < end && x0 >= glyph->pixel_width;
22546 ++glyph)
22547 x0 -= glyph->pixel_width;
22548
22549 if (glyph >= end)
22550 glyph = NULL;
22551 }
22552 }
22553 else
22554 {
22555 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
22556 string = marginal_area_string (w, area, &x, &y, &charpos,
22557 &object, &dx, &dy, &width, &height);
22558 }
22559
22560 help = Qnil;
22561
22562 if (IMAGEP (object))
22563 {
22564 Lisp_Object image_map, hotspot;
22565 if ((image_map = Fplist_get (XCDR (object), QCmap),
22566 !NILP (image_map))
22567 && (hotspot = find_hot_spot (image_map, dx, dy),
22568 CONSP (hotspot))
22569 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22570 {
22571 Lisp_Object area_id, plist;
22572
22573 area_id = XCAR (hotspot);
22574 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22575 If so, we could look for mouse-enter, mouse-leave
22576 properties in PLIST (and do something...). */
22577 hotspot = XCDR (hotspot);
22578 if (CONSP (hotspot)
22579 && (plist = XCAR (hotspot), CONSP (plist)))
22580 {
22581 pointer = Fplist_get (plist, Qpointer);
22582 if (NILP (pointer))
22583 pointer = Qhand;
22584 help = Fplist_get (plist, Qhelp_echo);
22585 if (!NILP (help))
22586 {
22587 help_echo_string = help;
22588 /* Is this correct? ++kfs */
22589 XSETWINDOW (help_echo_window, w);
22590 help_echo_object = w->buffer;
22591 help_echo_pos = charpos;
22592 }
22593 }
22594 }
22595 if (NILP (pointer))
22596 pointer = Fplist_get (XCDR (object), QCpointer);
22597 }
22598
22599 if (STRINGP (string))
22600 {
22601 pos = make_number (charpos);
22602 /* If we're on a string with `help-echo' text property, arrange
22603 for the help to be displayed. This is done by setting the
22604 global variable help_echo_string to the help string. */
22605 if (NILP (help))
22606 {
22607 help = Fget_text_property (pos, Qhelp_echo, string);
22608 if (!NILP (help))
22609 {
22610 help_echo_string = help;
22611 XSETWINDOW (help_echo_window, w);
22612 help_echo_object = string;
22613 help_echo_pos = charpos;
22614 }
22615 }
22616
22617 if (NILP (pointer))
22618 pointer = Fget_text_property (pos, Qpointer, string);
22619
22620 /* Change the mouse pointer according to what is under X/Y. */
22621 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
22622 {
22623 Lisp_Object map;
22624 map = Fget_text_property (pos, Qlocal_map, string);
22625 if (!KEYMAPP (map))
22626 map = Fget_text_property (pos, Qkeymap, string);
22627 if (!KEYMAPP (map))
22628 cursor = dpyinfo->vertical_scroll_bar_cursor;
22629 }
22630
22631 /* Change the mouse face according to what is under X/Y. */
22632 mouse_face = Fget_text_property (pos, Qmouse_face, string);
22633 if (!NILP (mouse_face)
22634 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22635 && glyph)
22636 {
22637 Lisp_Object b, e;
22638
22639 struct glyph * tmp_glyph;
22640
22641 int gpos;
22642 int gseq_length;
22643 int total_pixel_width;
22644 int ignore;
22645
22646 int vpos, hpos;
22647
22648 b = Fprevious_single_property_change (make_number (charpos + 1),
22649 Qmouse_face, string, Qnil);
22650 if (NILP (b))
22651 b = make_number (0);
22652
22653 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
22654 if (NILP (e))
22655 e = make_number (SCHARS (string));
22656
22657 /* Calculate the position(glyph position: GPOS) of GLYPH in
22658 displayed string. GPOS is different from CHARPOS.
22659
22660 CHARPOS is the position of glyph in internal string
22661 object. A mode line string format has structures which
22662 is converted to a flatten by emacs lisp interpreter.
22663 The internal string is an element of the structures.
22664 The displayed string is the flatten string. */
22665 gpos = 0;
22666 if (glyph > row_start_glyph)
22667 {
22668 tmp_glyph = glyph - 1;
22669 while (tmp_glyph >= row_start_glyph
22670 && tmp_glyph->charpos >= XINT (b)
22671 && EQ (tmp_glyph->object, glyph->object))
22672 {
22673 tmp_glyph--;
22674 gpos++;
22675 }
22676 }
22677
22678 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
22679 displayed string holding GLYPH.
22680
22681 GSEQ_LENGTH is different from SCHARS (STRING).
22682 SCHARS (STRING) returns the length of the internal string. */
22683 for (tmp_glyph = glyph, gseq_length = gpos;
22684 tmp_glyph->charpos < XINT (e);
22685 tmp_glyph++, gseq_length++)
22686 {
22687 if (!EQ (tmp_glyph->object, glyph->object))
22688 break;
22689 }
22690
22691 total_pixel_width = 0;
22692 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
22693 total_pixel_width += tmp_glyph->pixel_width;
22694
22695 /* Pre calculation of re-rendering position */
22696 vpos = (x - gpos);
22697 hpos = (area == ON_MODE_LINE
22698 ? (w->current_matrix)->nrows - 1
22699 : 0);
22700
22701 /* If the re-rendering position is included in the last
22702 re-rendering area, we should do nothing. */
22703 if ( EQ (window, dpyinfo->mouse_face_window)
22704 && dpyinfo->mouse_face_beg_col <= vpos
22705 && vpos < dpyinfo->mouse_face_end_col
22706 && dpyinfo->mouse_face_beg_row == hpos )
22707 return;
22708
22709 if (clear_mouse_face (dpyinfo))
22710 cursor = No_Cursor;
22711
22712 dpyinfo->mouse_face_beg_col = vpos;
22713 dpyinfo->mouse_face_beg_row = hpos;
22714
22715 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
22716 dpyinfo->mouse_face_beg_y = 0;
22717
22718 dpyinfo->mouse_face_end_col = vpos + gseq_length;
22719 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
22720
22721 dpyinfo->mouse_face_end_x = 0;
22722 dpyinfo->mouse_face_end_y = 0;
22723
22724 dpyinfo->mouse_face_past_end = 0;
22725 dpyinfo->mouse_face_window = window;
22726
22727 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
22728 charpos,
22729 0, 0, 0, &ignore,
22730 glyph->face_id, 1);
22731 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22732
22733 if (NILP (pointer))
22734 pointer = Qhand;
22735 }
22736 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22737 clear_mouse_face (dpyinfo);
22738 }
22739 define_frame_cursor1 (f, cursor, pointer);
22740 }
22741
22742
22743 /* EXPORT:
22744 Take proper action when the mouse has moved to position X, Y on
22745 frame F as regards highlighting characters that have mouse-face
22746 properties. Also de-highlighting chars where the mouse was before.
22747 X and Y can be negative or out of range. */
22748
22749 void
22750 note_mouse_highlight (f, x, y)
22751 struct frame *f;
22752 int x, y;
22753 {
22754 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22755 enum window_part part;
22756 Lisp_Object window;
22757 struct window *w;
22758 Cursor cursor = No_Cursor;
22759 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
22760 struct buffer *b;
22761
22762 /* When a menu is active, don't highlight because this looks odd. */
22763 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
22764 if (popup_activated ())
22765 return;
22766 #endif
22767
22768 if (NILP (Vmouse_highlight)
22769 || !f->glyphs_initialized_p)
22770 return;
22771
22772 dpyinfo->mouse_face_mouse_x = x;
22773 dpyinfo->mouse_face_mouse_y = y;
22774 dpyinfo->mouse_face_mouse_frame = f;
22775
22776 if (dpyinfo->mouse_face_defer)
22777 return;
22778
22779 if (gc_in_progress)
22780 {
22781 dpyinfo->mouse_face_deferred_gc = 1;
22782 return;
22783 }
22784
22785 /* Which window is that in? */
22786 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
22787
22788 /* If we were displaying active text in another window, clear that.
22789 Also clear if we move out of text area in same window. */
22790 if (! EQ (window, dpyinfo->mouse_face_window)
22791 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
22792 && !NILP (dpyinfo->mouse_face_window)))
22793 clear_mouse_face (dpyinfo);
22794
22795 /* Not on a window -> return. */
22796 if (!WINDOWP (window))
22797 return;
22798
22799 /* Reset help_echo_string. It will get recomputed below. */
22800 help_echo_string = Qnil;
22801
22802 /* Convert to window-relative pixel coordinates. */
22803 w = XWINDOW (window);
22804 frame_to_window_pixel_xy (w, &x, &y);
22805
22806 /* Handle tool-bar window differently since it doesn't display a
22807 buffer. */
22808 if (EQ (window, f->tool_bar_window))
22809 {
22810 note_tool_bar_highlight (f, x, y);
22811 return;
22812 }
22813
22814 /* Mouse is on the mode, header line or margin? */
22815 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
22816 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
22817 {
22818 note_mode_line_or_margin_highlight (window, x, y, part);
22819 return;
22820 }
22821
22822 if (part == ON_VERTICAL_BORDER)
22823 {
22824 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22825 help_echo_string = build_string ("drag-mouse-1: resize");
22826 }
22827 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
22828 || part == ON_SCROLL_BAR)
22829 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22830 else
22831 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22832
22833 /* Are we in a window whose display is up to date?
22834 And verify the buffer's text has not changed. */
22835 b = XBUFFER (w->buffer);
22836 if (part == ON_TEXT
22837 && EQ (w->window_end_valid, w->buffer)
22838 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
22839 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
22840 {
22841 int hpos, vpos, pos, i, dx, dy, area;
22842 struct glyph *glyph;
22843 Lisp_Object object;
22844 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
22845 Lisp_Object *overlay_vec = NULL;
22846 int noverlays;
22847 struct buffer *obuf;
22848 int obegv, ozv, same_region;
22849
22850 /* Find the glyph under X/Y. */
22851 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
22852
22853 /* Look for :pointer property on image. */
22854 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
22855 {
22856 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
22857 if (img != NULL && IMAGEP (img->spec))
22858 {
22859 Lisp_Object image_map, hotspot;
22860 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
22861 !NILP (image_map))
22862 && (hotspot = find_hot_spot (image_map,
22863 glyph->slice.x + dx,
22864 glyph->slice.y + dy),
22865 CONSP (hotspot))
22866 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22867 {
22868 Lisp_Object area_id, plist;
22869
22870 area_id = XCAR (hotspot);
22871 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22872 If so, we could look for mouse-enter, mouse-leave
22873 properties in PLIST (and do something...). */
22874 hotspot = XCDR (hotspot);
22875 if (CONSP (hotspot)
22876 && (plist = XCAR (hotspot), CONSP (plist)))
22877 {
22878 pointer = Fplist_get (plist, Qpointer);
22879 if (NILP (pointer))
22880 pointer = Qhand;
22881 help_echo_string = Fplist_get (plist, Qhelp_echo);
22882 if (!NILP (help_echo_string))
22883 {
22884 help_echo_window = window;
22885 help_echo_object = glyph->object;
22886 help_echo_pos = glyph->charpos;
22887 }
22888 }
22889 }
22890 if (NILP (pointer))
22891 pointer = Fplist_get (XCDR (img->spec), QCpointer);
22892 }
22893 }
22894
22895 /* Clear mouse face if X/Y not over text. */
22896 if (glyph == NULL
22897 || area != TEXT_AREA
22898 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
22899 {
22900 if (clear_mouse_face (dpyinfo))
22901 cursor = No_Cursor;
22902 if (NILP (pointer))
22903 {
22904 if (area != TEXT_AREA)
22905 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22906 else
22907 pointer = Vvoid_text_area_pointer;
22908 }
22909 goto set_cursor;
22910 }
22911
22912 pos = glyph->charpos;
22913 object = glyph->object;
22914 if (!STRINGP (object) && !BUFFERP (object))
22915 goto set_cursor;
22916
22917 /* If we get an out-of-range value, return now; avoid an error. */
22918 if (BUFFERP (object) && pos > BUF_Z (b))
22919 goto set_cursor;
22920
22921 /* Make the window's buffer temporarily current for
22922 overlays_at and compute_char_face. */
22923 obuf = current_buffer;
22924 current_buffer = b;
22925 obegv = BEGV;
22926 ozv = ZV;
22927 BEGV = BEG;
22928 ZV = Z;
22929
22930 /* Is this char mouse-active or does it have help-echo? */
22931 position = make_number (pos);
22932
22933 if (BUFFERP (object))
22934 {
22935 /* Put all the overlays we want in a vector in overlay_vec. */
22936 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
22937 /* Sort overlays into increasing priority order. */
22938 noverlays = sort_overlays (overlay_vec, noverlays, w);
22939 }
22940 else
22941 noverlays = 0;
22942
22943 same_region = (EQ (window, dpyinfo->mouse_face_window)
22944 && vpos >= dpyinfo->mouse_face_beg_row
22945 && vpos <= dpyinfo->mouse_face_end_row
22946 && (vpos > dpyinfo->mouse_face_beg_row
22947 || hpos >= dpyinfo->mouse_face_beg_col)
22948 && (vpos < dpyinfo->mouse_face_end_row
22949 || hpos < dpyinfo->mouse_face_end_col
22950 || dpyinfo->mouse_face_past_end));
22951
22952 if (same_region)
22953 cursor = No_Cursor;
22954
22955 /* Check mouse-face highlighting. */
22956 if (! same_region
22957 /* If there exists an overlay with mouse-face overlapping
22958 the one we are currently highlighting, we have to
22959 check if we enter the overlapping overlay, and then
22960 highlight only that. */
22961 || (OVERLAYP (dpyinfo->mouse_face_overlay)
22962 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
22963 {
22964 /* Find the highest priority overlay that has a mouse-face
22965 property. */
22966 overlay = Qnil;
22967 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
22968 {
22969 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
22970 if (!NILP (mouse_face))
22971 overlay = overlay_vec[i];
22972 }
22973
22974 /* If we're actually highlighting the same overlay as
22975 before, there's no need to do that again. */
22976 if (!NILP (overlay)
22977 && EQ (overlay, dpyinfo->mouse_face_overlay))
22978 goto check_help_echo;
22979
22980 dpyinfo->mouse_face_overlay = overlay;
22981
22982 /* Clear the display of the old active region, if any. */
22983 if (clear_mouse_face (dpyinfo))
22984 cursor = No_Cursor;
22985
22986 /* If no overlay applies, get a text property. */
22987 if (NILP (overlay))
22988 mouse_face = Fget_text_property (position, Qmouse_face, object);
22989
22990 /* Handle the overlay case. */
22991 if (!NILP (overlay))
22992 {
22993 /* Find the range of text around this char that
22994 should be active. */
22995 Lisp_Object before, after;
22996 int ignore;
22997
22998 before = Foverlay_start (overlay);
22999 after = Foverlay_end (overlay);
23000 /* Record this as the current active region. */
23001 fast_find_position (w, XFASTINT (before),
23002 &dpyinfo->mouse_face_beg_col,
23003 &dpyinfo->mouse_face_beg_row,
23004 &dpyinfo->mouse_face_beg_x,
23005 &dpyinfo->mouse_face_beg_y, Qnil);
23006
23007 dpyinfo->mouse_face_past_end
23008 = !fast_find_position (w, XFASTINT (after),
23009 &dpyinfo->mouse_face_end_col,
23010 &dpyinfo->mouse_face_end_row,
23011 &dpyinfo->mouse_face_end_x,
23012 &dpyinfo->mouse_face_end_y, Qnil);
23013 dpyinfo->mouse_face_window = window;
23014
23015 dpyinfo->mouse_face_face_id
23016 = face_at_buffer_position (w, pos, 0, 0,
23017 &ignore, pos + 1,
23018 !dpyinfo->mouse_face_hidden);
23019
23020 /* Display it as active. */
23021 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23022 cursor = No_Cursor;
23023 }
23024 /* Handle the text property case. */
23025 else if (!NILP (mouse_face) && BUFFERP (object))
23026 {
23027 /* Find the range of text around this char that
23028 should be active. */
23029 Lisp_Object before, after, beginning, end;
23030 int ignore;
23031
23032 beginning = Fmarker_position (w->start);
23033 end = make_number (BUF_Z (XBUFFER (object))
23034 - XFASTINT (w->window_end_pos));
23035 before
23036 = Fprevious_single_property_change (make_number (pos + 1),
23037 Qmouse_face,
23038 object, beginning);
23039 after
23040 = Fnext_single_property_change (position, Qmouse_face,
23041 object, end);
23042
23043 /* Record this as the current active region. */
23044 fast_find_position (w, XFASTINT (before),
23045 &dpyinfo->mouse_face_beg_col,
23046 &dpyinfo->mouse_face_beg_row,
23047 &dpyinfo->mouse_face_beg_x,
23048 &dpyinfo->mouse_face_beg_y, Qnil);
23049 dpyinfo->mouse_face_past_end
23050 = !fast_find_position (w, XFASTINT (after),
23051 &dpyinfo->mouse_face_end_col,
23052 &dpyinfo->mouse_face_end_row,
23053 &dpyinfo->mouse_face_end_x,
23054 &dpyinfo->mouse_face_end_y, Qnil);
23055 dpyinfo->mouse_face_window = window;
23056
23057 if (BUFFERP (object))
23058 dpyinfo->mouse_face_face_id
23059 = face_at_buffer_position (w, pos, 0, 0,
23060 &ignore, pos + 1,
23061 !dpyinfo->mouse_face_hidden);
23062
23063 /* Display it as active. */
23064 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23065 cursor = No_Cursor;
23066 }
23067 else if (!NILP (mouse_face) && STRINGP (object))
23068 {
23069 Lisp_Object b, e;
23070 int ignore;
23071
23072 b = Fprevious_single_property_change (make_number (pos + 1),
23073 Qmouse_face,
23074 object, Qnil);
23075 e = Fnext_single_property_change (position, Qmouse_face,
23076 object, Qnil);
23077 if (NILP (b))
23078 b = make_number (0);
23079 if (NILP (e))
23080 e = make_number (SCHARS (object) - 1);
23081
23082 fast_find_string_pos (w, XINT (b), object,
23083 &dpyinfo->mouse_face_beg_col,
23084 &dpyinfo->mouse_face_beg_row,
23085 &dpyinfo->mouse_face_beg_x,
23086 &dpyinfo->mouse_face_beg_y, 0);
23087 fast_find_string_pos (w, XINT (e), object,
23088 &dpyinfo->mouse_face_end_col,
23089 &dpyinfo->mouse_face_end_row,
23090 &dpyinfo->mouse_face_end_x,
23091 &dpyinfo->mouse_face_end_y, 1);
23092 dpyinfo->mouse_face_past_end = 0;
23093 dpyinfo->mouse_face_window = window;
23094 dpyinfo->mouse_face_face_id
23095 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
23096 glyph->face_id, 1);
23097 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23098 cursor = No_Cursor;
23099 }
23100 else if (STRINGP (object) && NILP (mouse_face))
23101 {
23102 /* A string which doesn't have mouse-face, but
23103 the text ``under'' it might have. */
23104 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
23105 int start = MATRIX_ROW_START_CHARPOS (r);
23106
23107 pos = string_buffer_position (w, object, start);
23108 if (pos > 0)
23109 mouse_face = get_char_property_and_overlay (make_number (pos),
23110 Qmouse_face,
23111 w->buffer,
23112 &overlay);
23113 if (!NILP (mouse_face) && !NILP (overlay))
23114 {
23115 Lisp_Object before = Foverlay_start (overlay);
23116 Lisp_Object after = Foverlay_end (overlay);
23117 int ignore;
23118
23119 /* Note that we might not be able to find position
23120 BEFORE in the glyph matrix if the overlay is
23121 entirely covered by a `display' property. In
23122 this case, we overshoot. So let's stop in
23123 the glyph matrix before glyphs for OBJECT. */
23124 fast_find_position (w, XFASTINT (before),
23125 &dpyinfo->mouse_face_beg_col,
23126 &dpyinfo->mouse_face_beg_row,
23127 &dpyinfo->mouse_face_beg_x,
23128 &dpyinfo->mouse_face_beg_y,
23129 object);
23130
23131 dpyinfo->mouse_face_past_end
23132 = !fast_find_position (w, XFASTINT (after),
23133 &dpyinfo->mouse_face_end_col,
23134 &dpyinfo->mouse_face_end_row,
23135 &dpyinfo->mouse_face_end_x,
23136 &dpyinfo->mouse_face_end_y,
23137 Qnil);
23138 dpyinfo->mouse_face_window = window;
23139 dpyinfo->mouse_face_face_id
23140 = face_at_buffer_position (w, pos, 0, 0,
23141 &ignore, pos + 1,
23142 !dpyinfo->mouse_face_hidden);
23143
23144 /* Display it as active. */
23145 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23146 cursor = No_Cursor;
23147 }
23148 }
23149 }
23150
23151 check_help_echo:
23152
23153 /* Look for a `help-echo' property. */
23154 if (NILP (help_echo_string)) {
23155 Lisp_Object help, overlay;
23156
23157 /* Check overlays first. */
23158 help = overlay = Qnil;
23159 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
23160 {
23161 overlay = overlay_vec[i];
23162 help = Foverlay_get (overlay, Qhelp_echo);
23163 }
23164
23165 if (!NILP (help))
23166 {
23167 help_echo_string = help;
23168 help_echo_window = window;
23169 help_echo_object = overlay;
23170 help_echo_pos = pos;
23171 }
23172 else
23173 {
23174 Lisp_Object object = glyph->object;
23175 int charpos = glyph->charpos;
23176
23177 /* Try text properties. */
23178 if (STRINGP (object)
23179 && charpos >= 0
23180 && charpos < SCHARS (object))
23181 {
23182 help = Fget_text_property (make_number (charpos),
23183 Qhelp_echo, object);
23184 if (NILP (help))
23185 {
23186 /* If the string itself doesn't specify a help-echo,
23187 see if the buffer text ``under'' it does. */
23188 struct glyph_row *r
23189 = MATRIX_ROW (w->current_matrix, vpos);
23190 int start = MATRIX_ROW_START_CHARPOS (r);
23191 int pos = string_buffer_position (w, object, start);
23192 if (pos > 0)
23193 {
23194 help = Fget_char_property (make_number (pos),
23195 Qhelp_echo, w->buffer);
23196 if (!NILP (help))
23197 {
23198 charpos = pos;
23199 object = w->buffer;
23200 }
23201 }
23202 }
23203 }
23204 else if (BUFFERP (object)
23205 && charpos >= BEGV
23206 && charpos < ZV)
23207 help = Fget_text_property (make_number (charpos), Qhelp_echo,
23208 object);
23209
23210 if (!NILP (help))
23211 {
23212 help_echo_string = help;
23213 help_echo_window = window;
23214 help_echo_object = object;
23215 help_echo_pos = charpos;
23216 }
23217 }
23218 }
23219
23220 /* Look for a `pointer' property. */
23221 if (NILP (pointer))
23222 {
23223 /* Check overlays first. */
23224 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
23225 pointer = Foverlay_get (overlay_vec[i], Qpointer);
23226
23227 if (NILP (pointer))
23228 {
23229 Lisp_Object object = glyph->object;
23230 int charpos = glyph->charpos;
23231
23232 /* Try text properties. */
23233 if (STRINGP (object)
23234 && charpos >= 0
23235 && charpos < SCHARS (object))
23236 {
23237 pointer = Fget_text_property (make_number (charpos),
23238 Qpointer, object);
23239 if (NILP (pointer))
23240 {
23241 /* If the string itself doesn't specify a pointer,
23242 see if the buffer text ``under'' it does. */
23243 struct glyph_row *r
23244 = MATRIX_ROW (w->current_matrix, vpos);
23245 int start = MATRIX_ROW_START_CHARPOS (r);
23246 int pos = string_buffer_position (w, object, start);
23247 if (pos > 0)
23248 pointer = Fget_char_property (make_number (pos),
23249 Qpointer, w->buffer);
23250 }
23251 }
23252 else if (BUFFERP (object)
23253 && charpos >= BEGV
23254 && charpos < ZV)
23255 pointer = Fget_text_property (make_number (charpos),
23256 Qpointer, object);
23257 }
23258 }
23259
23260 BEGV = obegv;
23261 ZV = ozv;
23262 current_buffer = obuf;
23263 }
23264
23265 set_cursor:
23266
23267 define_frame_cursor1 (f, cursor, pointer);
23268 }
23269
23270
23271 /* EXPORT for RIF:
23272 Clear any mouse-face on window W. This function is part of the
23273 redisplay interface, and is called from try_window_id and similar
23274 functions to ensure the mouse-highlight is off. */
23275
23276 void
23277 x_clear_window_mouse_face (w)
23278 struct window *w;
23279 {
23280 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23281 Lisp_Object window;
23282
23283 BLOCK_INPUT;
23284 XSETWINDOW (window, w);
23285 if (EQ (window, dpyinfo->mouse_face_window))
23286 clear_mouse_face (dpyinfo);
23287 UNBLOCK_INPUT;
23288 }
23289
23290
23291 /* EXPORT:
23292 Just discard the mouse face information for frame F, if any.
23293 This is used when the size of F is changed. */
23294
23295 void
23296 cancel_mouse_face (f)
23297 struct frame *f;
23298 {
23299 Lisp_Object window;
23300 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23301
23302 window = dpyinfo->mouse_face_window;
23303 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
23304 {
23305 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
23306 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
23307 dpyinfo->mouse_face_window = Qnil;
23308 }
23309 }
23310
23311
23312 #endif /* HAVE_WINDOW_SYSTEM */
23313
23314 \f
23315 /***********************************************************************
23316 Exposure Events
23317 ***********************************************************************/
23318
23319 #ifdef HAVE_WINDOW_SYSTEM
23320
23321 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
23322 which intersects rectangle R. R is in window-relative coordinates. */
23323
23324 static void
23325 expose_area (w, row, r, area)
23326 struct window *w;
23327 struct glyph_row *row;
23328 XRectangle *r;
23329 enum glyph_row_area area;
23330 {
23331 struct glyph *first = row->glyphs[area];
23332 struct glyph *end = row->glyphs[area] + row->used[area];
23333 struct glyph *last;
23334 int first_x, start_x, x;
23335
23336 if (area == TEXT_AREA && row->fill_line_p)
23337 /* If row extends face to end of line write the whole line. */
23338 draw_glyphs (w, 0, row, area,
23339 0, row->used[area],
23340 DRAW_NORMAL_TEXT, 0);
23341 else
23342 {
23343 /* Set START_X to the window-relative start position for drawing glyphs of
23344 AREA. The first glyph of the text area can be partially visible.
23345 The first glyphs of other areas cannot. */
23346 start_x = window_box_left_offset (w, area);
23347 x = start_x;
23348 if (area == TEXT_AREA)
23349 x += row->x;
23350
23351 /* Find the first glyph that must be redrawn. */
23352 while (first < end
23353 && x + first->pixel_width < r->x)
23354 {
23355 x += first->pixel_width;
23356 ++first;
23357 }
23358
23359 /* Find the last one. */
23360 last = first;
23361 first_x = x;
23362 while (last < end
23363 && x < r->x + r->width)
23364 {
23365 x += last->pixel_width;
23366 ++last;
23367 }
23368
23369 /* Repaint. */
23370 if (last > first)
23371 draw_glyphs (w, first_x - start_x, row, area,
23372 first - row->glyphs[area], last - row->glyphs[area],
23373 DRAW_NORMAL_TEXT, 0);
23374 }
23375 }
23376
23377
23378 /* Redraw the parts of the glyph row ROW on window W intersecting
23379 rectangle R. R is in window-relative coordinates. Value is
23380 non-zero if mouse-face was overwritten. */
23381
23382 static int
23383 expose_line (w, row, r)
23384 struct window *w;
23385 struct glyph_row *row;
23386 XRectangle *r;
23387 {
23388 xassert (row->enabled_p);
23389
23390 if (row->mode_line_p || w->pseudo_window_p)
23391 draw_glyphs (w, 0, row, TEXT_AREA,
23392 0, row->used[TEXT_AREA],
23393 DRAW_NORMAL_TEXT, 0);
23394 else
23395 {
23396 if (row->used[LEFT_MARGIN_AREA])
23397 expose_area (w, row, r, LEFT_MARGIN_AREA);
23398 if (row->used[TEXT_AREA])
23399 expose_area (w, row, r, TEXT_AREA);
23400 if (row->used[RIGHT_MARGIN_AREA])
23401 expose_area (w, row, r, RIGHT_MARGIN_AREA);
23402 draw_row_fringe_bitmaps (w, row);
23403 }
23404
23405 return row->mouse_face_p;
23406 }
23407
23408
23409 /* Redraw those parts of glyphs rows during expose event handling that
23410 overlap other rows. Redrawing of an exposed line writes over parts
23411 of lines overlapping that exposed line; this function fixes that.
23412
23413 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
23414 row in W's current matrix that is exposed and overlaps other rows.
23415 LAST_OVERLAPPING_ROW is the last such row. */
23416
23417 static void
23418 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
23419 struct window *w;
23420 struct glyph_row *first_overlapping_row;
23421 struct glyph_row *last_overlapping_row;
23422 {
23423 struct glyph_row *row;
23424
23425 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
23426 if (row->overlapping_p)
23427 {
23428 xassert (row->enabled_p && !row->mode_line_p);
23429
23430 if (row->used[LEFT_MARGIN_AREA])
23431 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
23432
23433 if (row->used[TEXT_AREA])
23434 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
23435
23436 if (row->used[RIGHT_MARGIN_AREA])
23437 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
23438 }
23439 }
23440
23441
23442 /* Return non-zero if W's cursor intersects rectangle R. */
23443
23444 static int
23445 phys_cursor_in_rect_p (w, r)
23446 struct window *w;
23447 XRectangle *r;
23448 {
23449 XRectangle cr, result;
23450 struct glyph *cursor_glyph;
23451
23452 cursor_glyph = get_phys_cursor_glyph (w);
23453 if (cursor_glyph)
23454 {
23455 /* r is relative to W's box, but w->phys_cursor.x is relative
23456 to left edge of W's TEXT area. Adjust it. */
23457 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
23458 cr.y = w->phys_cursor.y;
23459 cr.width = cursor_glyph->pixel_width;
23460 cr.height = w->phys_cursor_height;
23461 /* ++KFS: W32 version used W32-specific IntersectRect here, but
23462 I assume the effect is the same -- and this is portable. */
23463 return x_intersect_rectangles (&cr, r, &result);
23464 }
23465 /* If we don't understand the format, pretend we're not in the hot-spot. */
23466 return 0;
23467 }
23468
23469
23470 /* EXPORT:
23471 Draw a vertical window border to the right of window W if W doesn't
23472 have vertical scroll bars. */
23473
23474 void
23475 x_draw_vertical_border (w)
23476 struct window *w;
23477 {
23478 struct frame *f = XFRAME (WINDOW_FRAME (w));
23479
23480 /* We could do better, if we knew what type of scroll-bar the adjacent
23481 windows (on either side) have... But we don't :-(
23482 However, I think this works ok. ++KFS 2003-04-25 */
23483
23484 /* Redraw borders between horizontally adjacent windows. Don't
23485 do it for frames with vertical scroll bars because either the
23486 right scroll bar of a window, or the left scroll bar of its
23487 neighbor will suffice as a border. */
23488 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
23489 return;
23490
23491 if (!WINDOW_RIGHTMOST_P (w)
23492 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
23493 {
23494 int x0, x1, y0, y1;
23495
23496 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23497 y1 -= 1;
23498
23499 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23500 x1 -= 1;
23501
23502 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
23503 }
23504 else if (!WINDOW_LEFTMOST_P (w)
23505 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
23506 {
23507 int x0, x1, y0, y1;
23508
23509 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23510 y1 -= 1;
23511
23512 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23513 x0 -= 1;
23514
23515 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
23516 }
23517 }
23518
23519
23520 /* Redraw the part of window W intersection rectangle FR. Pixel
23521 coordinates in FR are frame-relative. Call this function with
23522 input blocked. Value is non-zero if the exposure overwrites
23523 mouse-face. */
23524
23525 static int
23526 expose_window (w, fr)
23527 struct window *w;
23528 XRectangle *fr;
23529 {
23530 struct frame *f = XFRAME (w->frame);
23531 XRectangle wr, r;
23532 int mouse_face_overwritten_p = 0;
23533
23534 /* If window is not yet fully initialized, do nothing. This can
23535 happen when toolkit scroll bars are used and a window is split.
23536 Reconfiguring the scroll bar will generate an expose for a newly
23537 created window. */
23538 if (w->current_matrix == NULL)
23539 return 0;
23540
23541 /* When we're currently updating the window, display and current
23542 matrix usually don't agree. Arrange for a thorough display
23543 later. */
23544 if (w == updated_window)
23545 {
23546 SET_FRAME_GARBAGED (f);
23547 return 0;
23548 }
23549
23550 /* Frame-relative pixel rectangle of W. */
23551 wr.x = WINDOW_LEFT_EDGE_X (w);
23552 wr.y = WINDOW_TOP_EDGE_Y (w);
23553 wr.width = WINDOW_TOTAL_WIDTH (w);
23554 wr.height = WINDOW_TOTAL_HEIGHT (w);
23555
23556 if (x_intersect_rectangles (fr, &wr, &r))
23557 {
23558 int yb = window_text_bottom_y (w);
23559 struct glyph_row *row;
23560 int cursor_cleared_p;
23561 struct glyph_row *first_overlapping_row, *last_overlapping_row;
23562
23563 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
23564 r.x, r.y, r.width, r.height));
23565
23566 /* Convert to window coordinates. */
23567 r.x -= WINDOW_LEFT_EDGE_X (w);
23568 r.y -= WINDOW_TOP_EDGE_Y (w);
23569
23570 /* Turn off the cursor. */
23571 if (!w->pseudo_window_p
23572 && phys_cursor_in_rect_p (w, &r))
23573 {
23574 x_clear_cursor (w);
23575 cursor_cleared_p = 1;
23576 }
23577 else
23578 cursor_cleared_p = 0;
23579
23580 /* Update lines intersecting rectangle R. */
23581 first_overlapping_row = last_overlapping_row = NULL;
23582 for (row = w->current_matrix->rows;
23583 row->enabled_p;
23584 ++row)
23585 {
23586 int y0 = row->y;
23587 int y1 = MATRIX_ROW_BOTTOM_Y (row);
23588
23589 if ((y0 >= r.y && y0 < r.y + r.height)
23590 || (y1 > r.y && y1 < r.y + r.height)
23591 || (r.y >= y0 && r.y < y1)
23592 || (r.y + r.height > y0 && r.y + r.height < y1))
23593 {
23594 /* A header line may be overlapping, but there is no need
23595 to fix overlapping areas for them. KFS 2005-02-12 */
23596 if (row->overlapping_p && !row->mode_line_p)
23597 {
23598 if (first_overlapping_row == NULL)
23599 first_overlapping_row = row;
23600 last_overlapping_row = row;
23601 }
23602
23603 if (expose_line (w, row, &r))
23604 mouse_face_overwritten_p = 1;
23605 }
23606
23607 if (y1 >= yb)
23608 break;
23609 }
23610
23611 /* Display the mode line if there is one. */
23612 if (WINDOW_WANTS_MODELINE_P (w)
23613 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
23614 row->enabled_p)
23615 && row->y < r.y + r.height)
23616 {
23617 if (expose_line (w, row, &r))
23618 mouse_face_overwritten_p = 1;
23619 }
23620
23621 if (!w->pseudo_window_p)
23622 {
23623 /* Fix the display of overlapping rows. */
23624 if (first_overlapping_row)
23625 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
23626
23627 /* Draw border between windows. */
23628 x_draw_vertical_border (w);
23629
23630 /* Turn the cursor on again. */
23631 if (cursor_cleared_p)
23632 update_window_cursor (w, 1);
23633 }
23634 }
23635
23636 return mouse_face_overwritten_p;
23637 }
23638
23639
23640
23641 /* Redraw (parts) of all windows in the window tree rooted at W that
23642 intersect R. R contains frame pixel coordinates. Value is
23643 non-zero if the exposure overwrites mouse-face. */
23644
23645 static int
23646 expose_window_tree (w, r)
23647 struct window *w;
23648 XRectangle *r;
23649 {
23650 struct frame *f = XFRAME (w->frame);
23651 int mouse_face_overwritten_p = 0;
23652
23653 while (w && !FRAME_GARBAGED_P (f))
23654 {
23655 if (!NILP (w->hchild))
23656 mouse_face_overwritten_p
23657 |= expose_window_tree (XWINDOW (w->hchild), r);
23658 else if (!NILP (w->vchild))
23659 mouse_face_overwritten_p
23660 |= expose_window_tree (XWINDOW (w->vchild), r);
23661 else
23662 mouse_face_overwritten_p |= expose_window (w, r);
23663
23664 w = NILP (w->next) ? NULL : XWINDOW (w->next);
23665 }
23666
23667 return mouse_face_overwritten_p;
23668 }
23669
23670
23671 /* EXPORT:
23672 Redisplay an exposed area of frame F. X and Y are the upper-left
23673 corner of the exposed rectangle. W and H are width and height of
23674 the exposed area. All are pixel values. W or H zero means redraw
23675 the entire frame. */
23676
23677 void
23678 expose_frame (f, x, y, w, h)
23679 struct frame *f;
23680 int x, y, w, h;
23681 {
23682 XRectangle r;
23683 int mouse_face_overwritten_p = 0;
23684
23685 TRACE ((stderr, "expose_frame "));
23686
23687 /* No need to redraw if frame will be redrawn soon. */
23688 if (FRAME_GARBAGED_P (f))
23689 {
23690 TRACE ((stderr, " garbaged\n"));
23691 return;
23692 }
23693
23694 /* If basic faces haven't been realized yet, there is no point in
23695 trying to redraw anything. This can happen when we get an expose
23696 event while Emacs is starting, e.g. by moving another window. */
23697 if (FRAME_FACE_CACHE (f) == NULL
23698 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
23699 {
23700 TRACE ((stderr, " no faces\n"));
23701 return;
23702 }
23703
23704 if (w == 0 || h == 0)
23705 {
23706 r.x = r.y = 0;
23707 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
23708 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
23709 }
23710 else
23711 {
23712 r.x = x;
23713 r.y = y;
23714 r.width = w;
23715 r.height = h;
23716 }
23717
23718 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
23719 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
23720
23721 if (WINDOWP (f->tool_bar_window))
23722 mouse_face_overwritten_p
23723 |= expose_window (XWINDOW (f->tool_bar_window), &r);
23724
23725 #ifdef HAVE_X_WINDOWS
23726 #ifndef MSDOS
23727 #ifndef USE_X_TOOLKIT
23728 if (WINDOWP (f->menu_bar_window))
23729 mouse_face_overwritten_p
23730 |= expose_window (XWINDOW (f->menu_bar_window), &r);
23731 #endif /* not USE_X_TOOLKIT */
23732 #endif
23733 #endif
23734
23735 /* Some window managers support a focus-follows-mouse style with
23736 delayed raising of frames. Imagine a partially obscured frame,
23737 and moving the mouse into partially obscured mouse-face on that
23738 frame. The visible part of the mouse-face will be highlighted,
23739 then the WM raises the obscured frame. With at least one WM, KDE
23740 2.1, Emacs is not getting any event for the raising of the frame
23741 (even tried with SubstructureRedirectMask), only Expose events.
23742 These expose events will draw text normally, i.e. not
23743 highlighted. Which means we must redo the highlight here.
23744 Subsume it under ``we love X''. --gerd 2001-08-15 */
23745 /* Included in Windows version because Windows most likely does not
23746 do the right thing if any third party tool offers
23747 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
23748 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
23749 {
23750 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23751 if (f == dpyinfo->mouse_face_mouse_frame)
23752 {
23753 int x = dpyinfo->mouse_face_mouse_x;
23754 int y = dpyinfo->mouse_face_mouse_y;
23755 clear_mouse_face (dpyinfo);
23756 note_mouse_highlight (f, x, y);
23757 }
23758 }
23759 }
23760
23761
23762 /* EXPORT:
23763 Determine the intersection of two rectangles R1 and R2. Return
23764 the intersection in *RESULT. Value is non-zero if RESULT is not
23765 empty. */
23766
23767 int
23768 x_intersect_rectangles (r1, r2, result)
23769 XRectangle *r1, *r2, *result;
23770 {
23771 XRectangle *left, *right;
23772 XRectangle *upper, *lower;
23773 int intersection_p = 0;
23774
23775 /* Rearrange so that R1 is the left-most rectangle. */
23776 if (r1->x < r2->x)
23777 left = r1, right = r2;
23778 else
23779 left = r2, right = r1;
23780
23781 /* X0 of the intersection is right.x0, if this is inside R1,
23782 otherwise there is no intersection. */
23783 if (right->x <= left->x + left->width)
23784 {
23785 result->x = right->x;
23786
23787 /* The right end of the intersection is the minimum of the
23788 the right ends of left and right. */
23789 result->width = (min (left->x + left->width, right->x + right->width)
23790 - result->x);
23791
23792 /* Same game for Y. */
23793 if (r1->y < r2->y)
23794 upper = r1, lower = r2;
23795 else
23796 upper = r2, lower = r1;
23797
23798 /* The upper end of the intersection is lower.y0, if this is inside
23799 of upper. Otherwise, there is no intersection. */
23800 if (lower->y <= upper->y + upper->height)
23801 {
23802 result->y = lower->y;
23803
23804 /* The lower end of the intersection is the minimum of the lower
23805 ends of upper and lower. */
23806 result->height = (min (lower->y + lower->height,
23807 upper->y + upper->height)
23808 - result->y);
23809 intersection_p = 1;
23810 }
23811 }
23812
23813 return intersection_p;
23814 }
23815
23816 #endif /* HAVE_WINDOW_SYSTEM */
23817
23818 \f
23819 /***********************************************************************
23820 Initialization
23821 ***********************************************************************/
23822
23823 void
23824 syms_of_xdisp ()
23825 {
23826 Vwith_echo_area_save_vector = Qnil;
23827 staticpro (&Vwith_echo_area_save_vector);
23828
23829 Vmessage_stack = Qnil;
23830 staticpro (&Vmessage_stack);
23831
23832 Qinhibit_redisplay = intern ("inhibit-redisplay");
23833 staticpro (&Qinhibit_redisplay);
23834
23835 message_dolog_marker1 = Fmake_marker ();
23836 staticpro (&message_dolog_marker1);
23837 message_dolog_marker2 = Fmake_marker ();
23838 staticpro (&message_dolog_marker2);
23839 message_dolog_marker3 = Fmake_marker ();
23840 staticpro (&message_dolog_marker3);
23841
23842 #if GLYPH_DEBUG
23843 defsubr (&Sdump_frame_glyph_matrix);
23844 defsubr (&Sdump_glyph_matrix);
23845 defsubr (&Sdump_glyph_row);
23846 defsubr (&Sdump_tool_bar_row);
23847 defsubr (&Strace_redisplay);
23848 defsubr (&Strace_to_stderr);
23849 #endif
23850 #ifdef HAVE_WINDOW_SYSTEM
23851 defsubr (&Stool_bar_lines_needed);
23852 defsubr (&Slookup_image_map);
23853 #endif
23854 defsubr (&Sformat_mode_line);
23855 defsubr (&Sinvisible_p);
23856
23857 staticpro (&Qmenu_bar_update_hook);
23858 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
23859
23860 staticpro (&Qoverriding_terminal_local_map);
23861 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
23862
23863 staticpro (&Qoverriding_local_map);
23864 Qoverriding_local_map = intern ("overriding-local-map");
23865
23866 staticpro (&Qwindow_scroll_functions);
23867 Qwindow_scroll_functions = intern ("window-scroll-functions");
23868
23869 staticpro (&Qredisplay_end_trigger_functions);
23870 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
23871
23872 staticpro (&Qinhibit_point_motion_hooks);
23873 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
23874
23875 QCdata = intern (":data");
23876 staticpro (&QCdata);
23877 Qdisplay = intern ("display");
23878 staticpro (&Qdisplay);
23879 Qspace_width = intern ("space-width");
23880 staticpro (&Qspace_width);
23881 Qraise = intern ("raise");
23882 staticpro (&Qraise);
23883 Qslice = intern ("slice");
23884 staticpro (&Qslice);
23885 Qspace = intern ("space");
23886 staticpro (&Qspace);
23887 Qmargin = intern ("margin");
23888 staticpro (&Qmargin);
23889 Qpointer = intern ("pointer");
23890 staticpro (&Qpointer);
23891 Qleft_margin = intern ("left-margin");
23892 staticpro (&Qleft_margin);
23893 Qright_margin = intern ("right-margin");
23894 staticpro (&Qright_margin);
23895 Qcenter = intern ("center");
23896 staticpro (&Qcenter);
23897 Qline_height = intern ("line-height");
23898 staticpro (&Qline_height);
23899 QCalign_to = intern (":align-to");
23900 staticpro (&QCalign_to);
23901 QCrelative_width = intern (":relative-width");
23902 staticpro (&QCrelative_width);
23903 QCrelative_height = intern (":relative-height");
23904 staticpro (&QCrelative_height);
23905 QCeval = intern (":eval");
23906 staticpro (&QCeval);
23907 QCpropertize = intern (":propertize");
23908 staticpro (&QCpropertize);
23909 QCfile = intern (":file");
23910 staticpro (&QCfile);
23911 Qfontified = intern ("fontified");
23912 staticpro (&Qfontified);
23913 Qfontification_functions = intern ("fontification-functions");
23914 staticpro (&Qfontification_functions);
23915 Qtrailing_whitespace = intern ("trailing-whitespace");
23916 staticpro (&Qtrailing_whitespace);
23917 Qescape_glyph = intern ("escape-glyph");
23918 staticpro (&Qescape_glyph);
23919 Qnobreak_space = intern ("nobreak-space");
23920 staticpro (&Qnobreak_space);
23921 Qimage = intern ("image");
23922 staticpro (&Qimage);
23923 QCmap = intern (":map");
23924 staticpro (&QCmap);
23925 QCpointer = intern (":pointer");
23926 staticpro (&QCpointer);
23927 Qrect = intern ("rect");
23928 staticpro (&Qrect);
23929 Qcircle = intern ("circle");
23930 staticpro (&Qcircle);
23931 Qpoly = intern ("poly");
23932 staticpro (&Qpoly);
23933 Qmessage_truncate_lines = intern ("message-truncate-lines");
23934 staticpro (&Qmessage_truncate_lines);
23935 Qgrow_only = intern ("grow-only");
23936 staticpro (&Qgrow_only);
23937 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
23938 staticpro (&Qinhibit_menubar_update);
23939 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
23940 staticpro (&Qinhibit_eval_during_redisplay);
23941 Qposition = intern ("position");
23942 staticpro (&Qposition);
23943 Qbuffer_position = intern ("buffer-position");
23944 staticpro (&Qbuffer_position);
23945 Qobject = intern ("object");
23946 staticpro (&Qobject);
23947 Qbar = intern ("bar");
23948 staticpro (&Qbar);
23949 Qhbar = intern ("hbar");
23950 staticpro (&Qhbar);
23951 Qbox = intern ("box");
23952 staticpro (&Qbox);
23953 Qhollow = intern ("hollow");
23954 staticpro (&Qhollow);
23955 Qhand = intern ("hand");
23956 staticpro (&Qhand);
23957 Qarrow = intern ("arrow");
23958 staticpro (&Qarrow);
23959 Qtext = intern ("text");
23960 staticpro (&Qtext);
23961 Qrisky_local_variable = intern ("risky-local-variable");
23962 staticpro (&Qrisky_local_variable);
23963 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
23964 staticpro (&Qinhibit_free_realized_faces);
23965
23966 list_of_error = Fcons (Fcons (intern ("error"),
23967 Fcons (intern ("void-variable"), Qnil)),
23968 Qnil);
23969 staticpro (&list_of_error);
23970
23971 Qlast_arrow_position = intern ("last-arrow-position");
23972 staticpro (&Qlast_arrow_position);
23973 Qlast_arrow_string = intern ("last-arrow-string");
23974 staticpro (&Qlast_arrow_string);
23975
23976 Qoverlay_arrow_string = intern ("overlay-arrow-string");
23977 staticpro (&Qoverlay_arrow_string);
23978 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
23979 staticpro (&Qoverlay_arrow_bitmap);
23980
23981 echo_buffer[0] = echo_buffer[1] = Qnil;
23982 staticpro (&echo_buffer[0]);
23983 staticpro (&echo_buffer[1]);
23984
23985 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
23986 staticpro (&echo_area_buffer[0]);
23987 staticpro (&echo_area_buffer[1]);
23988
23989 Vmessages_buffer_name = build_string ("*Messages*");
23990 staticpro (&Vmessages_buffer_name);
23991
23992 mode_line_proptrans_alist = Qnil;
23993 staticpro (&mode_line_proptrans_alist);
23994 mode_line_string_list = Qnil;
23995 staticpro (&mode_line_string_list);
23996 mode_line_string_face = Qnil;
23997 staticpro (&mode_line_string_face);
23998 mode_line_string_face_prop = Qnil;
23999 staticpro (&mode_line_string_face_prop);
24000 Vmode_line_unwind_vector = Qnil;
24001 staticpro (&Vmode_line_unwind_vector);
24002
24003 help_echo_string = Qnil;
24004 staticpro (&help_echo_string);
24005 help_echo_object = Qnil;
24006 staticpro (&help_echo_object);
24007 help_echo_window = Qnil;
24008 staticpro (&help_echo_window);
24009 previous_help_echo_string = Qnil;
24010 staticpro (&previous_help_echo_string);
24011 help_echo_pos = -1;
24012
24013 #ifdef HAVE_WINDOW_SYSTEM
24014 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
24015 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
24016 For example, if a block cursor is over a tab, it will be drawn as
24017 wide as that tab on the display. */);
24018 x_stretch_cursor_p = 0;
24019 #endif
24020
24021 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
24022 doc: /* *Non-nil means highlight trailing whitespace.
24023 The face used for trailing whitespace is `trailing-whitespace'. */);
24024 Vshow_trailing_whitespace = Qnil;
24025
24026 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
24027 doc: /* *Control highlighting of nobreak space and soft hyphen.
24028 A value of t means highlight the character itself (for nobreak space,
24029 use face `nobreak-space').
24030 A value of nil means no highlighting.
24031 Other values mean display the escape glyph followed by an ordinary
24032 space or ordinary hyphen. */);
24033 Vnobreak_char_display = Qt;
24034
24035 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
24036 doc: /* *The pointer shape to show in void text areas.
24037 A value of nil means to show the text pointer. Other options are `arrow',
24038 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
24039 Vvoid_text_area_pointer = Qarrow;
24040
24041 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
24042 doc: /* Non-nil means don't actually do any redisplay.
24043 This is used for internal purposes. */);
24044 Vinhibit_redisplay = Qnil;
24045
24046 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
24047 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
24048 Vglobal_mode_string = Qnil;
24049
24050 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
24051 doc: /* Marker for where to display an arrow on top of the buffer text.
24052 This must be the beginning of a line in order to work.
24053 See also `overlay-arrow-string'. */);
24054 Voverlay_arrow_position = Qnil;
24055
24056 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
24057 doc: /* String to display as an arrow in non-window frames.
24058 See also `overlay-arrow-position'. */);
24059 Voverlay_arrow_string = build_string ("=>");
24060
24061 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
24062 doc: /* List of variables (symbols) which hold markers for overlay arrows.
24063 The symbols on this list are examined during redisplay to determine
24064 where to display overlay arrows. */);
24065 Voverlay_arrow_variable_list
24066 = Fcons (intern ("overlay-arrow-position"), Qnil);
24067
24068 DEFVAR_INT ("scroll-step", &scroll_step,
24069 doc: /* *The number of lines to try scrolling a window by when point moves out.
24070 If that fails to bring point back on frame, point is centered instead.
24071 If this is zero, point is always centered after it moves off frame.
24072 If you want scrolling to always be a line at a time, you should set
24073 `scroll-conservatively' to a large value rather than set this to 1. */);
24074
24075 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
24076 doc: /* *Scroll up to this many lines, to bring point back on screen.
24077 A value of zero means to scroll the text to center point vertically
24078 in the window. */);
24079 scroll_conservatively = 0;
24080
24081 DEFVAR_INT ("scroll-margin", &scroll_margin,
24082 doc: /* *Number of lines of margin at the top and bottom of a window.
24083 Recenter the window whenever point gets within this many lines
24084 of the top or bottom of the window. */);
24085 scroll_margin = 0;
24086
24087 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
24088 doc: /* Pixels per inch value for non-window system displays.
24089 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
24090 Vdisplay_pixels_per_inch = make_float (72.0);
24091
24092 #if GLYPH_DEBUG
24093 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
24094 #endif
24095
24096 DEFVAR_BOOL ("truncate-partial-width-windows",
24097 &truncate_partial_width_windows,
24098 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
24099 truncate_partial_width_windows = 1;
24100
24101 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
24102 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
24103 Any other value means to use the appropriate face, `mode-line',
24104 `header-line', or `menu' respectively. */);
24105 mode_line_inverse_video = 1;
24106
24107 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
24108 doc: /* *Maximum buffer size for which line number should be displayed.
24109 If the buffer is bigger than this, the line number does not appear
24110 in the mode line. A value of nil means no limit. */);
24111 Vline_number_display_limit = Qnil;
24112
24113 DEFVAR_INT ("line-number-display-limit-width",
24114 &line_number_display_limit_width,
24115 doc: /* *Maximum line width (in characters) for line number display.
24116 If the average length of the lines near point is bigger than this, then the
24117 line number may be omitted from the mode line. */);
24118 line_number_display_limit_width = 200;
24119
24120 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
24121 doc: /* *Non-nil means highlight region even in nonselected windows. */);
24122 highlight_nonselected_windows = 0;
24123
24124 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
24125 doc: /* Non-nil if more than one frame is visible on this display.
24126 Minibuffer-only frames don't count, but iconified frames do.
24127 This variable is not guaranteed to be accurate except while processing
24128 `frame-title-format' and `icon-title-format'. */);
24129
24130 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
24131 doc: /* Template for displaying the title bar of visible frames.
24132 \(Assuming the window manager supports this feature.)
24133
24134 This variable has the same structure as `mode-line-format', except that
24135 the %c and %l constructs are ignored. It is used only on frames for
24136 which no explicit name has been set \(see `modify-frame-parameters'). */);
24137
24138 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
24139 doc: /* Template for displaying the title bar of an iconified frame.
24140 \(Assuming the window manager supports this feature.)
24141 This variable has the same structure as `mode-line-format' (which see),
24142 and is used only on frames for which no explicit name has been set
24143 \(see `modify-frame-parameters'). */);
24144 Vicon_title_format
24145 = Vframe_title_format
24146 = Fcons (intern ("multiple-frames"),
24147 Fcons (build_string ("%b"),
24148 Fcons (Fcons (empty_unibyte_string,
24149 Fcons (intern ("invocation-name"),
24150 Fcons (build_string ("@"),
24151 Fcons (intern ("system-name"),
24152 Qnil)))),
24153 Qnil)));
24154
24155 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
24156 doc: /* Maximum number of lines to keep in the message log buffer.
24157 If nil, disable message logging. If t, log messages but don't truncate
24158 the buffer when it becomes large. */);
24159 Vmessage_log_max = make_number (100);
24160
24161 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
24162 doc: /* Functions called before redisplay, if window sizes have changed.
24163 The value should be a list of functions that take one argument.
24164 Just before redisplay, for each frame, if any of its windows have changed
24165 size since the last redisplay, or have been split or deleted,
24166 all the functions in the list are called, with the frame as argument. */);
24167 Vwindow_size_change_functions = Qnil;
24168
24169 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
24170 doc: /* List of functions to call before redisplaying a window with scrolling.
24171 Each function is called with two arguments, the window
24172 and its new display-start position. Note that the value of `window-end'
24173 is not valid when these functions are called. */);
24174 Vwindow_scroll_functions = Qnil;
24175
24176 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
24177 doc: /* Functions called when redisplay of a window reaches the end trigger.
24178 Each function is called with two arguments, the window and the end trigger value.
24179 See `set-window-redisplay-end-trigger'. */);
24180 Vredisplay_end_trigger_functions = Qnil;
24181
24182 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
24183 doc: /* *Non-nil means autoselect window with mouse pointer.
24184 If nil, do not autoselect windows.
24185 A positive number means delay autoselection by that many seconds: a
24186 window is autoselected only after the mouse has remained in that
24187 window for the duration of the delay.
24188 A negative number has a similar effect, but causes windows to be
24189 autoselected only after the mouse has stopped moving. \(Because of
24190 the way Emacs compares mouse events, you will occasionally wait twice
24191 that time before the window gets selected.\)
24192 Any other value means to autoselect window instantaneously when the
24193 mouse pointer enters it.
24194
24195 Autoselection selects the minibuffer only if it is active, and never
24196 unselects the minibuffer if it is active. */);
24197 Vmouse_autoselect_window = Qnil;
24198
24199 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
24200 doc: /* *Non-nil means automatically resize tool-bars.
24201 This dynamically changes the tool-bar's height to the minimum height
24202 that is needed to make all tool-bar items visible.
24203 If value is `grow-only', the tool-bar's height is only increased
24204 automatically; to decrease the tool-bar height, use \\[recenter]. */);
24205 Vauto_resize_tool_bars = Qt;
24206
24207 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
24208 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
24209 auto_raise_tool_bar_buttons_p = 1;
24210
24211 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
24212 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
24213 make_cursor_line_fully_visible_p = 1;
24214
24215 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
24216 doc: /* *Border below tool-bar in pixels.
24217 If an integer, use it as the height of the border.
24218 If it is one of `internal-border-width' or `border-width', use the
24219 value of the corresponding frame parameter.
24220 Otherwise, no border is added below the tool-bar. */);
24221 Vtool_bar_border = Qinternal_border_width;
24222
24223 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
24224 doc: /* *Margin around tool-bar buttons in pixels.
24225 If an integer, use that for both horizontal and vertical margins.
24226 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
24227 HORZ specifying the horizontal margin, and VERT specifying the
24228 vertical margin. */);
24229 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
24230
24231 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
24232 doc: /* *Relief thickness of tool-bar buttons. */);
24233 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
24234
24235 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
24236 doc: /* List of functions to call to fontify regions of text.
24237 Each function is called with one argument POS. Functions must
24238 fontify a region starting at POS in the current buffer, and give
24239 fontified regions the property `fontified'. */);
24240 Vfontification_functions = Qnil;
24241 Fmake_variable_buffer_local (Qfontification_functions);
24242
24243 DEFVAR_BOOL ("unibyte-display-via-language-environment",
24244 &unibyte_display_via_language_environment,
24245 doc: /* *Non-nil means display unibyte text according to language environment.
24246 Specifically this means that unibyte non-ASCII characters
24247 are displayed by converting them to the equivalent multibyte characters
24248 according to the current language environment. As a result, they are
24249 displayed according to the current fontset. */);
24250 unibyte_display_via_language_environment = 0;
24251
24252 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
24253 doc: /* *Maximum height for resizing mini-windows.
24254 If a float, it specifies a fraction of the mini-window frame's height.
24255 If an integer, it specifies a number of lines. */);
24256 Vmax_mini_window_height = make_float (0.25);
24257
24258 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
24259 doc: /* *How to resize mini-windows.
24260 A value of nil means don't automatically resize mini-windows.
24261 A value of t means resize them to fit the text displayed in them.
24262 A value of `grow-only', the default, means let mini-windows grow
24263 only, until their display becomes empty, at which point the windows
24264 go back to their normal size. */);
24265 Vresize_mini_windows = Qgrow_only;
24266
24267 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
24268 doc: /* Alist specifying how to blink the cursor off.
24269 Each element has the form (ON-STATE . OFF-STATE). Whenever the
24270 `cursor-type' frame-parameter or variable equals ON-STATE,
24271 comparing using `equal', Emacs uses OFF-STATE to specify
24272 how to blink it off. ON-STATE and OFF-STATE are values for
24273 the `cursor-type' frame parameter.
24274
24275 If a frame's ON-STATE has no entry in this list,
24276 the frame's other specifications determine how to blink the cursor off. */);
24277 Vblink_cursor_alist = Qnil;
24278
24279 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
24280 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
24281 automatic_hscrolling_p = 1;
24282
24283 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
24284 doc: /* *How many columns away from the window edge point is allowed to get
24285 before automatic hscrolling will horizontally scroll the window. */);
24286 hscroll_margin = 5;
24287
24288 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
24289 doc: /* *How many columns to scroll the window when point gets too close to the edge.
24290 When point is less than `hscroll-margin' columns from the window
24291 edge, automatic hscrolling will scroll the window by the amount of columns
24292 determined by this variable. If its value is a positive integer, scroll that
24293 many columns. If it's a positive floating-point number, it specifies the
24294 fraction of the window's width to scroll. If it's nil or zero, point will be
24295 centered horizontally after the scroll. Any other value, including negative
24296 numbers, are treated as if the value were zero.
24297
24298 Automatic hscrolling always moves point outside the scroll margin, so if
24299 point was more than scroll step columns inside the margin, the window will
24300 scroll more than the value given by the scroll step.
24301
24302 Note that the lower bound for automatic hscrolling specified by `scroll-left'
24303 and `scroll-right' overrides this variable's effect. */);
24304 Vhscroll_step = make_number (0);
24305
24306 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
24307 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
24308 Bind this around calls to `message' to let it take effect. */);
24309 message_truncate_lines = 0;
24310
24311 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
24312 doc: /* Normal hook run to update the menu bar definitions.
24313 Redisplay runs this hook before it redisplays the menu bar.
24314 This is used to update submenus such as Buffers,
24315 whose contents depend on various data. */);
24316 Vmenu_bar_update_hook = Qnil;
24317
24318 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
24319 doc: /* Frame for which we are updating a menu.
24320 The enable predicate for a menu binding should check this variable. */);
24321 Vmenu_updating_frame = Qnil;
24322
24323 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
24324 doc: /* Non-nil means don't update menu bars. Internal use only. */);
24325 inhibit_menubar_update = 0;
24326
24327 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
24328 doc: /* Non-nil means don't eval Lisp during redisplay. */);
24329 inhibit_eval_during_redisplay = 0;
24330
24331 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
24332 doc: /* Non-nil means don't free realized faces. Internal use only. */);
24333 inhibit_free_realized_faces = 0;
24334
24335 #if GLYPH_DEBUG
24336 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
24337 doc: /* Inhibit try_window_id display optimization. */);
24338 inhibit_try_window_id = 0;
24339
24340 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
24341 doc: /* Inhibit try_window_reusing display optimization. */);
24342 inhibit_try_window_reusing = 0;
24343
24344 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
24345 doc: /* Inhibit try_cursor_movement display optimization. */);
24346 inhibit_try_cursor_movement = 0;
24347 #endif /* GLYPH_DEBUG */
24348
24349 DEFVAR_INT ("overline-margin", &overline_margin,
24350 doc: /* *Space between overline and text, in pixels.
24351 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
24352 margin to the caracter height. */);
24353 overline_margin = 2;
24354 }
24355
24356
24357 /* Initialize this module when Emacs starts. */
24358
24359 void
24360 init_xdisp ()
24361 {
24362 Lisp_Object root_window;
24363 struct window *mini_w;
24364
24365 current_header_line_height = current_mode_line_height = -1;
24366
24367 CHARPOS (this_line_start_pos) = 0;
24368
24369 mini_w = XWINDOW (minibuf_window);
24370 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
24371
24372 if (!noninteractive)
24373 {
24374 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
24375 int i;
24376
24377 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
24378 set_window_height (root_window,
24379 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
24380 0);
24381 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
24382 set_window_height (minibuf_window, 1, 0);
24383
24384 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
24385 mini_w->total_cols = make_number (FRAME_COLS (f));
24386
24387 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
24388 scratch_glyph_row.glyphs[TEXT_AREA + 1]
24389 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
24390
24391 /* The default ellipsis glyphs `...'. */
24392 for (i = 0; i < 3; ++i)
24393 default_invis_vector[i] = make_number ('.');
24394 }
24395
24396 {
24397 /* Allocate the buffer for frame titles.
24398 Also used for `format-mode-line'. */
24399 int size = 100;
24400 mode_line_noprop_buf = (char *) xmalloc (size);
24401 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
24402 mode_line_noprop_ptr = mode_line_noprop_buf;
24403 mode_line_target = MODE_LINE_DISPLAY;
24404 }
24405
24406 help_echo_showing_p = 0;
24407 }
24408
24409
24410 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
24411 (do not change this comment) */