]> code.delx.au - gnu-emacs/blob - src/xdisp.c
(main) [MAC_OS8 || MAC_OSX && HAVE_CARBON]: Call syms_of_macselect.
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
30
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the description of direct update
37 operations, below.)
38
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
48
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
62 |
63 expose_window (asynchronous) |
64 |
65 X expose events -----+
66
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
71
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
81
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
87
88
89 Direct operations.
90
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
95
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
102
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
108
109
110 Desired matrices.
111
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
118
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
124 argument.
125
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
131
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
137 see in dispextern.h.
138
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
146
147
148 Frame matrices.
149
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
156
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
168
169 #include <config.h>
170 #include <stdio.h>
171
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "keymap.h"
183 #include "macros.h"
184 #include "disptab.h"
185 #include "termhooks.h"
186 #include "intervals.h"
187 #include "coding.h"
188 #include "process.h"
189 #include "region-cache.h"
190 #include "fontset.h"
191 #include "blockinput.h"
192
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196 #ifdef WINDOWSNT
197 #include "w32term.h"
198 #endif
199 #ifdef MAC_OS
200 #include "macterm.h"
201 #endif
202
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
205 #endif
206
207 #define INFINITY 10000000
208
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
210 || defined (USE_GTK)
211 extern void set_frame_menubar P_ ((struct frame *f, int, int));
212 extern int pending_menu_activation;
213 #endif
214
215 extern int interrupt_input;
216 extern int command_loop_level;
217
218 extern Lisp_Object do_mouse_tracking;
219
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
222
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
225
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
231
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
241
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
244
245 /* Pointer shapes */
246 Lisp_Object Qarrow, Qhand, Qtext;
247
248 Lisp_Object Qrisky_local_variable;
249
250 /* Holds the list (error). */
251 Lisp_Object list_of_error;
252
253 /* Functions called to fontify regions of text. */
254
255 Lisp_Object Vfontification_functions;
256 Lisp_Object Qfontification_functions;
257
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window;
261
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 over them. */
264
265 int auto_raise_tool_bar_buttons_p;
266
267 /* Non-zero means to reposition window if cursor line is only partially visible. */
268
269 int make_cursor_line_fully_visible_p;
270
271 /* Margin around tool bar buttons in pixels. */
272
273 Lisp_Object Vtool_bar_button_margin;
274
275 /* Thickness of shadow to draw around tool bar buttons. */
276
277 EMACS_INT tool_bar_button_relief;
278
279 /* Non-zero means automatically resize tool-bars so that all tool-bar
280 items are visible, and no blank lines remain. */
281
282 int auto_resize_tool_bars_p;
283
284 /* Non-zero means draw block and hollow cursor as wide as the glyph
285 under it. For example, if a block cursor is over a tab, it will be
286 drawn as wide as that tab on the display. */
287
288 int x_stretch_cursor_p;
289
290 /* Non-nil means don't actually do any redisplay. */
291
292 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
293
294 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
295
296 int inhibit_eval_during_redisplay;
297
298 /* Names of text properties relevant for redisplay. */
299
300 Lisp_Object Qdisplay;
301 extern Lisp_Object Qface, Qinvisible, Qwidth;
302
303 /* Symbols used in text property values. */
304
305 Lisp_Object Vdisplay_pixels_per_inch;
306 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
307 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
308 Lisp_Object Qslice;
309 Lisp_Object Qcenter;
310 Lisp_Object Qmargin, Qpointer;
311 Lisp_Object Qline_height;
312 extern Lisp_Object Qheight;
313 extern Lisp_Object QCwidth, QCheight, QCascent;
314 extern Lisp_Object Qscroll_bar;
315 extern Lisp_Object Qcursor;
316
317 /* Non-nil means highlight trailing whitespace. */
318
319 Lisp_Object Vshow_trailing_whitespace;
320
321 /* Non-nil means escape non-break space and hyphens. */
322
323 Lisp_Object Vshow_nonbreak_escape;
324
325 #ifdef HAVE_WINDOW_SYSTEM
326 extern Lisp_Object Voverflow_newline_into_fringe;
327
328 /* Test if overflow newline into fringe. Called with iterator IT
329 at or past right window margin, and with IT->current_x set. */
330
331 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
332 (!NILP (Voverflow_newline_into_fringe) \
333 && FRAME_WINDOW_P (it->f) \
334 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
335 && it->current_x == it->last_visible_x)
336
337 #endif /* HAVE_WINDOW_SYSTEM */
338
339 /* Non-nil means show the text cursor in void text areas
340 i.e. in blank areas after eol and eob. This used to be
341 the default in 21.3. */
342
343 Lisp_Object Vvoid_text_area_pointer;
344
345 /* Name of the face used to highlight trailing whitespace. */
346
347 Lisp_Object Qtrailing_whitespace;
348
349 /* Name and number of the face used to highlight escape glyphs. */
350
351 Lisp_Object Qescape_glyph;
352
353 /* The symbol `image' which is the car of the lists used to represent
354 images in Lisp. */
355
356 Lisp_Object Qimage;
357
358 /* The image map types. */
359 Lisp_Object QCmap, QCpointer;
360 Lisp_Object Qrect, Qcircle, Qpoly;
361
362 /* Non-zero means print newline to stdout before next mini-buffer
363 message. */
364
365 int noninteractive_need_newline;
366
367 /* Non-zero means print newline to message log before next message. */
368
369 static int message_log_need_newline;
370
371 /* Three markers that message_dolog uses.
372 It could allocate them itself, but that causes trouble
373 in handling memory-full errors. */
374 static Lisp_Object message_dolog_marker1;
375 static Lisp_Object message_dolog_marker2;
376 static Lisp_Object message_dolog_marker3;
377 \f
378 /* The buffer position of the first character appearing entirely or
379 partially on the line of the selected window which contains the
380 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
381 redisplay optimization in redisplay_internal. */
382
383 static struct text_pos this_line_start_pos;
384
385 /* Number of characters past the end of the line above, including the
386 terminating newline. */
387
388 static struct text_pos this_line_end_pos;
389
390 /* The vertical positions and the height of this line. */
391
392 static int this_line_vpos;
393 static int this_line_y;
394 static int this_line_pixel_height;
395
396 /* X position at which this display line starts. Usually zero;
397 negative if first character is partially visible. */
398
399 static int this_line_start_x;
400
401 /* Buffer that this_line_.* variables are referring to. */
402
403 static struct buffer *this_line_buffer;
404
405 /* Nonzero means truncate lines in all windows less wide than the
406 frame. */
407
408 int truncate_partial_width_windows;
409
410 /* A flag to control how to display unibyte 8-bit character. */
411
412 int unibyte_display_via_language_environment;
413
414 /* Nonzero means we have more than one non-mini-buffer-only frame.
415 Not guaranteed to be accurate except while parsing
416 frame-title-format. */
417
418 int multiple_frames;
419
420 Lisp_Object Vglobal_mode_string;
421
422
423 /* List of variables (symbols) which hold markers for overlay arrows.
424 The symbols on this list are examined during redisplay to determine
425 where to display overlay arrows. */
426
427 Lisp_Object Voverlay_arrow_variable_list;
428
429 /* Marker for where to display an arrow on top of the buffer text. */
430
431 Lisp_Object Voverlay_arrow_position;
432
433 /* String to display for the arrow. Only used on terminal frames. */
434
435 Lisp_Object Voverlay_arrow_string;
436
437 /* Values of those variables at last redisplay are stored as
438 properties on `overlay-arrow-position' symbol. However, if
439 Voverlay_arrow_position is a marker, last-arrow-position is its
440 numerical position. */
441
442 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
443
444 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
445 properties on a symbol in overlay-arrow-variable-list. */
446
447 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
448
449 /* Like mode-line-format, but for the title bar on a visible frame. */
450
451 Lisp_Object Vframe_title_format;
452
453 /* Like mode-line-format, but for the title bar on an iconified frame. */
454
455 Lisp_Object Vicon_title_format;
456
457 /* List of functions to call when a window's size changes. These
458 functions get one arg, a frame on which one or more windows' sizes
459 have changed. */
460
461 static Lisp_Object Vwindow_size_change_functions;
462
463 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
464
465 /* Nonzero if an overlay arrow has been displayed in this window. */
466
467 static int overlay_arrow_seen;
468
469 /* Nonzero means highlight the region even in nonselected windows. */
470
471 int highlight_nonselected_windows;
472
473 /* If cursor motion alone moves point off frame, try scrolling this
474 many lines up or down if that will bring it back. */
475
476 static EMACS_INT scroll_step;
477
478 /* Nonzero means scroll just far enough to bring point back on the
479 screen, when appropriate. */
480
481 static EMACS_INT scroll_conservatively;
482
483 /* Recenter the window whenever point gets within this many lines of
484 the top or bottom of the window. This value is translated into a
485 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
486 that there is really a fixed pixel height scroll margin. */
487
488 EMACS_INT scroll_margin;
489
490 /* Number of windows showing the buffer of the selected window (or
491 another buffer with the same base buffer). keyboard.c refers to
492 this. */
493
494 int buffer_shared;
495
496 /* Vector containing glyphs for an ellipsis `...'. */
497
498 static Lisp_Object default_invis_vector[3];
499
500 /* Zero means display the mode-line/header-line/menu-bar in the default face
501 (this slightly odd definition is for compatibility with previous versions
502 of emacs), non-zero means display them using their respective faces.
503
504 This variable is deprecated. */
505
506 int mode_line_inverse_video;
507
508 /* Prompt to display in front of the mini-buffer contents. */
509
510 Lisp_Object minibuf_prompt;
511
512 /* Width of current mini-buffer prompt. Only set after display_line
513 of the line that contains the prompt. */
514
515 int minibuf_prompt_width;
516
517 /* This is the window where the echo area message was displayed. It
518 is always a mini-buffer window, but it may not be the same window
519 currently active as a mini-buffer. */
520
521 Lisp_Object echo_area_window;
522
523 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
524 pushes the current message and the value of
525 message_enable_multibyte on the stack, the function restore_message
526 pops the stack and displays MESSAGE again. */
527
528 Lisp_Object Vmessage_stack;
529
530 /* Nonzero means multibyte characters were enabled when the echo area
531 message was specified. */
532
533 int message_enable_multibyte;
534
535 /* Nonzero if we should redraw the mode lines on the next redisplay. */
536
537 int update_mode_lines;
538
539 /* Nonzero if window sizes or contents have changed since last
540 redisplay that finished. */
541
542 int windows_or_buffers_changed;
543
544 /* Nonzero means a frame's cursor type has been changed. */
545
546 int cursor_type_changed;
547
548 /* Nonzero after display_mode_line if %l was used and it displayed a
549 line number. */
550
551 int line_number_displayed;
552
553 /* Maximum buffer size for which to display line numbers. */
554
555 Lisp_Object Vline_number_display_limit;
556
557 /* Line width to consider when repositioning for line number display. */
558
559 static EMACS_INT line_number_display_limit_width;
560
561 /* Number of lines to keep in the message log buffer. t means
562 infinite. nil means don't log at all. */
563
564 Lisp_Object Vmessage_log_max;
565
566 /* The name of the *Messages* buffer, a string. */
567
568 static Lisp_Object Vmessages_buffer_name;
569
570 /* Index 0 is the buffer that holds the current (desired) echo area message,
571 or nil if none is desired right now.
572
573 Index 1 is the buffer that holds the previously displayed echo area message,
574 or nil to indicate no message. This is normally what's on the screen now.
575
576 These two can point to the same buffer. That happens when the last
577 message output by the user (or made by echoing) has been displayed. */
578
579 Lisp_Object echo_area_buffer[2];
580
581 /* Permanent pointers to the two buffers that are used for echo area
582 purposes. Once the two buffers are made, and their pointers are
583 placed here, these two slots remain unchanged unless those buffers
584 need to be created afresh. */
585
586 static Lisp_Object echo_buffer[2];
587
588 /* A vector saved used in with_area_buffer to reduce consing. */
589
590 static Lisp_Object Vwith_echo_area_save_vector;
591
592 /* Non-zero means display_echo_area should display the last echo area
593 message again. Set by redisplay_preserve_echo_area. */
594
595 static int display_last_displayed_message_p;
596
597 /* Nonzero if echo area is being used by print; zero if being used by
598 message. */
599
600 int message_buf_print;
601
602 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
603
604 Lisp_Object Qinhibit_menubar_update;
605 int inhibit_menubar_update;
606
607 /* Maximum height for resizing mini-windows. Either a float
608 specifying a fraction of the available height, or an integer
609 specifying a number of lines. */
610
611 Lisp_Object Vmax_mini_window_height;
612
613 /* Non-zero means messages should be displayed with truncated
614 lines instead of being continued. */
615
616 int message_truncate_lines;
617 Lisp_Object Qmessage_truncate_lines;
618
619 /* Set to 1 in clear_message to make redisplay_internal aware
620 of an emptied echo area. */
621
622 static int message_cleared_p;
623
624 /* Non-zero means we want a hollow cursor in windows that are not
625 selected. Zero means there's no cursor in such windows. */
626
627 Lisp_Object Vcursor_in_non_selected_windows;
628 Lisp_Object Qcursor_in_non_selected_windows;
629
630 /* How to blink the default frame cursor off. */
631 Lisp_Object Vblink_cursor_alist;
632
633 /* A scratch glyph row with contents used for generating truncation
634 glyphs. Also used in direct_output_for_insert. */
635
636 #define MAX_SCRATCH_GLYPHS 100
637 struct glyph_row scratch_glyph_row;
638 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
639
640 /* Ascent and height of the last line processed by move_it_to. */
641
642 static int last_max_ascent, last_height;
643
644 /* Non-zero if there's a help-echo in the echo area. */
645
646 int help_echo_showing_p;
647
648 /* If >= 0, computed, exact values of mode-line and header-line height
649 to use in the macros CURRENT_MODE_LINE_HEIGHT and
650 CURRENT_HEADER_LINE_HEIGHT. */
651
652 int current_mode_line_height, current_header_line_height;
653
654 /* The maximum distance to look ahead for text properties. Values
655 that are too small let us call compute_char_face and similar
656 functions too often which is expensive. Values that are too large
657 let us call compute_char_face and alike too often because we
658 might not be interested in text properties that far away. */
659
660 #define TEXT_PROP_DISTANCE_LIMIT 100
661
662 #if GLYPH_DEBUG
663
664 /* Variables to turn off display optimizations from Lisp. */
665
666 int inhibit_try_window_id, inhibit_try_window_reusing;
667 int inhibit_try_cursor_movement;
668
669 /* Non-zero means print traces of redisplay if compiled with
670 GLYPH_DEBUG != 0. */
671
672 int trace_redisplay_p;
673
674 #endif /* GLYPH_DEBUG */
675
676 #ifdef DEBUG_TRACE_MOVE
677 /* Non-zero means trace with TRACE_MOVE to stderr. */
678 int trace_move;
679
680 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
681 #else
682 #define TRACE_MOVE(x) (void) 0
683 #endif
684
685 /* Non-zero means automatically scroll windows horizontally to make
686 point visible. */
687
688 int automatic_hscrolling_p;
689
690 /* How close to the margin can point get before the window is scrolled
691 horizontally. */
692 EMACS_INT hscroll_margin;
693
694 /* How much to scroll horizontally when point is inside the above margin. */
695 Lisp_Object Vhscroll_step;
696
697 /* The variable `resize-mini-windows'. If nil, don't resize
698 mini-windows. If t, always resize them to fit the text they
699 display. If `grow-only', let mini-windows grow only until they
700 become empty. */
701
702 Lisp_Object Vresize_mini_windows;
703
704 /* Buffer being redisplayed -- for redisplay_window_error. */
705
706 struct buffer *displayed_buffer;
707
708 /* Value returned from text property handlers (see below). */
709
710 enum prop_handled
711 {
712 HANDLED_NORMALLY,
713 HANDLED_RECOMPUTE_PROPS,
714 HANDLED_OVERLAY_STRING_CONSUMED,
715 HANDLED_RETURN
716 };
717
718 /* A description of text properties that redisplay is interested
719 in. */
720
721 struct props
722 {
723 /* The name of the property. */
724 Lisp_Object *name;
725
726 /* A unique index for the property. */
727 enum prop_idx idx;
728
729 /* A handler function called to set up iterator IT from the property
730 at IT's current position. Value is used to steer handle_stop. */
731 enum prop_handled (*handler) P_ ((struct it *it));
732 };
733
734 static enum prop_handled handle_face_prop P_ ((struct it *));
735 static enum prop_handled handle_invisible_prop P_ ((struct it *));
736 static enum prop_handled handle_display_prop P_ ((struct it *));
737 static enum prop_handled handle_composition_prop P_ ((struct it *));
738 static enum prop_handled handle_overlay_change P_ ((struct it *));
739 static enum prop_handled handle_fontified_prop P_ ((struct it *));
740
741 /* Properties handled by iterators. */
742
743 static struct props it_props[] =
744 {
745 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
746 /* Handle `face' before `display' because some sub-properties of
747 `display' need to know the face. */
748 {&Qface, FACE_PROP_IDX, handle_face_prop},
749 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
750 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
751 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
752 {NULL, 0, NULL}
753 };
754
755 /* Value is the position described by X. If X is a marker, value is
756 the marker_position of X. Otherwise, value is X. */
757
758 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
759
760 /* Enumeration returned by some move_it_.* functions internally. */
761
762 enum move_it_result
763 {
764 /* Not used. Undefined value. */
765 MOVE_UNDEFINED,
766
767 /* Move ended at the requested buffer position or ZV. */
768 MOVE_POS_MATCH_OR_ZV,
769
770 /* Move ended at the requested X pixel position. */
771 MOVE_X_REACHED,
772
773 /* Move within a line ended at the end of a line that must be
774 continued. */
775 MOVE_LINE_CONTINUED,
776
777 /* Move within a line ended at the end of a line that would
778 be displayed truncated. */
779 MOVE_LINE_TRUNCATED,
780
781 /* Move within a line ended at a line end. */
782 MOVE_NEWLINE_OR_CR
783 };
784
785 /* This counter is used to clear the face cache every once in a while
786 in redisplay_internal. It is incremented for each redisplay.
787 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
788 cleared. */
789
790 #define CLEAR_FACE_CACHE_COUNT 500
791 static int clear_face_cache_count;
792
793 /* Similarly for the image cache. */
794
795 #ifdef HAVE_WINDOW_SYSTEM
796 #define CLEAR_IMAGE_CACHE_COUNT 101
797 static int clear_image_cache_count;
798 #endif
799
800 /* Record the previous terminal frame we displayed. */
801
802 static struct frame *previous_terminal_frame;
803
804 /* Non-zero while redisplay_internal is in progress. */
805
806 int redisplaying_p;
807
808 /* Non-zero means don't free realized faces. Bound while freeing
809 realized faces is dangerous because glyph matrices might still
810 reference them. */
811
812 int inhibit_free_realized_faces;
813 Lisp_Object Qinhibit_free_realized_faces;
814
815 /* If a string, XTread_socket generates an event to display that string.
816 (The display is done in read_char.) */
817
818 Lisp_Object help_echo_string;
819 Lisp_Object help_echo_window;
820 Lisp_Object help_echo_object;
821 int help_echo_pos;
822
823 /* Temporary variable for XTread_socket. */
824
825 Lisp_Object previous_help_echo_string;
826
827 /* Null glyph slice */
828
829 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
830
831 \f
832 /* Function prototypes. */
833
834 static void setup_for_ellipsis P_ ((struct it *, int));
835 static void mark_window_display_accurate_1 P_ ((struct window *, int));
836 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
837 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
838 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
839 static int redisplay_mode_lines P_ ((Lisp_Object, int));
840 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
841
842 #if 0
843 static int invisible_text_between_p P_ ((struct it *, int, int));
844 #endif
845
846 static void pint2str P_ ((char *, int, int));
847 static void pint2hrstr P_ ((char *, int, int));
848 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
849 struct text_pos));
850 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
851 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
852 static void store_frame_title_char P_ ((char));
853 static int store_frame_title P_ ((const unsigned char *, int, int));
854 static void x_consider_frame_title P_ ((Lisp_Object));
855 static void handle_stop P_ ((struct it *));
856 static int tool_bar_lines_needed P_ ((struct frame *));
857 static int single_display_spec_intangible_p P_ ((Lisp_Object));
858 static void ensure_echo_area_buffers P_ ((void));
859 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
860 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
861 static int with_echo_area_buffer P_ ((struct window *, int,
862 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
863 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
864 static void clear_garbaged_frames P_ ((void));
865 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
866 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
867 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
868 static int display_echo_area P_ ((struct window *));
869 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
870 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
871 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
872 static int string_char_and_length P_ ((const unsigned char *, int, int *));
873 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
874 struct text_pos));
875 static int compute_window_start_on_continuation_line P_ ((struct window *));
876 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
877 static void insert_left_trunc_glyphs P_ ((struct it *));
878 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
879 Lisp_Object));
880 static void extend_face_to_end_of_line P_ ((struct it *));
881 static int append_space_for_newline P_ ((struct it *, int));
882 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
883 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
884 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
885 static int trailing_whitespace_p P_ ((int));
886 static int message_log_check_duplicate P_ ((int, int, int, int));
887 static void push_it P_ ((struct it *));
888 static void pop_it P_ ((struct it *));
889 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
890 static void select_frame_for_redisplay P_ ((Lisp_Object));
891 static void redisplay_internal P_ ((int));
892 static int echo_area_display P_ ((int));
893 static void redisplay_windows P_ ((Lisp_Object));
894 static void redisplay_window P_ ((Lisp_Object, int));
895 static Lisp_Object redisplay_window_error ();
896 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
897 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
898 static void update_menu_bar P_ ((struct frame *, int));
899 static int try_window_reusing_current_matrix P_ ((struct window *));
900 static int try_window_id P_ ((struct window *));
901 static int display_line P_ ((struct it *));
902 static int display_mode_lines P_ ((struct window *));
903 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
904 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
905 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
906 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
907 static void display_menu_bar P_ ((struct window *));
908 static int display_count_lines P_ ((int, int, int, int, int *));
909 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
910 int, int, struct it *, int, int, int, int));
911 static void compute_line_metrics P_ ((struct it *));
912 static void run_redisplay_end_trigger_hook P_ ((struct it *));
913 static int get_overlay_strings P_ ((struct it *, int));
914 static void next_overlay_string P_ ((struct it *));
915 static void reseat P_ ((struct it *, struct text_pos, int));
916 static void reseat_1 P_ ((struct it *, struct text_pos, int));
917 static void back_to_previous_visible_line_start P_ ((struct it *));
918 void reseat_at_previous_visible_line_start P_ ((struct it *));
919 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
920 static int next_element_from_ellipsis P_ ((struct it *));
921 static int next_element_from_display_vector P_ ((struct it *));
922 static int next_element_from_string P_ ((struct it *));
923 static int next_element_from_c_string P_ ((struct it *));
924 static int next_element_from_buffer P_ ((struct it *));
925 static int next_element_from_composition P_ ((struct it *));
926 static int next_element_from_image P_ ((struct it *));
927 static int next_element_from_stretch P_ ((struct it *));
928 static void load_overlay_strings P_ ((struct it *, int));
929 static int init_from_display_pos P_ ((struct it *, struct window *,
930 struct display_pos *));
931 static void reseat_to_string P_ ((struct it *, unsigned char *,
932 Lisp_Object, int, int, int, int));
933 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
934 int, int, int));
935 void move_it_vertically_backward P_ ((struct it *, int));
936 static void init_to_row_start P_ ((struct it *, struct window *,
937 struct glyph_row *));
938 static int init_to_row_end P_ ((struct it *, struct window *,
939 struct glyph_row *));
940 static void back_to_previous_line_start P_ ((struct it *));
941 static int forward_to_next_line_start P_ ((struct it *, int *));
942 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
943 Lisp_Object, int));
944 static struct text_pos string_pos P_ ((int, Lisp_Object));
945 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
946 static int number_of_chars P_ ((unsigned char *, int));
947 static void compute_stop_pos P_ ((struct it *));
948 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
949 Lisp_Object));
950 static int face_before_or_after_it_pos P_ ((struct it *, int));
951 static int next_overlay_change P_ ((int));
952 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
953 Lisp_Object, struct text_pos *,
954 int));
955 static int underlying_face_id P_ ((struct it *));
956 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
957 struct window *));
958
959 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
960 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
961
962 #ifdef HAVE_WINDOW_SYSTEM
963
964 static void update_tool_bar P_ ((struct frame *, int));
965 static void build_desired_tool_bar_string P_ ((struct frame *f));
966 static int redisplay_tool_bar P_ ((struct frame *));
967 static void display_tool_bar_line P_ ((struct it *));
968 static void notice_overwritten_cursor P_ ((struct window *,
969 enum glyph_row_area,
970 int, int, int, int));
971
972
973
974 #endif /* HAVE_WINDOW_SYSTEM */
975
976 \f
977 /***********************************************************************
978 Window display dimensions
979 ***********************************************************************/
980
981 /* Return the bottom boundary y-position for text lines in window W.
982 This is the first y position at which a line cannot start.
983 It is relative to the top of the window.
984
985 This is the height of W minus the height of a mode line, if any. */
986
987 INLINE int
988 window_text_bottom_y (w)
989 struct window *w;
990 {
991 int height = WINDOW_TOTAL_HEIGHT (w);
992
993 if (WINDOW_WANTS_MODELINE_P (w))
994 height -= CURRENT_MODE_LINE_HEIGHT (w);
995 return height;
996 }
997
998 /* Return the pixel width of display area AREA of window W. AREA < 0
999 means return the total width of W, not including fringes to
1000 the left and right of the window. */
1001
1002 INLINE int
1003 window_box_width (w, area)
1004 struct window *w;
1005 int area;
1006 {
1007 int cols = XFASTINT (w->total_cols);
1008 int pixels = 0;
1009
1010 if (!w->pseudo_window_p)
1011 {
1012 cols -= WINDOW_SCROLL_BAR_COLS (w);
1013
1014 if (area == TEXT_AREA)
1015 {
1016 if (INTEGERP (w->left_margin_cols))
1017 cols -= XFASTINT (w->left_margin_cols);
1018 if (INTEGERP (w->right_margin_cols))
1019 cols -= XFASTINT (w->right_margin_cols);
1020 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1021 }
1022 else if (area == LEFT_MARGIN_AREA)
1023 {
1024 cols = (INTEGERP (w->left_margin_cols)
1025 ? XFASTINT (w->left_margin_cols) : 0);
1026 pixels = 0;
1027 }
1028 else if (area == RIGHT_MARGIN_AREA)
1029 {
1030 cols = (INTEGERP (w->right_margin_cols)
1031 ? XFASTINT (w->right_margin_cols) : 0);
1032 pixels = 0;
1033 }
1034 }
1035
1036 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1037 }
1038
1039
1040 /* Return the pixel height of the display area of window W, not
1041 including mode lines of W, if any. */
1042
1043 INLINE int
1044 window_box_height (w)
1045 struct window *w;
1046 {
1047 struct frame *f = XFRAME (w->frame);
1048 int height = WINDOW_TOTAL_HEIGHT (w);
1049
1050 xassert (height >= 0);
1051
1052 /* Note: the code below that determines the mode-line/header-line
1053 height is essentially the same as that contained in the macro
1054 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1055 the appropriate glyph row has its `mode_line_p' flag set,
1056 and if it doesn't, uses estimate_mode_line_height instead. */
1057
1058 if (WINDOW_WANTS_MODELINE_P (w))
1059 {
1060 struct glyph_row *ml_row
1061 = (w->current_matrix && w->current_matrix->rows
1062 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1063 : 0);
1064 if (ml_row && ml_row->mode_line_p)
1065 height -= ml_row->height;
1066 else
1067 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1068 }
1069
1070 if (WINDOW_WANTS_HEADER_LINE_P (w))
1071 {
1072 struct glyph_row *hl_row
1073 = (w->current_matrix && w->current_matrix->rows
1074 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1075 : 0);
1076 if (hl_row && hl_row->mode_line_p)
1077 height -= hl_row->height;
1078 else
1079 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1080 }
1081
1082 /* With a very small font and a mode-line that's taller than
1083 default, we might end up with a negative height. */
1084 return max (0, height);
1085 }
1086
1087 /* Return the window-relative coordinate of the left edge of display
1088 area AREA of window W. AREA < 0 means return the left edge of the
1089 whole window, to the right of the left fringe of W. */
1090
1091 INLINE int
1092 window_box_left_offset (w, area)
1093 struct window *w;
1094 int area;
1095 {
1096 int x;
1097
1098 if (w->pseudo_window_p)
1099 return 0;
1100
1101 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1102
1103 if (area == TEXT_AREA)
1104 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1105 + window_box_width (w, LEFT_MARGIN_AREA));
1106 else if (area == RIGHT_MARGIN_AREA)
1107 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1108 + window_box_width (w, LEFT_MARGIN_AREA)
1109 + window_box_width (w, TEXT_AREA)
1110 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1111 ? 0
1112 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1113 else if (area == LEFT_MARGIN_AREA
1114 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1115 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1116
1117 return x;
1118 }
1119
1120
1121 /* Return the window-relative coordinate of the right edge of display
1122 area AREA of window W. AREA < 0 means return the left edge of the
1123 whole window, to the left of the right fringe of W. */
1124
1125 INLINE int
1126 window_box_right_offset (w, area)
1127 struct window *w;
1128 int area;
1129 {
1130 return window_box_left_offset (w, area) + window_box_width (w, area);
1131 }
1132
1133 /* Return the frame-relative coordinate of the left edge of display
1134 area AREA of window W. AREA < 0 means return the left edge of the
1135 whole window, to the right of the left fringe of W. */
1136
1137 INLINE int
1138 window_box_left (w, area)
1139 struct window *w;
1140 int area;
1141 {
1142 struct frame *f = XFRAME (w->frame);
1143 int x;
1144
1145 if (w->pseudo_window_p)
1146 return FRAME_INTERNAL_BORDER_WIDTH (f);
1147
1148 x = (WINDOW_LEFT_EDGE_X (w)
1149 + window_box_left_offset (w, area));
1150
1151 return x;
1152 }
1153
1154
1155 /* Return the frame-relative coordinate of the right edge of display
1156 area AREA of window W. AREA < 0 means return the left edge of the
1157 whole window, to the left of the right fringe of W. */
1158
1159 INLINE int
1160 window_box_right (w, area)
1161 struct window *w;
1162 int area;
1163 {
1164 return window_box_left (w, area) + window_box_width (w, area);
1165 }
1166
1167 /* Get the bounding box of the display area AREA of window W, without
1168 mode lines, in frame-relative coordinates. AREA < 0 means the
1169 whole window, not including the left and right fringes of
1170 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1171 coordinates of the upper-left corner of the box. Return in
1172 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1173
1174 INLINE void
1175 window_box (w, area, box_x, box_y, box_width, box_height)
1176 struct window *w;
1177 int area;
1178 int *box_x, *box_y, *box_width, *box_height;
1179 {
1180 if (box_width)
1181 *box_width = window_box_width (w, area);
1182 if (box_height)
1183 *box_height = window_box_height (w);
1184 if (box_x)
1185 *box_x = window_box_left (w, area);
1186 if (box_y)
1187 {
1188 *box_y = WINDOW_TOP_EDGE_Y (w);
1189 if (WINDOW_WANTS_HEADER_LINE_P (w))
1190 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1191 }
1192 }
1193
1194
1195 /* Get the bounding box of the display area AREA of window W, without
1196 mode lines. AREA < 0 means the whole window, not including the
1197 left and right fringe of the window. Return in *TOP_LEFT_X
1198 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1199 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1200 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1201 box. */
1202
1203 INLINE void
1204 window_box_edges (w, area, top_left_x, top_left_y,
1205 bottom_right_x, bottom_right_y)
1206 struct window *w;
1207 int area;
1208 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1209 {
1210 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1211 bottom_right_y);
1212 *bottom_right_x += *top_left_x;
1213 *bottom_right_y += *top_left_y;
1214 }
1215
1216
1217 \f
1218 /***********************************************************************
1219 Utilities
1220 ***********************************************************************/
1221
1222 /* Return the bottom y-position of the line the iterator IT is in.
1223 This can modify IT's settings. */
1224
1225 int
1226 line_bottom_y (it)
1227 struct it *it;
1228 {
1229 int line_height = it->max_ascent + it->max_descent;
1230 int line_top_y = it->current_y;
1231
1232 if (line_height == 0)
1233 {
1234 if (last_height)
1235 line_height = last_height;
1236 else if (IT_CHARPOS (*it) < ZV)
1237 {
1238 move_it_by_lines (it, 1, 1);
1239 line_height = (it->max_ascent || it->max_descent
1240 ? it->max_ascent + it->max_descent
1241 : last_height);
1242 }
1243 else
1244 {
1245 struct glyph_row *row = it->glyph_row;
1246
1247 /* Use the default character height. */
1248 it->glyph_row = NULL;
1249 it->what = IT_CHARACTER;
1250 it->c = ' ';
1251 it->len = 1;
1252 PRODUCE_GLYPHS (it);
1253 line_height = it->ascent + it->descent;
1254 it->glyph_row = row;
1255 }
1256 }
1257
1258 return line_top_y + line_height;
1259 }
1260
1261
1262 /* Return 1 if position CHARPOS is visible in window W.
1263 If visible, set *X and *Y to pixel coordinates of top left corner.
1264 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1265 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1266 and header-lines heights. */
1267
1268 int
1269 pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1270 struct window *w;
1271 int charpos, *x, *y, *rtop, *rbot, exact_mode_line_heights_p;
1272 {
1273 struct it it;
1274 struct text_pos top;
1275 int visible_p = 0;
1276 struct buffer *old_buffer = NULL;
1277
1278 if (noninteractive)
1279 return visible_p;
1280
1281 if (XBUFFER (w->buffer) != current_buffer)
1282 {
1283 old_buffer = current_buffer;
1284 set_buffer_internal_1 (XBUFFER (w->buffer));
1285 }
1286
1287 SET_TEXT_POS_FROM_MARKER (top, w->start);
1288
1289 /* Compute exact mode line heights, if requested. */
1290 if (exact_mode_line_heights_p)
1291 {
1292 if (WINDOW_WANTS_MODELINE_P (w))
1293 current_mode_line_height
1294 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1295 current_buffer->mode_line_format);
1296
1297 if (WINDOW_WANTS_HEADER_LINE_P (w))
1298 current_header_line_height
1299 = display_mode_line (w, HEADER_LINE_FACE_ID,
1300 current_buffer->header_line_format);
1301 }
1302
1303 start_display (&it, w, top);
1304 move_it_to (&it, charpos, -1, it.last_visible_y, -1,
1305 MOVE_TO_POS | MOVE_TO_Y);
1306
1307 /* Note that we may overshoot because of invisible text. */
1308 if (IT_CHARPOS (it) >= charpos)
1309 {
1310 int top_x = it.current_x;
1311 int top_y = it.current_y;
1312 int bottom_y = (last_height = 0, line_bottom_y (&it));
1313 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1314
1315 if (top_y < window_top_y)
1316 visible_p = bottom_y > window_top_y;
1317 else if (top_y < it.last_visible_y)
1318 visible_p = 1;
1319 if (visible_p)
1320 {
1321 *x = top_x;
1322 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1323 *rtop = max (0, window_top_y - top_y);
1324 *rbot = max (0, bottom_y - it.last_visible_y);
1325 }
1326 }
1327 else
1328 {
1329 struct it it2;
1330
1331 it2 = it;
1332 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1333 move_it_by_lines (&it, 1, 0);
1334 if (charpos < IT_CHARPOS (it))
1335 {
1336 visible_p = 1;
1337 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1338 *x = it2.current_x;
1339 *y = it2.current_y + it2.max_ascent - it2.ascent;
1340 *rtop = max (0, -it2.current_y);
1341 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1342 - it.last_visible_y));
1343 }
1344 }
1345
1346 if (old_buffer)
1347 set_buffer_internal_1 (old_buffer);
1348
1349 current_header_line_height = current_mode_line_height = -1;
1350
1351 return visible_p;
1352 }
1353
1354
1355 /* Return the next character from STR which is MAXLEN bytes long.
1356 Return in *LEN the length of the character. This is like
1357 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1358 we find one, we return a `?', but with the length of the invalid
1359 character. */
1360
1361 static INLINE int
1362 string_char_and_length (str, maxlen, len)
1363 const unsigned char *str;
1364 int maxlen, *len;
1365 {
1366 int c;
1367
1368 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1369 if (!CHAR_VALID_P (c, 1))
1370 /* We may not change the length here because other places in Emacs
1371 don't use this function, i.e. they silently accept invalid
1372 characters. */
1373 c = '?';
1374
1375 return c;
1376 }
1377
1378
1379
1380 /* Given a position POS containing a valid character and byte position
1381 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1382
1383 static struct text_pos
1384 string_pos_nchars_ahead (pos, string, nchars)
1385 struct text_pos pos;
1386 Lisp_Object string;
1387 int nchars;
1388 {
1389 xassert (STRINGP (string) && nchars >= 0);
1390
1391 if (STRING_MULTIBYTE (string))
1392 {
1393 int rest = SBYTES (string) - BYTEPOS (pos);
1394 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1395 int len;
1396
1397 while (nchars--)
1398 {
1399 string_char_and_length (p, rest, &len);
1400 p += len, rest -= len;
1401 xassert (rest >= 0);
1402 CHARPOS (pos) += 1;
1403 BYTEPOS (pos) += len;
1404 }
1405 }
1406 else
1407 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1408
1409 return pos;
1410 }
1411
1412
1413 /* Value is the text position, i.e. character and byte position,
1414 for character position CHARPOS in STRING. */
1415
1416 static INLINE struct text_pos
1417 string_pos (charpos, string)
1418 int charpos;
1419 Lisp_Object string;
1420 {
1421 struct text_pos pos;
1422 xassert (STRINGP (string));
1423 xassert (charpos >= 0);
1424 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1425 return pos;
1426 }
1427
1428
1429 /* Value is a text position, i.e. character and byte position, for
1430 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1431 means recognize multibyte characters. */
1432
1433 static struct text_pos
1434 c_string_pos (charpos, s, multibyte_p)
1435 int charpos;
1436 unsigned char *s;
1437 int multibyte_p;
1438 {
1439 struct text_pos pos;
1440
1441 xassert (s != NULL);
1442 xassert (charpos >= 0);
1443
1444 if (multibyte_p)
1445 {
1446 int rest = strlen (s), len;
1447
1448 SET_TEXT_POS (pos, 0, 0);
1449 while (charpos--)
1450 {
1451 string_char_and_length (s, rest, &len);
1452 s += len, rest -= len;
1453 xassert (rest >= 0);
1454 CHARPOS (pos) += 1;
1455 BYTEPOS (pos) += len;
1456 }
1457 }
1458 else
1459 SET_TEXT_POS (pos, charpos, charpos);
1460
1461 return pos;
1462 }
1463
1464
1465 /* Value is the number of characters in C string S. MULTIBYTE_P
1466 non-zero means recognize multibyte characters. */
1467
1468 static int
1469 number_of_chars (s, multibyte_p)
1470 unsigned char *s;
1471 int multibyte_p;
1472 {
1473 int nchars;
1474
1475 if (multibyte_p)
1476 {
1477 int rest = strlen (s), len;
1478 unsigned char *p = (unsigned char *) s;
1479
1480 for (nchars = 0; rest > 0; ++nchars)
1481 {
1482 string_char_and_length (p, rest, &len);
1483 rest -= len, p += len;
1484 }
1485 }
1486 else
1487 nchars = strlen (s);
1488
1489 return nchars;
1490 }
1491
1492
1493 /* Compute byte position NEWPOS->bytepos corresponding to
1494 NEWPOS->charpos. POS is a known position in string STRING.
1495 NEWPOS->charpos must be >= POS.charpos. */
1496
1497 static void
1498 compute_string_pos (newpos, pos, string)
1499 struct text_pos *newpos, pos;
1500 Lisp_Object string;
1501 {
1502 xassert (STRINGP (string));
1503 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1504
1505 if (STRING_MULTIBYTE (string))
1506 *newpos = string_pos_nchars_ahead (pos, string,
1507 CHARPOS (*newpos) - CHARPOS (pos));
1508 else
1509 BYTEPOS (*newpos) = CHARPOS (*newpos);
1510 }
1511
1512 /* EXPORT:
1513 Return an estimation of the pixel height of mode or top lines on
1514 frame F. FACE_ID specifies what line's height to estimate. */
1515
1516 int
1517 estimate_mode_line_height (f, face_id)
1518 struct frame *f;
1519 enum face_id face_id;
1520 {
1521 #ifdef HAVE_WINDOW_SYSTEM
1522 if (FRAME_WINDOW_P (f))
1523 {
1524 int height = FONT_HEIGHT (FRAME_FONT (f));
1525
1526 /* This function is called so early when Emacs starts that the face
1527 cache and mode line face are not yet initialized. */
1528 if (FRAME_FACE_CACHE (f))
1529 {
1530 struct face *face = FACE_FROM_ID (f, face_id);
1531 if (face)
1532 {
1533 if (face->font)
1534 height = FONT_HEIGHT (face->font);
1535 if (face->box_line_width > 0)
1536 height += 2 * face->box_line_width;
1537 }
1538 }
1539
1540 return height;
1541 }
1542 #endif
1543
1544 return 1;
1545 }
1546
1547 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1548 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1549 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1550 not force the value into range. */
1551
1552 void
1553 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1554 FRAME_PTR f;
1555 register int pix_x, pix_y;
1556 int *x, *y;
1557 NativeRectangle *bounds;
1558 int noclip;
1559 {
1560
1561 #ifdef HAVE_WINDOW_SYSTEM
1562 if (FRAME_WINDOW_P (f))
1563 {
1564 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1565 even for negative values. */
1566 if (pix_x < 0)
1567 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1568 if (pix_y < 0)
1569 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1570
1571 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1572 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1573
1574 if (bounds)
1575 STORE_NATIVE_RECT (*bounds,
1576 FRAME_COL_TO_PIXEL_X (f, pix_x),
1577 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1578 FRAME_COLUMN_WIDTH (f) - 1,
1579 FRAME_LINE_HEIGHT (f) - 1);
1580
1581 if (!noclip)
1582 {
1583 if (pix_x < 0)
1584 pix_x = 0;
1585 else if (pix_x > FRAME_TOTAL_COLS (f))
1586 pix_x = FRAME_TOTAL_COLS (f);
1587
1588 if (pix_y < 0)
1589 pix_y = 0;
1590 else if (pix_y > FRAME_LINES (f))
1591 pix_y = FRAME_LINES (f);
1592 }
1593 }
1594 #endif
1595
1596 *x = pix_x;
1597 *y = pix_y;
1598 }
1599
1600
1601 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1602 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1603 can't tell the positions because W's display is not up to date,
1604 return 0. */
1605
1606 int
1607 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1608 struct window *w;
1609 int hpos, vpos;
1610 int *frame_x, *frame_y;
1611 {
1612 #ifdef HAVE_WINDOW_SYSTEM
1613 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1614 {
1615 int success_p;
1616
1617 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1618 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1619
1620 if (display_completed)
1621 {
1622 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1623 struct glyph *glyph = row->glyphs[TEXT_AREA];
1624 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1625
1626 hpos = row->x;
1627 vpos = row->y;
1628 while (glyph < end)
1629 {
1630 hpos += glyph->pixel_width;
1631 ++glyph;
1632 }
1633
1634 /* If first glyph is partially visible, its first visible position is still 0. */
1635 if (hpos < 0)
1636 hpos = 0;
1637
1638 success_p = 1;
1639 }
1640 else
1641 {
1642 hpos = vpos = 0;
1643 success_p = 0;
1644 }
1645
1646 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1647 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1648 return success_p;
1649 }
1650 #endif
1651
1652 *frame_x = hpos;
1653 *frame_y = vpos;
1654 return 1;
1655 }
1656
1657
1658 #ifdef HAVE_WINDOW_SYSTEM
1659
1660 /* Find the glyph under window-relative coordinates X/Y in window W.
1661 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1662 strings. Return in *HPOS and *VPOS the row and column number of
1663 the glyph found. Return in *AREA the glyph area containing X.
1664 Value is a pointer to the glyph found or null if X/Y is not on
1665 text, or we can't tell because W's current matrix is not up to
1666 date. */
1667
1668 static struct glyph *
1669 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1670 struct window *w;
1671 int x, y;
1672 int *hpos, *vpos, *dx, *dy, *area;
1673 {
1674 struct glyph *glyph, *end;
1675 struct glyph_row *row = NULL;
1676 int x0, i;
1677
1678 /* Find row containing Y. Give up if some row is not enabled. */
1679 for (i = 0; i < w->current_matrix->nrows; ++i)
1680 {
1681 row = MATRIX_ROW (w->current_matrix, i);
1682 if (!row->enabled_p)
1683 return NULL;
1684 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1685 break;
1686 }
1687
1688 *vpos = i;
1689 *hpos = 0;
1690
1691 /* Give up if Y is not in the window. */
1692 if (i == w->current_matrix->nrows)
1693 return NULL;
1694
1695 /* Get the glyph area containing X. */
1696 if (w->pseudo_window_p)
1697 {
1698 *area = TEXT_AREA;
1699 x0 = 0;
1700 }
1701 else
1702 {
1703 if (x < window_box_left_offset (w, TEXT_AREA))
1704 {
1705 *area = LEFT_MARGIN_AREA;
1706 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1707 }
1708 else if (x < window_box_right_offset (w, TEXT_AREA))
1709 {
1710 *area = TEXT_AREA;
1711 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1712 }
1713 else
1714 {
1715 *area = RIGHT_MARGIN_AREA;
1716 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1717 }
1718 }
1719
1720 /* Find glyph containing X. */
1721 glyph = row->glyphs[*area];
1722 end = glyph + row->used[*area];
1723 x -= x0;
1724 while (glyph < end && x >= glyph->pixel_width)
1725 {
1726 x -= glyph->pixel_width;
1727 ++glyph;
1728 }
1729
1730 if (glyph == end)
1731 return NULL;
1732
1733 if (dx)
1734 {
1735 *dx = x;
1736 *dy = y - (row->y + row->ascent - glyph->ascent);
1737 }
1738
1739 *hpos = glyph - row->glyphs[*area];
1740 return glyph;
1741 }
1742
1743
1744 /* EXPORT:
1745 Convert frame-relative x/y to coordinates relative to window W.
1746 Takes pseudo-windows into account. */
1747
1748 void
1749 frame_to_window_pixel_xy (w, x, y)
1750 struct window *w;
1751 int *x, *y;
1752 {
1753 if (w->pseudo_window_p)
1754 {
1755 /* A pseudo-window is always full-width, and starts at the
1756 left edge of the frame, plus a frame border. */
1757 struct frame *f = XFRAME (w->frame);
1758 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1759 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1760 }
1761 else
1762 {
1763 *x -= WINDOW_LEFT_EDGE_X (w);
1764 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1765 }
1766 }
1767
1768 /* EXPORT:
1769 Return in *R the clipping rectangle for glyph string S. */
1770
1771 void
1772 get_glyph_string_clip_rect (s, nr)
1773 struct glyph_string *s;
1774 NativeRectangle *nr;
1775 {
1776 XRectangle r;
1777
1778 if (s->row->full_width_p)
1779 {
1780 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1781 r.x = WINDOW_LEFT_EDGE_X (s->w);
1782 r.width = WINDOW_TOTAL_WIDTH (s->w);
1783
1784 /* Unless displaying a mode or menu bar line, which are always
1785 fully visible, clip to the visible part of the row. */
1786 if (s->w->pseudo_window_p)
1787 r.height = s->row->visible_height;
1788 else
1789 r.height = s->height;
1790 }
1791 else
1792 {
1793 /* This is a text line that may be partially visible. */
1794 r.x = window_box_left (s->w, s->area);
1795 r.width = window_box_width (s->w, s->area);
1796 r.height = s->row->visible_height;
1797 }
1798
1799 if (s->clip_head)
1800 if (r.x < s->clip_head->x)
1801 {
1802 if (r.width >= s->clip_head->x - r.x)
1803 r.width -= s->clip_head->x - r.x;
1804 else
1805 r.width = 0;
1806 r.x = s->clip_head->x;
1807 }
1808 if (s->clip_tail)
1809 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1810 {
1811 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1812 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1813 else
1814 r.width = 0;
1815 }
1816
1817 /* If S draws overlapping rows, it's sufficient to use the top and
1818 bottom of the window for clipping because this glyph string
1819 intentionally draws over other lines. */
1820 if (s->for_overlaps_p)
1821 {
1822 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1823 r.height = window_text_bottom_y (s->w) - r.y;
1824 }
1825 else
1826 {
1827 /* Don't use S->y for clipping because it doesn't take partially
1828 visible lines into account. For example, it can be negative for
1829 partially visible lines at the top of a window. */
1830 if (!s->row->full_width_p
1831 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1832 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1833 else
1834 r.y = max (0, s->row->y);
1835
1836 /* If drawing a tool-bar window, draw it over the internal border
1837 at the top of the window. */
1838 if (WINDOWP (s->f->tool_bar_window)
1839 && s->w == XWINDOW (s->f->tool_bar_window))
1840 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1841 }
1842
1843 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1844
1845 /* If drawing the cursor, don't let glyph draw outside its
1846 advertised boundaries. Cleartype does this under some circumstances. */
1847 if (s->hl == DRAW_CURSOR)
1848 {
1849 struct glyph *glyph = s->first_glyph;
1850 int height, max_y;
1851
1852 if (s->x > r.x)
1853 {
1854 r.width -= s->x - r.x;
1855 r.x = s->x;
1856 }
1857 r.width = min (r.width, glyph->pixel_width);
1858
1859 /* If r.y is below window bottom, ensure that we still see a cursor. */
1860 height = min (glyph->ascent + glyph->descent,
1861 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1862 max_y = window_text_bottom_y (s->w) - height;
1863 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1864 if (s->ybase - glyph->ascent > max_y)
1865 {
1866 r.y = max_y;
1867 r.height = height;
1868 }
1869 else
1870 {
1871 /* Don't draw cursor glyph taller than our actual glyph. */
1872 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1873 if (height < r.height)
1874 {
1875 max_y = r.y + r.height;
1876 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1877 r.height = min (max_y - r.y, height);
1878 }
1879 }
1880 }
1881
1882 #ifdef CONVERT_FROM_XRECT
1883 CONVERT_FROM_XRECT (r, *nr);
1884 #else
1885 *nr = r;
1886 #endif
1887 }
1888
1889
1890 /* EXPORT:
1891 Return the position and height of the phys cursor in window W.
1892 Set w->phys_cursor_width to width of phys cursor.
1893 */
1894
1895 int
1896 get_phys_cursor_geometry (w, row, glyph, heightp)
1897 struct window *w;
1898 struct glyph_row *row;
1899 struct glyph *glyph;
1900 int *heightp;
1901 {
1902 struct frame *f = XFRAME (WINDOW_FRAME (w));
1903 int x, y, wd, h, h0, y0;
1904
1905 /* Compute the width of the rectangle to draw. If on a stretch
1906 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1907 rectangle as wide as the glyph, but use a canonical character
1908 width instead. */
1909 wd = glyph->pixel_width - 1;
1910 #ifdef HAVE_NTGUI
1911 wd++; /* Why? */
1912 #endif
1913 if (glyph->type == STRETCH_GLYPH
1914 && !x_stretch_cursor_p)
1915 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1916 w->phys_cursor_width = wd;
1917
1918 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1919
1920 /* If y is below window bottom, ensure that we still see a cursor. */
1921 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1922
1923 h = max (h0, glyph->ascent + glyph->descent);
1924 h0 = min (h0, glyph->ascent + glyph->descent);
1925
1926 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1927 if (y < y0)
1928 {
1929 h = max (h - (y0 - y) + 1, h0);
1930 y = y0 - 1;
1931 }
1932 else
1933 {
1934 y0 = window_text_bottom_y (w) - h0;
1935 if (y > y0)
1936 {
1937 h += y - y0;
1938 y = y0;
1939 }
1940 }
1941
1942 *heightp = h - 1;
1943 return WINDOW_TO_FRAME_PIXEL_Y (w, y);
1944 }
1945
1946
1947 #endif /* HAVE_WINDOW_SYSTEM */
1948
1949 \f
1950 /***********************************************************************
1951 Lisp form evaluation
1952 ***********************************************************************/
1953
1954 /* Error handler for safe_eval and safe_call. */
1955
1956 static Lisp_Object
1957 safe_eval_handler (arg)
1958 Lisp_Object arg;
1959 {
1960 add_to_log ("Error during redisplay: %s", arg, Qnil);
1961 return Qnil;
1962 }
1963
1964
1965 /* Evaluate SEXPR and return the result, or nil if something went
1966 wrong. Prevent redisplay during the evaluation. */
1967
1968 Lisp_Object
1969 safe_eval (sexpr)
1970 Lisp_Object sexpr;
1971 {
1972 Lisp_Object val;
1973
1974 if (inhibit_eval_during_redisplay)
1975 val = Qnil;
1976 else
1977 {
1978 int count = SPECPDL_INDEX ();
1979 struct gcpro gcpro1;
1980
1981 GCPRO1 (sexpr);
1982 specbind (Qinhibit_redisplay, Qt);
1983 /* Use Qt to ensure debugger does not run,
1984 so there is no possibility of wanting to redisplay. */
1985 val = internal_condition_case_1 (Feval, sexpr, Qt,
1986 safe_eval_handler);
1987 UNGCPRO;
1988 val = unbind_to (count, val);
1989 }
1990
1991 return val;
1992 }
1993
1994
1995 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1996 Return the result, or nil if something went wrong. Prevent
1997 redisplay during the evaluation. */
1998
1999 Lisp_Object
2000 safe_call (nargs, args)
2001 int nargs;
2002 Lisp_Object *args;
2003 {
2004 Lisp_Object val;
2005
2006 if (inhibit_eval_during_redisplay)
2007 val = Qnil;
2008 else
2009 {
2010 int count = SPECPDL_INDEX ();
2011 struct gcpro gcpro1;
2012
2013 GCPRO1 (args[0]);
2014 gcpro1.nvars = nargs;
2015 specbind (Qinhibit_redisplay, Qt);
2016 /* Use Qt to ensure debugger does not run,
2017 so there is no possibility of wanting to redisplay. */
2018 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2019 safe_eval_handler);
2020 UNGCPRO;
2021 val = unbind_to (count, val);
2022 }
2023
2024 return val;
2025 }
2026
2027
2028 /* Call function FN with one argument ARG.
2029 Return the result, or nil if something went wrong. */
2030
2031 Lisp_Object
2032 safe_call1 (fn, arg)
2033 Lisp_Object fn, arg;
2034 {
2035 Lisp_Object args[2];
2036 args[0] = fn;
2037 args[1] = arg;
2038 return safe_call (2, args);
2039 }
2040
2041
2042 \f
2043 /***********************************************************************
2044 Debugging
2045 ***********************************************************************/
2046
2047 #if 0
2048
2049 /* Define CHECK_IT to perform sanity checks on iterators.
2050 This is for debugging. It is too slow to do unconditionally. */
2051
2052 static void
2053 check_it (it)
2054 struct it *it;
2055 {
2056 if (it->method == GET_FROM_STRING)
2057 {
2058 xassert (STRINGP (it->string));
2059 xassert (IT_STRING_CHARPOS (*it) >= 0);
2060 }
2061 else
2062 {
2063 xassert (IT_STRING_CHARPOS (*it) < 0);
2064 if (it->method == GET_FROM_BUFFER)
2065 {
2066 /* Check that character and byte positions agree. */
2067 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2068 }
2069 }
2070
2071 if (it->dpvec)
2072 xassert (it->current.dpvec_index >= 0);
2073 else
2074 xassert (it->current.dpvec_index < 0);
2075 }
2076
2077 #define CHECK_IT(IT) check_it ((IT))
2078
2079 #else /* not 0 */
2080
2081 #define CHECK_IT(IT) (void) 0
2082
2083 #endif /* not 0 */
2084
2085
2086 #if GLYPH_DEBUG
2087
2088 /* Check that the window end of window W is what we expect it
2089 to be---the last row in the current matrix displaying text. */
2090
2091 static void
2092 check_window_end (w)
2093 struct window *w;
2094 {
2095 if (!MINI_WINDOW_P (w)
2096 && !NILP (w->window_end_valid))
2097 {
2098 struct glyph_row *row;
2099 xassert ((row = MATRIX_ROW (w->current_matrix,
2100 XFASTINT (w->window_end_vpos)),
2101 !row->enabled_p
2102 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2103 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2104 }
2105 }
2106
2107 #define CHECK_WINDOW_END(W) check_window_end ((W))
2108
2109 #else /* not GLYPH_DEBUG */
2110
2111 #define CHECK_WINDOW_END(W) (void) 0
2112
2113 #endif /* not GLYPH_DEBUG */
2114
2115
2116 \f
2117 /***********************************************************************
2118 Iterator initialization
2119 ***********************************************************************/
2120
2121 /* Initialize IT for displaying current_buffer in window W, starting
2122 at character position CHARPOS. CHARPOS < 0 means that no buffer
2123 position is specified which is useful when the iterator is assigned
2124 a position later. BYTEPOS is the byte position corresponding to
2125 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2126
2127 If ROW is not null, calls to produce_glyphs with IT as parameter
2128 will produce glyphs in that row.
2129
2130 BASE_FACE_ID is the id of a base face to use. It must be one of
2131 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2132 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2133 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2134
2135 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2136 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2137 will be initialized to use the corresponding mode line glyph row of
2138 the desired matrix of W. */
2139
2140 void
2141 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2142 struct it *it;
2143 struct window *w;
2144 int charpos, bytepos;
2145 struct glyph_row *row;
2146 enum face_id base_face_id;
2147 {
2148 int highlight_region_p;
2149
2150 /* Some precondition checks. */
2151 xassert (w != NULL && it != NULL);
2152 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2153 && charpos <= ZV));
2154
2155 /* If face attributes have been changed since the last redisplay,
2156 free realized faces now because they depend on face definitions
2157 that might have changed. Don't free faces while there might be
2158 desired matrices pending which reference these faces. */
2159 if (face_change_count && !inhibit_free_realized_faces)
2160 {
2161 face_change_count = 0;
2162 free_all_realized_faces (Qnil);
2163 }
2164
2165 /* Use one of the mode line rows of W's desired matrix if
2166 appropriate. */
2167 if (row == NULL)
2168 {
2169 if (base_face_id == MODE_LINE_FACE_ID
2170 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2171 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2172 else if (base_face_id == HEADER_LINE_FACE_ID)
2173 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2174 }
2175
2176 /* Clear IT. */
2177 bzero (it, sizeof *it);
2178 it->current.overlay_string_index = -1;
2179 it->current.dpvec_index = -1;
2180 it->base_face_id = base_face_id;
2181 it->string = Qnil;
2182 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2183
2184 /* The window in which we iterate over current_buffer: */
2185 XSETWINDOW (it->window, w);
2186 it->w = w;
2187 it->f = XFRAME (w->frame);
2188
2189 /* Extra space between lines (on window systems only). */
2190 if (base_face_id == DEFAULT_FACE_ID
2191 && FRAME_WINDOW_P (it->f))
2192 {
2193 if (NATNUMP (current_buffer->extra_line_spacing))
2194 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2195 else if (FLOATP (current_buffer->extra_line_spacing))
2196 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2197 * FRAME_LINE_HEIGHT (it->f));
2198 else if (it->f->extra_line_spacing > 0)
2199 it->extra_line_spacing = it->f->extra_line_spacing;
2200 it->max_extra_line_spacing = 0;
2201 }
2202
2203 /* If realized faces have been removed, e.g. because of face
2204 attribute changes of named faces, recompute them. When running
2205 in batch mode, the face cache of Vterminal_frame is null. If
2206 we happen to get called, make a dummy face cache. */
2207 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2208 init_frame_faces (it->f);
2209 if (FRAME_FACE_CACHE (it->f)->used == 0)
2210 recompute_basic_faces (it->f);
2211
2212 /* Current value of the `slice', `space-width', and 'height' properties. */
2213 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2214 it->space_width = Qnil;
2215 it->font_height = Qnil;
2216 it->override_ascent = -1;
2217
2218 /* Are control characters displayed as `^C'? */
2219 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2220
2221 /* -1 means everything between a CR and the following line end
2222 is invisible. >0 means lines indented more than this value are
2223 invisible. */
2224 it->selective = (INTEGERP (current_buffer->selective_display)
2225 ? XFASTINT (current_buffer->selective_display)
2226 : (!NILP (current_buffer->selective_display)
2227 ? -1 : 0));
2228 it->selective_display_ellipsis_p
2229 = !NILP (current_buffer->selective_display_ellipses);
2230
2231 /* Display table to use. */
2232 it->dp = window_display_table (w);
2233
2234 /* Are multibyte characters enabled in current_buffer? */
2235 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2236
2237 /* Non-zero if we should highlight the region. */
2238 highlight_region_p
2239 = (!NILP (Vtransient_mark_mode)
2240 && !NILP (current_buffer->mark_active)
2241 && XMARKER (current_buffer->mark)->buffer != 0);
2242
2243 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2244 start and end of a visible region in window IT->w. Set both to
2245 -1 to indicate no region. */
2246 if (highlight_region_p
2247 /* Maybe highlight only in selected window. */
2248 && (/* Either show region everywhere. */
2249 highlight_nonselected_windows
2250 /* Or show region in the selected window. */
2251 || w == XWINDOW (selected_window)
2252 /* Or show the region if we are in the mini-buffer and W is
2253 the window the mini-buffer refers to. */
2254 || (MINI_WINDOW_P (XWINDOW (selected_window))
2255 && WINDOWP (minibuf_selected_window)
2256 && w == XWINDOW (minibuf_selected_window))))
2257 {
2258 int charpos = marker_position (current_buffer->mark);
2259 it->region_beg_charpos = min (PT, charpos);
2260 it->region_end_charpos = max (PT, charpos);
2261 }
2262 else
2263 it->region_beg_charpos = it->region_end_charpos = -1;
2264
2265 /* Get the position at which the redisplay_end_trigger hook should
2266 be run, if it is to be run at all. */
2267 if (MARKERP (w->redisplay_end_trigger)
2268 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2269 it->redisplay_end_trigger_charpos
2270 = marker_position (w->redisplay_end_trigger);
2271 else if (INTEGERP (w->redisplay_end_trigger))
2272 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2273
2274 /* Correct bogus values of tab_width. */
2275 it->tab_width = XINT (current_buffer->tab_width);
2276 if (it->tab_width <= 0 || it->tab_width > 1000)
2277 it->tab_width = 8;
2278
2279 /* Are lines in the display truncated? */
2280 it->truncate_lines_p
2281 = (base_face_id != DEFAULT_FACE_ID
2282 || XINT (it->w->hscroll)
2283 || (truncate_partial_width_windows
2284 && !WINDOW_FULL_WIDTH_P (it->w))
2285 || !NILP (current_buffer->truncate_lines));
2286
2287 /* Get dimensions of truncation and continuation glyphs. These are
2288 displayed as fringe bitmaps under X, so we don't need them for such
2289 frames. */
2290 if (!FRAME_WINDOW_P (it->f))
2291 {
2292 if (it->truncate_lines_p)
2293 {
2294 /* We will need the truncation glyph. */
2295 xassert (it->glyph_row == NULL);
2296 produce_special_glyphs (it, IT_TRUNCATION);
2297 it->truncation_pixel_width = it->pixel_width;
2298 }
2299 else
2300 {
2301 /* We will need the continuation glyph. */
2302 xassert (it->glyph_row == NULL);
2303 produce_special_glyphs (it, IT_CONTINUATION);
2304 it->continuation_pixel_width = it->pixel_width;
2305 }
2306
2307 /* Reset these values to zero because the produce_special_glyphs
2308 above has changed them. */
2309 it->pixel_width = it->ascent = it->descent = 0;
2310 it->phys_ascent = it->phys_descent = 0;
2311 }
2312
2313 /* Set this after getting the dimensions of truncation and
2314 continuation glyphs, so that we don't produce glyphs when calling
2315 produce_special_glyphs, above. */
2316 it->glyph_row = row;
2317 it->area = TEXT_AREA;
2318
2319 /* Get the dimensions of the display area. The display area
2320 consists of the visible window area plus a horizontally scrolled
2321 part to the left of the window. All x-values are relative to the
2322 start of this total display area. */
2323 if (base_face_id != DEFAULT_FACE_ID)
2324 {
2325 /* Mode lines, menu bar in terminal frames. */
2326 it->first_visible_x = 0;
2327 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2328 }
2329 else
2330 {
2331 it->first_visible_x
2332 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2333 it->last_visible_x = (it->first_visible_x
2334 + window_box_width (w, TEXT_AREA));
2335
2336 /* If we truncate lines, leave room for the truncator glyph(s) at
2337 the right margin. Otherwise, leave room for the continuation
2338 glyph(s). Truncation and continuation glyphs are not inserted
2339 for window-based redisplay. */
2340 if (!FRAME_WINDOW_P (it->f))
2341 {
2342 if (it->truncate_lines_p)
2343 it->last_visible_x -= it->truncation_pixel_width;
2344 else
2345 it->last_visible_x -= it->continuation_pixel_width;
2346 }
2347
2348 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2349 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2350 }
2351
2352 /* Leave room for a border glyph. */
2353 if (!FRAME_WINDOW_P (it->f)
2354 && !WINDOW_RIGHTMOST_P (it->w))
2355 it->last_visible_x -= 1;
2356
2357 it->last_visible_y = window_text_bottom_y (w);
2358
2359 /* For mode lines and alike, arrange for the first glyph having a
2360 left box line if the face specifies a box. */
2361 if (base_face_id != DEFAULT_FACE_ID)
2362 {
2363 struct face *face;
2364
2365 it->face_id = base_face_id;
2366
2367 /* If we have a boxed mode line, make the first character appear
2368 with a left box line. */
2369 face = FACE_FROM_ID (it->f, base_face_id);
2370 if (face->box != FACE_NO_BOX)
2371 it->start_of_box_run_p = 1;
2372 }
2373
2374 /* If a buffer position was specified, set the iterator there,
2375 getting overlays and face properties from that position. */
2376 if (charpos >= BUF_BEG (current_buffer))
2377 {
2378 it->end_charpos = ZV;
2379 it->face_id = -1;
2380 IT_CHARPOS (*it) = charpos;
2381
2382 /* Compute byte position if not specified. */
2383 if (bytepos < charpos)
2384 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2385 else
2386 IT_BYTEPOS (*it) = bytepos;
2387
2388 it->start = it->current;
2389
2390 /* Compute faces etc. */
2391 reseat (it, it->current.pos, 1);
2392 }
2393
2394 CHECK_IT (it);
2395 }
2396
2397
2398 /* Initialize IT for the display of window W with window start POS. */
2399
2400 void
2401 start_display (it, w, pos)
2402 struct it *it;
2403 struct window *w;
2404 struct text_pos pos;
2405 {
2406 struct glyph_row *row;
2407 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2408
2409 row = w->desired_matrix->rows + first_vpos;
2410 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2411 it->first_vpos = first_vpos;
2412
2413 if (!it->truncate_lines_p)
2414 {
2415 int start_at_line_beg_p;
2416 int first_y = it->current_y;
2417
2418 /* If window start is not at a line start, skip forward to POS to
2419 get the correct continuation lines width. */
2420 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2421 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2422 if (!start_at_line_beg_p)
2423 {
2424 int new_x;
2425
2426 reseat_at_previous_visible_line_start (it);
2427 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2428
2429 new_x = it->current_x + it->pixel_width;
2430
2431 /* If lines are continued, this line may end in the middle
2432 of a multi-glyph character (e.g. a control character
2433 displayed as \003, or in the middle of an overlay
2434 string). In this case move_it_to above will not have
2435 taken us to the start of the continuation line but to the
2436 end of the continued line. */
2437 if (it->current_x > 0
2438 && !it->truncate_lines_p /* Lines are continued. */
2439 && (/* And glyph doesn't fit on the line. */
2440 new_x > it->last_visible_x
2441 /* Or it fits exactly and we're on a window
2442 system frame. */
2443 || (new_x == it->last_visible_x
2444 && FRAME_WINDOW_P (it->f))))
2445 {
2446 if (it->current.dpvec_index >= 0
2447 || it->current.overlay_string_index >= 0)
2448 {
2449 set_iterator_to_next (it, 1);
2450 move_it_in_display_line_to (it, -1, -1, 0);
2451 }
2452
2453 it->continuation_lines_width += it->current_x;
2454 }
2455
2456 /* We're starting a new display line, not affected by the
2457 height of the continued line, so clear the appropriate
2458 fields in the iterator structure. */
2459 it->max_ascent = it->max_descent = 0;
2460 it->max_phys_ascent = it->max_phys_descent = 0;
2461
2462 it->current_y = first_y;
2463 it->vpos = 0;
2464 it->current_x = it->hpos = 0;
2465 }
2466 }
2467
2468 #if 0 /* Don't assert the following because start_display is sometimes
2469 called intentionally with a window start that is not at a
2470 line start. Please leave this code in as a comment. */
2471
2472 /* Window start should be on a line start, now. */
2473 xassert (it->continuation_lines_width
2474 || IT_CHARPOS (it) == BEGV
2475 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2476 #endif /* 0 */
2477 }
2478
2479
2480 /* Return 1 if POS is a position in ellipses displayed for invisible
2481 text. W is the window we display, for text property lookup. */
2482
2483 static int
2484 in_ellipses_for_invisible_text_p (pos, w)
2485 struct display_pos *pos;
2486 struct window *w;
2487 {
2488 Lisp_Object prop, window;
2489 int ellipses_p = 0;
2490 int charpos = CHARPOS (pos->pos);
2491
2492 /* If POS specifies a position in a display vector, this might
2493 be for an ellipsis displayed for invisible text. We won't
2494 get the iterator set up for delivering that ellipsis unless
2495 we make sure that it gets aware of the invisible text. */
2496 if (pos->dpvec_index >= 0
2497 && pos->overlay_string_index < 0
2498 && CHARPOS (pos->string_pos) < 0
2499 && charpos > BEGV
2500 && (XSETWINDOW (window, w),
2501 prop = Fget_char_property (make_number (charpos),
2502 Qinvisible, window),
2503 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2504 {
2505 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2506 window);
2507 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2508 }
2509
2510 return ellipses_p;
2511 }
2512
2513
2514 /* Initialize IT for stepping through current_buffer in window W,
2515 starting at position POS that includes overlay string and display
2516 vector/ control character translation position information. Value
2517 is zero if there are overlay strings with newlines at POS. */
2518
2519 static int
2520 init_from_display_pos (it, w, pos)
2521 struct it *it;
2522 struct window *w;
2523 struct display_pos *pos;
2524 {
2525 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2526 int i, overlay_strings_with_newlines = 0;
2527
2528 /* If POS specifies a position in a display vector, this might
2529 be for an ellipsis displayed for invisible text. We won't
2530 get the iterator set up for delivering that ellipsis unless
2531 we make sure that it gets aware of the invisible text. */
2532 if (in_ellipses_for_invisible_text_p (pos, w))
2533 {
2534 --charpos;
2535 bytepos = 0;
2536 }
2537
2538 /* Keep in mind: the call to reseat in init_iterator skips invisible
2539 text, so we might end up at a position different from POS. This
2540 is only a problem when POS is a row start after a newline and an
2541 overlay starts there with an after-string, and the overlay has an
2542 invisible property. Since we don't skip invisible text in
2543 display_line and elsewhere immediately after consuming the
2544 newline before the row start, such a POS will not be in a string,
2545 but the call to init_iterator below will move us to the
2546 after-string. */
2547 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2548
2549 /* This only scans the current chunk -- it should scan all chunks.
2550 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2551 to 16 in 22.1 to make this a lesser problem. */
2552 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2553 {
2554 const char *s = SDATA (it->overlay_strings[i]);
2555 const char *e = s + SBYTES (it->overlay_strings[i]);
2556
2557 while (s < e && *s != '\n')
2558 ++s;
2559
2560 if (s < e)
2561 {
2562 overlay_strings_with_newlines = 1;
2563 break;
2564 }
2565 }
2566
2567 /* If position is within an overlay string, set up IT to the right
2568 overlay string. */
2569 if (pos->overlay_string_index >= 0)
2570 {
2571 int relative_index;
2572
2573 /* If the first overlay string happens to have a `display'
2574 property for an image, the iterator will be set up for that
2575 image, and we have to undo that setup first before we can
2576 correct the overlay string index. */
2577 if (it->method == GET_FROM_IMAGE)
2578 pop_it (it);
2579
2580 /* We already have the first chunk of overlay strings in
2581 IT->overlay_strings. Load more until the one for
2582 pos->overlay_string_index is in IT->overlay_strings. */
2583 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2584 {
2585 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2586 it->current.overlay_string_index = 0;
2587 while (n--)
2588 {
2589 load_overlay_strings (it, 0);
2590 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2591 }
2592 }
2593
2594 it->current.overlay_string_index = pos->overlay_string_index;
2595 relative_index = (it->current.overlay_string_index
2596 % OVERLAY_STRING_CHUNK_SIZE);
2597 it->string = it->overlay_strings[relative_index];
2598 xassert (STRINGP (it->string));
2599 it->current.string_pos = pos->string_pos;
2600 it->method = GET_FROM_STRING;
2601 }
2602
2603 #if 0 /* This is bogus because POS not having an overlay string
2604 position does not mean it's after the string. Example: A
2605 line starting with a before-string and initialization of IT
2606 to the previous row's end position. */
2607 else if (it->current.overlay_string_index >= 0)
2608 {
2609 /* If POS says we're already after an overlay string ending at
2610 POS, make sure to pop the iterator because it will be in
2611 front of that overlay string. When POS is ZV, we've thereby
2612 also ``processed'' overlay strings at ZV. */
2613 while (it->sp)
2614 pop_it (it);
2615 it->current.overlay_string_index = -1;
2616 it->method = GET_FROM_BUFFER;
2617 if (CHARPOS (pos->pos) == ZV)
2618 it->overlay_strings_at_end_processed_p = 1;
2619 }
2620 #endif /* 0 */
2621
2622 if (CHARPOS (pos->string_pos) >= 0)
2623 {
2624 /* Recorded position is not in an overlay string, but in another
2625 string. This can only be a string from a `display' property.
2626 IT should already be filled with that string. */
2627 it->current.string_pos = pos->string_pos;
2628 xassert (STRINGP (it->string));
2629 }
2630
2631 /* Restore position in display vector translations, control
2632 character translations or ellipses. */
2633 if (pos->dpvec_index >= 0)
2634 {
2635 if (it->dpvec == NULL)
2636 get_next_display_element (it);
2637 xassert (it->dpvec && it->current.dpvec_index == 0);
2638 it->current.dpvec_index = pos->dpvec_index;
2639 }
2640
2641 CHECK_IT (it);
2642 return !overlay_strings_with_newlines;
2643 }
2644
2645
2646 /* Initialize IT for stepping through current_buffer in window W
2647 starting at ROW->start. */
2648
2649 static void
2650 init_to_row_start (it, w, row)
2651 struct it *it;
2652 struct window *w;
2653 struct glyph_row *row;
2654 {
2655 init_from_display_pos (it, w, &row->start);
2656 it->start = row->start;
2657 it->continuation_lines_width = row->continuation_lines_width;
2658 CHECK_IT (it);
2659 }
2660
2661
2662 /* Initialize IT for stepping through current_buffer in window W
2663 starting in the line following ROW, i.e. starting at ROW->end.
2664 Value is zero if there are overlay strings with newlines at ROW's
2665 end position. */
2666
2667 static int
2668 init_to_row_end (it, w, row)
2669 struct it *it;
2670 struct window *w;
2671 struct glyph_row *row;
2672 {
2673 int success = 0;
2674
2675 if (init_from_display_pos (it, w, &row->end))
2676 {
2677 if (row->continued_p)
2678 it->continuation_lines_width
2679 = row->continuation_lines_width + row->pixel_width;
2680 CHECK_IT (it);
2681 success = 1;
2682 }
2683
2684 return success;
2685 }
2686
2687
2688
2689 \f
2690 /***********************************************************************
2691 Text properties
2692 ***********************************************************************/
2693
2694 /* Called when IT reaches IT->stop_charpos. Handle text property and
2695 overlay changes. Set IT->stop_charpos to the next position where
2696 to stop. */
2697
2698 static void
2699 handle_stop (it)
2700 struct it *it;
2701 {
2702 enum prop_handled handled;
2703 int handle_overlay_change_p = 1;
2704 struct props *p;
2705
2706 it->dpvec = NULL;
2707 it->current.dpvec_index = -1;
2708
2709 /* Use face of preceding text for ellipsis (if invisible) */
2710 if (it->selective_display_ellipsis_p)
2711 it->saved_face_id = it->face_id;
2712
2713 do
2714 {
2715 handled = HANDLED_NORMALLY;
2716
2717 /* Call text property handlers. */
2718 for (p = it_props; p->handler; ++p)
2719 {
2720 handled = p->handler (it);
2721
2722 if (handled == HANDLED_RECOMPUTE_PROPS)
2723 break;
2724 else if (handled == HANDLED_RETURN)
2725 return;
2726 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2727 handle_overlay_change_p = 0;
2728 }
2729
2730 if (handled != HANDLED_RECOMPUTE_PROPS)
2731 {
2732 /* Don't check for overlay strings below when set to deliver
2733 characters from a display vector. */
2734 if (it->method == GET_FROM_DISPLAY_VECTOR)
2735 handle_overlay_change_p = 0;
2736
2737 /* Handle overlay changes. */
2738 if (handle_overlay_change_p)
2739 handled = handle_overlay_change (it);
2740
2741 /* Determine where to stop next. */
2742 if (handled == HANDLED_NORMALLY)
2743 compute_stop_pos (it);
2744 }
2745 }
2746 while (handled == HANDLED_RECOMPUTE_PROPS);
2747 }
2748
2749
2750 /* Compute IT->stop_charpos from text property and overlay change
2751 information for IT's current position. */
2752
2753 static void
2754 compute_stop_pos (it)
2755 struct it *it;
2756 {
2757 register INTERVAL iv, next_iv;
2758 Lisp_Object object, limit, position;
2759
2760 /* If nowhere else, stop at the end. */
2761 it->stop_charpos = it->end_charpos;
2762
2763 if (STRINGP (it->string))
2764 {
2765 /* Strings are usually short, so don't limit the search for
2766 properties. */
2767 object = it->string;
2768 limit = Qnil;
2769 position = make_number (IT_STRING_CHARPOS (*it));
2770 }
2771 else
2772 {
2773 int charpos;
2774
2775 /* If next overlay change is in front of the current stop pos
2776 (which is IT->end_charpos), stop there. Note: value of
2777 next_overlay_change is point-max if no overlay change
2778 follows. */
2779 charpos = next_overlay_change (IT_CHARPOS (*it));
2780 if (charpos < it->stop_charpos)
2781 it->stop_charpos = charpos;
2782
2783 /* If showing the region, we have to stop at the region
2784 start or end because the face might change there. */
2785 if (it->region_beg_charpos > 0)
2786 {
2787 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2788 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2789 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2790 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2791 }
2792
2793 /* Set up variables for computing the stop position from text
2794 property changes. */
2795 XSETBUFFER (object, current_buffer);
2796 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2797 position = make_number (IT_CHARPOS (*it));
2798
2799 }
2800
2801 /* Get the interval containing IT's position. Value is a null
2802 interval if there isn't such an interval. */
2803 iv = validate_interval_range (object, &position, &position, 0);
2804 if (!NULL_INTERVAL_P (iv))
2805 {
2806 Lisp_Object values_here[LAST_PROP_IDX];
2807 struct props *p;
2808
2809 /* Get properties here. */
2810 for (p = it_props; p->handler; ++p)
2811 values_here[p->idx] = textget (iv->plist, *p->name);
2812
2813 /* Look for an interval following iv that has different
2814 properties. */
2815 for (next_iv = next_interval (iv);
2816 (!NULL_INTERVAL_P (next_iv)
2817 && (NILP (limit)
2818 || XFASTINT (limit) > next_iv->position));
2819 next_iv = next_interval (next_iv))
2820 {
2821 for (p = it_props; p->handler; ++p)
2822 {
2823 Lisp_Object new_value;
2824
2825 new_value = textget (next_iv->plist, *p->name);
2826 if (!EQ (values_here[p->idx], new_value))
2827 break;
2828 }
2829
2830 if (p->handler)
2831 break;
2832 }
2833
2834 if (!NULL_INTERVAL_P (next_iv))
2835 {
2836 if (INTEGERP (limit)
2837 && next_iv->position >= XFASTINT (limit))
2838 /* No text property change up to limit. */
2839 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2840 else
2841 /* Text properties change in next_iv. */
2842 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2843 }
2844 }
2845
2846 xassert (STRINGP (it->string)
2847 || (it->stop_charpos >= BEGV
2848 && it->stop_charpos >= IT_CHARPOS (*it)));
2849 }
2850
2851
2852 /* Return the position of the next overlay change after POS in
2853 current_buffer. Value is point-max if no overlay change
2854 follows. This is like `next-overlay-change' but doesn't use
2855 xmalloc. */
2856
2857 static int
2858 next_overlay_change (pos)
2859 int pos;
2860 {
2861 int noverlays;
2862 int endpos;
2863 Lisp_Object *overlays;
2864 int i;
2865
2866 /* Get all overlays at the given position. */
2867 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2868
2869 /* If any of these overlays ends before endpos,
2870 use its ending point instead. */
2871 for (i = 0; i < noverlays; ++i)
2872 {
2873 Lisp_Object oend;
2874 int oendpos;
2875
2876 oend = OVERLAY_END (overlays[i]);
2877 oendpos = OVERLAY_POSITION (oend);
2878 endpos = min (endpos, oendpos);
2879 }
2880
2881 return endpos;
2882 }
2883
2884
2885 \f
2886 /***********************************************************************
2887 Fontification
2888 ***********************************************************************/
2889
2890 /* Handle changes in the `fontified' property of the current buffer by
2891 calling hook functions from Qfontification_functions to fontify
2892 regions of text. */
2893
2894 static enum prop_handled
2895 handle_fontified_prop (it)
2896 struct it *it;
2897 {
2898 Lisp_Object prop, pos;
2899 enum prop_handled handled = HANDLED_NORMALLY;
2900
2901 /* Get the value of the `fontified' property at IT's current buffer
2902 position. (The `fontified' property doesn't have a special
2903 meaning in strings.) If the value is nil, call functions from
2904 Qfontification_functions. */
2905 if (!STRINGP (it->string)
2906 && it->s == NULL
2907 && !NILP (Vfontification_functions)
2908 && !NILP (Vrun_hooks)
2909 && (pos = make_number (IT_CHARPOS (*it)),
2910 prop = Fget_char_property (pos, Qfontified, Qnil),
2911 NILP (prop)))
2912 {
2913 int count = SPECPDL_INDEX ();
2914 Lisp_Object val;
2915
2916 val = Vfontification_functions;
2917 specbind (Qfontification_functions, Qnil);
2918
2919 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2920 safe_call1 (val, pos);
2921 else
2922 {
2923 Lisp_Object globals, fn;
2924 struct gcpro gcpro1, gcpro2;
2925
2926 globals = Qnil;
2927 GCPRO2 (val, globals);
2928
2929 for (; CONSP (val); val = XCDR (val))
2930 {
2931 fn = XCAR (val);
2932
2933 if (EQ (fn, Qt))
2934 {
2935 /* A value of t indicates this hook has a local
2936 binding; it means to run the global binding too.
2937 In a global value, t should not occur. If it
2938 does, we must ignore it to avoid an endless
2939 loop. */
2940 for (globals = Fdefault_value (Qfontification_functions);
2941 CONSP (globals);
2942 globals = XCDR (globals))
2943 {
2944 fn = XCAR (globals);
2945 if (!EQ (fn, Qt))
2946 safe_call1 (fn, pos);
2947 }
2948 }
2949 else
2950 safe_call1 (fn, pos);
2951 }
2952
2953 UNGCPRO;
2954 }
2955
2956 unbind_to (count, Qnil);
2957
2958 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2959 something. This avoids an endless loop if they failed to
2960 fontify the text for which reason ever. */
2961 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2962 handled = HANDLED_RECOMPUTE_PROPS;
2963 }
2964
2965 return handled;
2966 }
2967
2968
2969 \f
2970 /***********************************************************************
2971 Faces
2972 ***********************************************************************/
2973
2974 /* Set up iterator IT from face properties at its current position.
2975 Called from handle_stop. */
2976
2977 static enum prop_handled
2978 handle_face_prop (it)
2979 struct it *it;
2980 {
2981 int new_face_id, next_stop;
2982
2983 if (!STRINGP (it->string))
2984 {
2985 new_face_id
2986 = face_at_buffer_position (it->w,
2987 IT_CHARPOS (*it),
2988 it->region_beg_charpos,
2989 it->region_end_charpos,
2990 &next_stop,
2991 (IT_CHARPOS (*it)
2992 + TEXT_PROP_DISTANCE_LIMIT),
2993 0);
2994
2995 /* Is this a start of a run of characters with box face?
2996 Caveat: this can be called for a freshly initialized
2997 iterator; face_id is -1 in this case. We know that the new
2998 face will not change until limit, i.e. if the new face has a
2999 box, all characters up to limit will have one. But, as
3000 usual, we don't know whether limit is really the end. */
3001 if (new_face_id != it->face_id)
3002 {
3003 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3004
3005 /* If new face has a box but old face has not, this is
3006 the start of a run of characters with box, i.e. it has
3007 a shadow on the left side. The value of face_id of the
3008 iterator will be -1 if this is the initial call that gets
3009 the face. In this case, we have to look in front of IT's
3010 position and see whether there is a face != new_face_id. */
3011 it->start_of_box_run_p
3012 = (new_face->box != FACE_NO_BOX
3013 && (it->face_id >= 0
3014 || IT_CHARPOS (*it) == BEG
3015 || new_face_id != face_before_it_pos (it)));
3016 it->face_box_p = new_face->box != FACE_NO_BOX;
3017 }
3018 }
3019 else
3020 {
3021 int base_face_id, bufpos;
3022
3023 if (it->current.overlay_string_index >= 0)
3024 bufpos = IT_CHARPOS (*it);
3025 else
3026 bufpos = 0;
3027
3028 /* For strings from a buffer, i.e. overlay strings or strings
3029 from a `display' property, use the face at IT's current
3030 buffer position as the base face to merge with, so that
3031 overlay strings appear in the same face as surrounding
3032 text, unless they specify their own faces. */
3033 base_face_id = underlying_face_id (it);
3034
3035 new_face_id = face_at_string_position (it->w,
3036 it->string,
3037 IT_STRING_CHARPOS (*it),
3038 bufpos,
3039 it->region_beg_charpos,
3040 it->region_end_charpos,
3041 &next_stop,
3042 base_face_id, 0);
3043
3044 #if 0 /* This shouldn't be neccessary. Let's check it. */
3045 /* If IT is used to display a mode line we would really like to
3046 use the mode line face instead of the frame's default face. */
3047 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3048 && new_face_id == DEFAULT_FACE_ID)
3049 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3050 #endif
3051
3052 /* Is this a start of a run of characters with box? Caveat:
3053 this can be called for a freshly allocated iterator; face_id
3054 is -1 is this case. We know that the new face will not
3055 change until the next check pos, i.e. if the new face has a
3056 box, all characters up to that position will have a
3057 box. But, as usual, we don't know whether that position
3058 is really the end. */
3059 if (new_face_id != it->face_id)
3060 {
3061 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3062 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3063
3064 /* If new face has a box but old face hasn't, this is the
3065 start of a run of characters with box, i.e. it has a
3066 shadow on the left side. */
3067 it->start_of_box_run_p
3068 = new_face->box && (old_face == NULL || !old_face->box);
3069 it->face_box_p = new_face->box != FACE_NO_BOX;
3070 }
3071 }
3072
3073 it->face_id = new_face_id;
3074 return HANDLED_NORMALLY;
3075 }
3076
3077
3078 /* Return the ID of the face ``underlying'' IT's current position,
3079 which is in a string. If the iterator is associated with a
3080 buffer, return the face at IT's current buffer position.
3081 Otherwise, use the iterator's base_face_id. */
3082
3083 static int
3084 underlying_face_id (it)
3085 struct it *it;
3086 {
3087 int face_id = it->base_face_id, i;
3088
3089 xassert (STRINGP (it->string));
3090
3091 for (i = it->sp - 1; i >= 0; --i)
3092 if (NILP (it->stack[i].string))
3093 face_id = it->stack[i].face_id;
3094
3095 return face_id;
3096 }
3097
3098
3099 /* Compute the face one character before or after the current position
3100 of IT. BEFORE_P non-zero means get the face in front of IT's
3101 position. Value is the id of the face. */
3102
3103 static int
3104 face_before_or_after_it_pos (it, before_p)
3105 struct it *it;
3106 int before_p;
3107 {
3108 int face_id, limit;
3109 int next_check_charpos;
3110 struct text_pos pos;
3111
3112 xassert (it->s == NULL);
3113
3114 if (STRINGP (it->string))
3115 {
3116 int bufpos, base_face_id;
3117
3118 /* No face change past the end of the string (for the case
3119 we are padding with spaces). No face change before the
3120 string start. */
3121 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3122 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3123 return it->face_id;
3124
3125 /* Set pos to the position before or after IT's current position. */
3126 if (before_p)
3127 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3128 else
3129 /* For composition, we must check the character after the
3130 composition. */
3131 pos = (it->what == IT_COMPOSITION
3132 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3133 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3134
3135 if (it->current.overlay_string_index >= 0)
3136 bufpos = IT_CHARPOS (*it);
3137 else
3138 bufpos = 0;
3139
3140 base_face_id = underlying_face_id (it);
3141
3142 /* Get the face for ASCII, or unibyte. */
3143 face_id = face_at_string_position (it->w,
3144 it->string,
3145 CHARPOS (pos),
3146 bufpos,
3147 it->region_beg_charpos,
3148 it->region_end_charpos,
3149 &next_check_charpos,
3150 base_face_id, 0);
3151
3152 /* Correct the face for charsets different from ASCII. Do it
3153 for the multibyte case only. The face returned above is
3154 suitable for unibyte text if IT->string is unibyte. */
3155 if (STRING_MULTIBYTE (it->string))
3156 {
3157 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3158 int rest = SBYTES (it->string) - BYTEPOS (pos);
3159 int c, len;
3160 struct face *face = FACE_FROM_ID (it->f, face_id);
3161
3162 c = string_char_and_length (p, rest, &len);
3163 face_id = FACE_FOR_CHAR (it->f, face, c);
3164 }
3165 }
3166 else
3167 {
3168 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3169 || (IT_CHARPOS (*it) <= BEGV && before_p))
3170 return it->face_id;
3171
3172 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3173 pos = it->current.pos;
3174
3175 if (before_p)
3176 DEC_TEXT_POS (pos, it->multibyte_p);
3177 else
3178 {
3179 if (it->what == IT_COMPOSITION)
3180 /* For composition, we must check the position after the
3181 composition. */
3182 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3183 else
3184 INC_TEXT_POS (pos, it->multibyte_p);
3185 }
3186
3187 /* Determine face for CHARSET_ASCII, or unibyte. */
3188 face_id = face_at_buffer_position (it->w,
3189 CHARPOS (pos),
3190 it->region_beg_charpos,
3191 it->region_end_charpos,
3192 &next_check_charpos,
3193 limit, 0);
3194
3195 /* Correct the face for charsets different from ASCII. Do it
3196 for the multibyte case only. The face returned above is
3197 suitable for unibyte text if current_buffer is unibyte. */
3198 if (it->multibyte_p)
3199 {
3200 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3201 struct face *face = FACE_FROM_ID (it->f, face_id);
3202 face_id = FACE_FOR_CHAR (it->f, face, c);
3203 }
3204 }
3205
3206 return face_id;
3207 }
3208
3209
3210 \f
3211 /***********************************************************************
3212 Invisible text
3213 ***********************************************************************/
3214
3215 /* Set up iterator IT from invisible properties at its current
3216 position. Called from handle_stop. */
3217
3218 static enum prop_handled
3219 handle_invisible_prop (it)
3220 struct it *it;
3221 {
3222 enum prop_handled handled = HANDLED_NORMALLY;
3223
3224 if (STRINGP (it->string))
3225 {
3226 extern Lisp_Object Qinvisible;
3227 Lisp_Object prop, end_charpos, limit, charpos;
3228
3229 /* Get the value of the invisible text property at the
3230 current position. Value will be nil if there is no such
3231 property. */
3232 charpos = make_number (IT_STRING_CHARPOS (*it));
3233 prop = Fget_text_property (charpos, Qinvisible, it->string);
3234
3235 if (!NILP (prop)
3236 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3237 {
3238 handled = HANDLED_RECOMPUTE_PROPS;
3239
3240 /* Get the position at which the next change of the
3241 invisible text property can be found in IT->string.
3242 Value will be nil if the property value is the same for
3243 all the rest of IT->string. */
3244 XSETINT (limit, SCHARS (it->string));
3245 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3246 it->string, limit);
3247
3248 /* Text at current position is invisible. The next
3249 change in the property is at position end_charpos.
3250 Move IT's current position to that position. */
3251 if (INTEGERP (end_charpos)
3252 && XFASTINT (end_charpos) < XFASTINT (limit))
3253 {
3254 struct text_pos old;
3255 old = it->current.string_pos;
3256 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3257 compute_string_pos (&it->current.string_pos, old, it->string);
3258 }
3259 else
3260 {
3261 /* The rest of the string is invisible. If this is an
3262 overlay string, proceed with the next overlay string
3263 or whatever comes and return a character from there. */
3264 if (it->current.overlay_string_index >= 0)
3265 {
3266 next_overlay_string (it);
3267 /* Don't check for overlay strings when we just
3268 finished processing them. */
3269 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3270 }
3271 else
3272 {
3273 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3274 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3275 }
3276 }
3277 }
3278 }
3279 else
3280 {
3281 int invis_p, newpos, next_stop, start_charpos;
3282 Lisp_Object pos, prop, overlay;
3283
3284 /* First of all, is there invisible text at this position? */
3285 start_charpos = IT_CHARPOS (*it);
3286 pos = make_number (IT_CHARPOS (*it));
3287 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3288 &overlay);
3289 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3290
3291 /* If we are on invisible text, skip over it. */
3292 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3293 {
3294 /* Record whether we have to display an ellipsis for the
3295 invisible text. */
3296 int display_ellipsis_p = invis_p == 2;
3297
3298 handled = HANDLED_RECOMPUTE_PROPS;
3299
3300 /* Loop skipping over invisible text. The loop is left at
3301 ZV or with IT on the first char being visible again. */
3302 do
3303 {
3304 /* Try to skip some invisible text. Return value is the
3305 position reached which can be equal to IT's position
3306 if there is nothing invisible here. This skips both
3307 over invisible text properties and overlays with
3308 invisible property. */
3309 newpos = skip_invisible (IT_CHARPOS (*it),
3310 &next_stop, ZV, it->window);
3311
3312 /* If we skipped nothing at all we weren't at invisible
3313 text in the first place. If everything to the end of
3314 the buffer was skipped, end the loop. */
3315 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3316 invis_p = 0;
3317 else
3318 {
3319 /* We skipped some characters but not necessarily
3320 all there are. Check if we ended up on visible
3321 text. Fget_char_property returns the property of
3322 the char before the given position, i.e. if we
3323 get invis_p = 0, this means that the char at
3324 newpos is visible. */
3325 pos = make_number (newpos);
3326 prop = Fget_char_property (pos, Qinvisible, it->window);
3327 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3328 }
3329
3330 /* If we ended up on invisible text, proceed to
3331 skip starting with next_stop. */
3332 if (invis_p)
3333 IT_CHARPOS (*it) = next_stop;
3334 }
3335 while (invis_p);
3336
3337 /* The position newpos is now either ZV or on visible text. */
3338 IT_CHARPOS (*it) = newpos;
3339 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3340
3341 /* If there are before-strings at the start of invisible
3342 text, and the text is invisible because of a text
3343 property, arrange to show before-strings because 20.x did
3344 it that way. (If the text is invisible because of an
3345 overlay property instead of a text property, this is
3346 already handled in the overlay code.) */
3347 if (NILP (overlay)
3348 && get_overlay_strings (it, start_charpos))
3349 {
3350 handled = HANDLED_RECOMPUTE_PROPS;
3351 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3352 }
3353 else if (display_ellipsis_p)
3354 setup_for_ellipsis (it, 0);
3355 }
3356 }
3357
3358 return handled;
3359 }
3360
3361
3362 /* Make iterator IT return `...' next.
3363 Replaces LEN characters from buffer. */
3364
3365 static void
3366 setup_for_ellipsis (it, len)
3367 struct it *it;
3368 int len;
3369 {
3370 /* Use the display table definition for `...'. Invalid glyphs
3371 will be handled by the method returning elements from dpvec. */
3372 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3373 {
3374 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3375 it->dpvec = v->contents;
3376 it->dpend = v->contents + v->size;
3377 }
3378 else
3379 {
3380 /* Default `...'. */
3381 it->dpvec = default_invis_vector;
3382 it->dpend = default_invis_vector + 3;
3383 }
3384
3385 it->dpvec_char_len = len;
3386 it->current.dpvec_index = 0;
3387 it->dpvec_face_id = -1;
3388
3389 /* Remember the current face id in case glyphs specify faces.
3390 IT's face is restored in set_iterator_to_next.
3391 saved_face_id was set to preceding char's face in handle_stop. */
3392 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3393 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3394
3395 it->method = GET_FROM_DISPLAY_VECTOR;
3396 it->ellipsis_p = 1;
3397 }
3398
3399
3400 \f
3401 /***********************************************************************
3402 'display' property
3403 ***********************************************************************/
3404
3405 /* Set up iterator IT from `display' property at its current position.
3406 Called from handle_stop.
3407 We return HANDLED_RETURN if some part of the display property
3408 overrides the display of the buffer text itself.
3409 Otherwise we return HANDLED_NORMALLY. */
3410
3411 static enum prop_handled
3412 handle_display_prop (it)
3413 struct it *it;
3414 {
3415 Lisp_Object prop, object;
3416 struct text_pos *position;
3417 /* Nonzero if some property replaces the display of the text itself. */
3418 int display_replaced_p = 0;
3419
3420 if (STRINGP (it->string))
3421 {
3422 object = it->string;
3423 position = &it->current.string_pos;
3424 }
3425 else
3426 {
3427 object = it->w->buffer;
3428 position = &it->current.pos;
3429 }
3430
3431 /* Reset those iterator values set from display property values. */
3432 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3433 it->space_width = Qnil;
3434 it->font_height = Qnil;
3435 it->voffset = 0;
3436
3437 /* We don't support recursive `display' properties, i.e. string
3438 values that have a string `display' property, that have a string
3439 `display' property etc. */
3440 if (!it->string_from_display_prop_p)
3441 it->area = TEXT_AREA;
3442
3443 prop = Fget_char_property (make_number (position->charpos),
3444 Qdisplay, object);
3445 if (NILP (prop))
3446 return HANDLED_NORMALLY;
3447
3448 if (CONSP (prop)
3449 /* Simple properties. */
3450 && !EQ (XCAR (prop), Qimage)
3451 && !EQ (XCAR (prop), Qspace)
3452 && !EQ (XCAR (prop), Qwhen)
3453 && !EQ (XCAR (prop), Qslice)
3454 && !EQ (XCAR (prop), Qspace_width)
3455 && !EQ (XCAR (prop), Qheight)
3456 && !EQ (XCAR (prop), Qraise)
3457 /* Marginal area specifications. */
3458 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3459 && !EQ (XCAR (prop), Qleft_fringe)
3460 && !EQ (XCAR (prop), Qright_fringe)
3461 && !NILP (XCAR (prop)))
3462 {
3463 for (; CONSP (prop); prop = XCDR (prop))
3464 {
3465 if (handle_single_display_spec (it, XCAR (prop), object,
3466 position, display_replaced_p))
3467 display_replaced_p = 1;
3468 }
3469 }
3470 else if (VECTORP (prop))
3471 {
3472 int i;
3473 for (i = 0; i < ASIZE (prop); ++i)
3474 if (handle_single_display_spec (it, AREF (prop, i), object,
3475 position, display_replaced_p))
3476 display_replaced_p = 1;
3477 }
3478 else
3479 {
3480 if (handle_single_display_spec (it, prop, object, position, 0))
3481 display_replaced_p = 1;
3482 }
3483
3484 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3485 }
3486
3487
3488 /* Value is the position of the end of the `display' property starting
3489 at START_POS in OBJECT. */
3490
3491 static struct text_pos
3492 display_prop_end (it, object, start_pos)
3493 struct it *it;
3494 Lisp_Object object;
3495 struct text_pos start_pos;
3496 {
3497 Lisp_Object end;
3498 struct text_pos end_pos;
3499
3500 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3501 Qdisplay, object, Qnil);
3502 CHARPOS (end_pos) = XFASTINT (end);
3503 if (STRINGP (object))
3504 compute_string_pos (&end_pos, start_pos, it->string);
3505 else
3506 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3507
3508 return end_pos;
3509 }
3510
3511
3512 /* Set up IT from a single `display' specification PROP. OBJECT
3513 is the object in which the `display' property was found. *POSITION
3514 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3515 means that we previously saw a display specification which already
3516 replaced text display with something else, for example an image;
3517 we ignore such properties after the first one has been processed.
3518
3519 If PROP is a `space' or `image' specification, and in some other
3520 cases too, set *POSITION to the position where the `display'
3521 property ends.
3522
3523 Value is non-zero if something was found which replaces the display
3524 of buffer or string text. */
3525
3526 static int
3527 handle_single_display_spec (it, spec, object, position,
3528 display_replaced_before_p)
3529 struct it *it;
3530 Lisp_Object spec;
3531 Lisp_Object object;
3532 struct text_pos *position;
3533 int display_replaced_before_p;
3534 {
3535 Lisp_Object form;
3536 Lisp_Object location, value;
3537 struct text_pos start_pos;
3538 int valid_p;
3539
3540 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3541 If the result is non-nil, use VALUE instead of SPEC. */
3542 form = Qt;
3543 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3544 {
3545 spec = XCDR (spec);
3546 if (!CONSP (spec))
3547 return 0;
3548 form = XCAR (spec);
3549 spec = XCDR (spec);
3550 }
3551
3552 if (!NILP (form) && !EQ (form, Qt))
3553 {
3554 int count = SPECPDL_INDEX ();
3555 struct gcpro gcpro1;
3556
3557 /* Bind `object' to the object having the `display' property, a
3558 buffer or string. Bind `position' to the position in the
3559 object where the property was found, and `buffer-position'
3560 to the current position in the buffer. */
3561 specbind (Qobject, object);
3562 specbind (Qposition, make_number (CHARPOS (*position)));
3563 specbind (Qbuffer_position,
3564 make_number (STRINGP (object)
3565 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3566 GCPRO1 (form);
3567 form = safe_eval (form);
3568 UNGCPRO;
3569 unbind_to (count, Qnil);
3570 }
3571
3572 if (NILP (form))
3573 return 0;
3574
3575 /* Handle `(height HEIGHT)' specifications. */
3576 if (CONSP (spec)
3577 && EQ (XCAR (spec), Qheight)
3578 && CONSP (XCDR (spec)))
3579 {
3580 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3581 return 0;
3582
3583 it->font_height = XCAR (XCDR (spec));
3584 if (!NILP (it->font_height))
3585 {
3586 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3587 int new_height = -1;
3588
3589 if (CONSP (it->font_height)
3590 && (EQ (XCAR (it->font_height), Qplus)
3591 || EQ (XCAR (it->font_height), Qminus))
3592 && CONSP (XCDR (it->font_height))
3593 && INTEGERP (XCAR (XCDR (it->font_height))))
3594 {
3595 /* `(+ N)' or `(- N)' where N is an integer. */
3596 int steps = XINT (XCAR (XCDR (it->font_height)));
3597 if (EQ (XCAR (it->font_height), Qplus))
3598 steps = - steps;
3599 it->face_id = smaller_face (it->f, it->face_id, steps);
3600 }
3601 else if (FUNCTIONP (it->font_height))
3602 {
3603 /* Call function with current height as argument.
3604 Value is the new height. */
3605 Lisp_Object height;
3606 height = safe_call1 (it->font_height,
3607 face->lface[LFACE_HEIGHT_INDEX]);
3608 if (NUMBERP (height))
3609 new_height = XFLOATINT (height);
3610 }
3611 else if (NUMBERP (it->font_height))
3612 {
3613 /* Value is a multiple of the canonical char height. */
3614 struct face *face;
3615
3616 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3617 new_height = (XFLOATINT (it->font_height)
3618 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3619 }
3620 else
3621 {
3622 /* Evaluate IT->font_height with `height' bound to the
3623 current specified height to get the new height. */
3624 int count = SPECPDL_INDEX ();
3625
3626 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3627 value = safe_eval (it->font_height);
3628 unbind_to (count, Qnil);
3629
3630 if (NUMBERP (value))
3631 new_height = XFLOATINT (value);
3632 }
3633
3634 if (new_height > 0)
3635 it->face_id = face_with_height (it->f, it->face_id, new_height);
3636 }
3637
3638 return 0;
3639 }
3640
3641 /* Handle `(space_width WIDTH)'. */
3642 if (CONSP (spec)
3643 && EQ (XCAR (spec), Qspace_width)
3644 && CONSP (XCDR (spec)))
3645 {
3646 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3647 return 0;
3648
3649 value = XCAR (XCDR (spec));
3650 if (NUMBERP (value) && XFLOATINT (value) > 0)
3651 it->space_width = value;
3652
3653 return 0;
3654 }
3655
3656 /* Handle `(slice X Y WIDTH HEIGHT)'. */
3657 if (CONSP (spec)
3658 && EQ (XCAR (spec), Qslice))
3659 {
3660 Lisp_Object tem;
3661
3662 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3663 return 0;
3664
3665 if (tem = XCDR (spec), CONSP (tem))
3666 {
3667 it->slice.x = XCAR (tem);
3668 if (tem = XCDR (tem), CONSP (tem))
3669 {
3670 it->slice.y = XCAR (tem);
3671 if (tem = XCDR (tem), CONSP (tem))
3672 {
3673 it->slice.width = XCAR (tem);
3674 if (tem = XCDR (tem), CONSP (tem))
3675 it->slice.height = XCAR (tem);
3676 }
3677 }
3678 }
3679
3680 return 0;
3681 }
3682
3683 /* Handle `(raise FACTOR)'. */
3684 if (CONSP (spec)
3685 && EQ (XCAR (spec), Qraise)
3686 && CONSP (XCDR (spec)))
3687 {
3688 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3689 return 0;
3690
3691 #ifdef HAVE_WINDOW_SYSTEM
3692 value = XCAR (XCDR (spec));
3693 if (NUMBERP (value))
3694 {
3695 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3696 it->voffset = - (XFLOATINT (value)
3697 * (FONT_HEIGHT (face->font)));
3698 }
3699 #endif /* HAVE_WINDOW_SYSTEM */
3700
3701 return 0;
3702 }
3703
3704 /* Don't handle the other kinds of display specifications
3705 inside a string that we got from a `display' property. */
3706 if (it->string_from_display_prop_p)
3707 return 0;
3708
3709 /* Characters having this form of property are not displayed, so
3710 we have to find the end of the property. */
3711 start_pos = *position;
3712 *position = display_prop_end (it, object, start_pos);
3713 value = Qnil;
3714
3715 /* Stop the scan at that end position--we assume that all
3716 text properties change there. */
3717 it->stop_charpos = position->charpos;
3718
3719 /* Handle `(left-fringe BITMAP [FACE])'
3720 and `(right-fringe BITMAP [FACE])'. */
3721 if (CONSP (spec)
3722 && (EQ (XCAR (spec), Qleft_fringe)
3723 || EQ (XCAR (spec), Qright_fringe))
3724 && CONSP (XCDR (spec)))
3725 {
3726 int face_id = DEFAULT_FACE_ID;
3727 int fringe_bitmap;
3728
3729 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3730 /* If we return here, POSITION has been advanced
3731 across the text with this property. */
3732 return 0;
3733
3734 #ifdef HAVE_WINDOW_SYSTEM
3735 value = XCAR (XCDR (spec));
3736 if (!SYMBOLP (value)
3737 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3738 /* If we return here, POSITION has been advanced
3739 across the text with this property. */
3740 return 0;
3741
3742 if (CONSP (XCDR (XCDR (spec))))
3743 {
3744 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
3745 int face_id2 = lookup_derived_face (it->f, face_name,
3746 'A', FRINGE_FACE_ID, 0);
3747 if (face_id2 >= 0)
3748 face_id = face_id2;
3749 }
3750
3751 /* Save current settings of IT so that we can restore them
3752 when we are finished with the glyph property value. */
3753
3754 push_it (it);
3755
3756 it->area = TEXT_AREA;
3757 it->what = IT_IMAGE;
3758 it->image_id = -1; /* no image */
3759 it->position = start_pos;
3760 it->object = NILP (object) ? it->w->buffer : object;
3761 it->method = GET_FROM_IMAGE;
3762 it->face_id = face_id;
3763
3764 /* Say that we haven't consumed the characters with
3765 `display' property yet. The call to pop_it in
3766 set_iterator_to_next will clean this up. */
3767 *position = start_pos;
3768
3769 if (EQ (XCAR (spec), Qleft_fringe))
3770 {
3771 it->left_user_fringe_bitmap = fringe_bitmap;
3772 it->left_user_fringe_face_id = face_id;
3773 }
3774 else
3775 {
3776 it->right_user_fringe_bitmap = fringe_bitmap;
3777 it->right_user_fringe_face_id = face_id;
3778 }
3779 #endif /* HAVE_WINDOW_SYSTEM */
3780 return 1;
3781 }
3782
3783 /* Prepare to handle `((margin left-margin) ...)',
3784 `((margin right-margin) ...)' and `((margin nil) ...)'
3785 prefixes for display specifications. */
3786 location = Qunbound;
3787 if (CONSP (spec) && CONSP (XCAR (spec)))
3788 {
3789 Lisp_Object tem;
3790
3791 value = XCDR (spec);
3792 if (CONSP (value))
3793 value = XCAR (value);
3794
3795 tem = XCAR (spec);
3796 if (EQ (XCAR (tem), Qmargin)
3797 && (tem = XCDR (tem),
3798 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3799 (NILP (tem)
3800 || EQ (tem, Qleft_margin)
3801 || EQ (tem, Qright_margin))))
3802 location = tem;
3803 }
3804
3805 if (EQ (location, Qunbound))
3806 {
3807 location = Qnil;
3808 value = spec;
3809 }
3810
3811 /* After this point, VALUE is the property after any
3812 margin prefix has been stripped. It must be a string,
3813 an image specification, or `(space ...)'.
3814
3815 LOCATION specifies where to display: `left-margin',
3816 `right-margin' or nil. */
3817
3818 valid_p = (STRINGP (value)
3819 #ifdef HAVE_WINDOW_SYSTEM
3820 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3821 #endif /* not HAVE_WINDOW_SYSTEM */
3822 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3823
3824 if (valid_p && !display_replaced_before_p)
3825 {
3826 /* Save current settings of IT so that we can restore them
3827 when we are finished with the glyph property value. */
3828 push_it (it);
3829
3830 if (NILP (location))
3831 it->area = TEXT_AREA;
3832 else if (EQ (location, Qleft_margin))
3833 it->area = LEFT_MARGIN_AREA;
3834 else
3835 it->area = RIGHT_MARGIN_AREA;
3836
3837 if (STRINGP (value))
3838 {
3839 it->string = value;
3840 it->multibyte_p = STRING_MULTIBYTE (it->string);
3841 it->current.overlay_string_index = -1;
3842 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3843 it->end_charpos = it->string_nchars = SCHARS (it->string);
3844 it->method = GET_FROM_STRING;
3845 it->stop_charpos = 0;
3846 it->string_from_display_prop_p = 1;
3847 /* Say that we haven't consumed the characters with
3848 `display' property yet. The call to pop_it in
3849 set_iterator_to_next will clean this up. */
3850 *position = start_pos;
3851 }
3852 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3853 {
3854 it->method = GET_FROM_STRETCH;
3855 it->object = value;
3856 it->current.pos = it->position = start_pos;
3857 }
3858 #ifdef HAVE_WINDOW_SYSTEM
3859 else
3860 {
3861 it->what = IT_IMAGE;
3862 it->image_id = lookup_image (it->f, value);
3863 it->position = start_pos;
3864 it->object = NILP (object) ? it->w->buffer : object;
3865 it->method = GET_FROM_IMAGE;
3866
3867 /* Say that we haven't consumed the characters with
3868 `display' property yet. The call to pop_it in
3869 set_iterator_to_next will clean this up. */
3870 *position = start_pos;
3871 }
3872 #endif /* HAVE_WINDOW_SYSTEM */
3873
3874 return 1;
3875 }
3876
3877 /* Invalid property or property not supported. Restore
3878 POSITION to what it was before. */
3879 *position = start_pos;
3880 return 0;
3881 }
3882
3883
3884 /* Check if SPEC is a display specification value whose text should be
3885 treated as intangible. */
3886
3887 static int
3888 single_display_spec_intangible_p (prop)
3889 Lisp_Object prop;
3890 {
3891 /* Skip over `when FORM'. */
3892 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3893 {
3894 prop = XCDR (prop);
3895 if (!CONSP (prop))
3896 return 0;
3897 prop = XCDR (prop);
3898 }
3899
3900 if (STRINGP (prop))
3901 return 1;
3902
3903 if (!CONSP (prop))
3904 return 0;
3905
3906 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3907 we don't need to treat text as intangible. */
3908 if (EQ (XCAR (prop), Qmargin))
3909 {
3910 prop = XCDR (prop);
3911 if (!CONSP (prop))
3912 return 0;
3913
3914 prop = XCDR (prop);
3915 if (!CONSP (prop)
3916 || EQ (XCAR (prop), Qleft_margin)
3917 || EQ (XCAR (prop), Qright_margin))
3918 return 0;
3919 }
3920
3921 return (CONSP (prop)
3922 && (EQ (XCAR (prop), Qimage)
3923 || EQ (XCAR (prop), Qspace)));
3924 }
3925
3926
3927 /* Check if PROP is a display property value whose text should be
3928 treated as intangible. */
3929
3930 int
3931 display_prop_intangible_p (prop)
3932 Lisp_Object prop;
3933 {
3934 if (CONSP (prop)
3935 && CONSP (XCAR (prop))
3936 && !EQ (Qmargin, XCAR (XCAR (prop))))
3937 {
3938 /* A list of sub-properties. */
3939 while (CONSP (prop))
3940 {
3941 if (single_display_spec_intangible_p (XCAR (prop)))
3942 return 1;
3943 prop = XCDR (prop);
3944 }
3945 }
3946 else if (VECTORP (prop))
3947 {
3948 /* A vector of sub-properties. */
3949 int i;
3950 for (i = 0; i < ASIZE (prop); ++i)
3951 if (single_display_spec_intangible_p (AREF (prop, i)))
3952 return 1;
3953 }
3954 else
3955 return single_display_spec_intangible_p (prop);
3956
3957 return 0;
3958 }
3959
3960
3961 /* Return 1 if PROP is a display sub-property value containing STRING. */
3962
3963 static int
3964 single_display_spec_string_p (prop, string)
3965 Lisp_Object prop, string;
3966 {
3967 if (EQ (string, prop))
3968 return 1;
3969
3970 /* Skip over `when FORM'. */
3971 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3972 {
3973 prop = XCDR (prop);
3974 if (!CONSP (prop))
3975 return 0;
3976 prop = XCDR (prop);
3977 }
3978
3979 if (CONSP (prop))
3980 /* Skip over `margin LOCATION'. */
3981 if (EQ (XCAR (prop), Qmargin))
3982 {
3983 prop = XCDR (prop);
3984 if (!CONSP (prop))
3985 return 0;
3986
3987 prop = XCDR (prop);
3988 if (!CONSP (prop))
3989 return 0;
3990 }
3991
3992 return CONSP (prop) && EQ (XCAR (prop), string);
3993 }
3994
3995
3996 /* Return 1 if STRING appears in the `display' property PROP. */
3997
3998 static int
3999 display_prop_string_p (prop, string)
4000 Lisp_Object prop, string;
4001 {
4002 if (CONSP (prop)
4003 && CONSP (XCAR (prop))
4004 && !EQ (Qmargin, XCAR (XCAR (prop))))
4005 {
4006 /* A list of sub-properties. */
4007 while (CONSP (prop))
4008 {
4009 if (single_display_spec_string_p (XCAR (prop), string))
4010 return 1;
4011 prop = XCDR (prop);
4012 }
4013 }
4014 else if (VECTORP (prop))
4015 {
4016 /* A vector of sub-properties. */
4017 int i;
4018 for (i = 0; i < ASIZE (prop); ++i)
4019 if (single_display_spec_string_p (AREF (prop, i), string))
4020 return 1;
4021 }
4022 else
4023 return single_display_spec_string_p (prop, string);
4024
4025 return 0;
4026 }
4027
4028
4029 /* Determine from which buffer position in W's buffer STRING comes
4030 from. AROUND_CHARPOS is an approximate position where it could
4031 be from. Value is the buffer position or 0 if it couldn't be
4032 determined.
4033
4034 W's buffer must be current.
4035
4036 This function is necessary because we don't record buffer positions
4037 in glyphs generated from strings (to keep struct glyph small).
4038 This function may only use code that doesn't eval because it is
4039 called asynchronously from note_mouse_highlight. */
4040
4041 int
4042 string_buffer_position (w, string, around_charpos)
4043 struct window *w;
4044 Lisp_Object string;
4045 int around_charpos;
4046 {
4047 Lisp_Object limit, prop, pos;
4048 const int MAX_DISTANCE = 1000;
4049 int found = 0;
4050
4051 pos = make_number (around_charpos);
4052 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4053 while (!found && !EQ (pos, limit))
4054 {
4055 prop = Fget_char_property (pos, Qdisplay, Qnil);
4056 if (!NILP (prop) && display_prop_string_p (prop, string))
4057 found = 1;
4058 else
4059 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4060 }
4061
4062 if (!found)
4063 {
4064 pos = make_number (around_charpos);
4065 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4066 while (!found && !EQ (pos, limit))
4067 {
4068 prop = Fget_char_property (pos, Qdisplay, Qnil);
4069 if (!NILP (prop) && display_prop_string_p (prop, string))
4070 found = 1;
4071 else
4072 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4073 limit);
4074 }
4075 }
4076
4077 return found ? XINT (pos) : 0;
4078 }
4079
4080
4081 \f
4082 /***********************************************************************
4083 `composition' property
4084 ***********************************************************************/
4085
4086 /* Set up iterator IT from `composition' property at its current
4087 position. Called from handle_stop. */
4088
4089 static enum prop_handled
4090 handle_composition_prop (it)
4091 struct it *it;
4092 {
4093 Lisp_Object prop, string;
4094 int pos, pos_byte, end;
4095 enum prop_handled handled = HANDLED_NORMALLY;
4096
4097 if (STRINGP (it->string))
4098 {
4099 pos = IT_STRING_CHARPOS (*it);
4100 pos_byte = IT_STRING_BYTEPOS (*it);
4101 string = it->string;
4102 }
4103 else
4104 {
4105 pos = IT_CHARPOS (*it);
4106 pos_byte = IT_BYTEPOS (*it);
4107 string = Qnil;
4108 }
4109
4110 /* If there's a valid composition and point is not inside of the
4111 composition (in the case that the composition is from the current
4112 buffer), draw a glyph composed from the composition components. */
4113 if (find_composition (pos, -1, &pos, &end, &prop, string)
4114 && COMPOSITION_VALID_P (pos, end, prop)
4115 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4116 {
4117 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4118
4119 if (id >= 0)
4120 {
4121 it->method = GET_FROM_COMPOSITION;
4122 it->cmp_id = id;
4123 it->cmp_len = COMPOSITION_LENGTH (prop);
4124 /* For a terminal, draw only the first character of the
4125 components. */
4126 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4127 it->len = (STRINGP (it->string)
4128 ? string_char_to_byte (it->string, end)
4129 : CHAR_TO_BYTE (end)) - pos_byte;
4130 it->stop_charpos = end;
4131 handled = HANDLED_RETURN;
4132 }
4133 }
4134
4135 return handled;
4136 }
4137
4138
4139 \f
4140 /***********************************************************************
4141 Overlay strings
4142 ***********************************************************************/
4143
4144 /* The following structure is used to record overlay strings for
4145 later sorting in load_overlay_strings. */
4146
4147 struct overlay_entry
4148 {
4149 Lisp_Object overlay;
4150 Lisp_Object string;
4151 int priority;
4152 int after_string_p;
4153 };
4154
4155
4156 /* Set up iterator IT from overlay strings at its current position.
4157 Called from handle_stop. */
4158
4159 static enum prop_handled
4160 handle_overlay_change (it)
4161 struct it *it;
4162 {
4163 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4164 return HANDLED_RECOMPUTE_PROPS;
4165 else
4166 return HANDLED_NORMALLY;
4167 }
4168
4169
4170 /* Set up the next overlay string for delivery by IT, if there is an
4171 overlay string to deliver. Called by set_iterator_to_next when the
4172 end of the current overlay string is reached. If there are more
4173 overlay strings to display, IT->string and
4174 IT->current.overlay_string_index are set appropriately here.
4175 Otherwise IT->string is set to nil. */
4176
4177 static void
4178 next_overlay_string (it)
4179 struct it *it;
4180 {
4181 ++it->current.overlay_string_index;
4182 if (it->current.overlay_string_index == it->n_overlay_strings)
4183 {
4184 /* No more overlay strings. Restore IT's settings to what
4185 they were before overlay strings were processed, and
4186 continue to deliver from current_buffer. */
4187 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4188
4189 pop_it (it);
4190 xassert (it->stop_charpos >= BEGV
4191 && it->stop_charpos <= it->end_charpos);
4192 it->string = Qnil;
4193 it->current.overlay_string_index = -1;
4194 SET_TEXT_POS (it->current.string_pos, -1, -1);
4195 it->n_overlay_strings = 0;
4196 it->method = GET_FROM_BUFFER;
4197
4198 /* If we're at the end of the buffer, record that we have
4199 processed the overlay strings there already, so that
4200 next_element_from_buffer doesn't try it again. */
4201 if (IT_CHARPOS (*it) >= it->end_charpos)
4202 it->overlay_strings_at_end_processed_p = 1;
4203
4204 /* If we have to display `...' for invisible text, set
4205 the iterator up for that. */
4206 if (display_ellipsis_p)
4207 setup_for_ellipsis (it, 0);
4208 }
4209 else
4210 {
4211 /* There are more overlay strings to process. If
4212 IT->current.overlay_string_index has advanced to a position
4213 where we must load IT->overlay_strings with more strings, do
4214 it. */
4215 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4216
4217 if (it->current.overlay_string_index && i == 0)
4218 load_overlay_strings (it, 0);
4219
4220 /* Initialize IT to deliver display elements from the overlay
4221 string. */
4222 it->string = it->overlay_strings[i];
4223 it->multibyte_p = STRING_MULTIBYTE (it->string);
4224 SET_TEXT_POS (it->current.string_pos, 0, 0);
4225 it->method = GET_FROM_STRING;
4226 it->stop_charpos = 0;
4227 }
4228
4229 CHECK_IT (it);
4230 }
4231
4232
4233 /* Compare two overlay_entry structures E1 and E2. Used as a
4234 comparison function for qsort in load_overlay_strings. Overlay
4235 strings for the same position are sorted so that
4236
4237 1. All after-strings come in front of before-strings, except
4238 when they come from the same overlay.
4239
4240 2. Within after-strings, strings are sorted so that overlay strings
4241 from overlays with higher priorities come first.
4242
4243 2. Within before-strings, strings are sorted so that overlay
4244 strings from overlays with higher priorities come last.
4245
4246 Value is analogous to strcmp. */
4247
4248
4249 static int
4250 compare_overlay_entries (e1, e2)
4251 void *e1, *e2;
4252 {
4253 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4254 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4255 int result;
4256
4257 if (entry1->after_string_p != entry2->after_string_p)
4258 {
4259 /* Let after-strings appear in front of before-strings if
4260 they come from different overlays. */
4261 if (EQ (entry1->overlay, entry2->overlay))
4262 result = entry1->after_string_p ? 1 : -1;
4263 else
4264 result = entry1->after_string_p ? -1 : 1;
4265 }
4266 else if (entry1->after_string_p)
4267 /* After-strings sorted in order of decreasing priority. */
4268 result = entry2->priority - entry1->priority;
4269 else
4270 /* Before-strings sorted in order of increasing priority. */
4271 result = entry1->priority - entry2->priority;
4272
4273 return result;
4274 }
4275
4276
4277 /* Load the vector IT->overlay_strings with overlay strings from IT's
4278 current buffer position, or from CHARPOS if that is > 0. Set
4279 IT->n_overlays to the total number of overlay strings found.
4280
4281 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4282 a time. On entry into load_overlay_strings,
4283 IT->current.overlay_string_index gives the number of overlay
4284 strings that have already been loaded by previous calls to this
4285 function.
4286
4287 IT->add_overlay_start contains an additional overlay start
4288 position to consider for taking overlay strings from, if non-zero.
4289 This position comes into play when the overlay has an `invisible'
4290 property, and both before and after-strings. When we've skipped to
4291 the end of the overlay, because of its `invisible' property, we
4292 nevertheless want its before-string to appear.
4293 IT->add_overlay_start will contain the overlay start position
4294 in this case.
4295
4296 Overlay strings are sorted so that after-string strings come in
4297 front of before-string strings. Within before and after-strings,
4298 strings are sorted by overlay priority. See also function
4299 compare_overlay_entries. */
4300
4301 static void
4302 load_overlay_strings (it, charpos)
4303 struct it *it;
4304 int charpos;
4305 {
4306 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4307 Lisp_Object overlay, window, str, invisible;
4308 struct Lisp_Overlay *ov;
4309 int start, end;
4310 int size = 20;
4311 int n = 0, i, j, invis_p;
4312 struct overlay_entry *entries
4313 = (struct overlay_entry *) alloca (size * sizeof *entries);
4314
4315 if (charpos <= 0)
4316 charpos = IT_CHARPOS (*it);
4317
4318 /* Append the overlay string STRING of overlay OVERLAY to vector
4319 `entries' which has size `size' and currently contains `n'
4320 elements. AFTER_P non-zero means STRING is an after-string of
4321 OVERLAY. */
4322 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4323 do \
4324 { \
4325 Lisp_Object priority; \
4326 \
4327 if (n == size) \
4328 { \
4329 int new_size = 2 * size; \
4330 struct overlay_entry *old = entries; \
4331 entries = \
4332 (struct overlay_entry *) alloca (new_size \
4333 * sizeof *entries); \
4334 bcopy (old, entries, size * sizeof *entries); \
4335 size = new_size; \
4336 } \
4337 \
4338 entries[n].string = (STRING); \
4339 entries[n].overlay = (OVERLAY); \
4340 priority = Foverlay_get ((OVERLAY), Qpriority); \
4341 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4342 entries[n].after_string_p = (AFTER_P); \
4343 ++n; \
4344 } \
4345 while (0)
4346
4347 /* Process overlay before the overlay center. */
4348 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4349 {
4350 XSETMISC (overlay, ov);
4351 xassert (OVERLAYP (overlay));
4352 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4353 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4354
4355 if (end < charpos)
4356 break;
4357
4358 /* Skip this overlay if it doesn't start or end at IT's current
4359 position. */
4360 if (end != charpos && start != charpos)
4361 continue;
4362
4363 /* Skip this overlay if it doesn't apply to IT->w. */
4364 window = Foverlay_get (overlay, Qwindow);
4365 if (WINDOWP (window) && XWINDOW (window) != it->w)
4366 continue;
4367
4368 /* If the text ``under'' the overlay is invisible, both before-
4369 and after-strings from this overlay are visible; start and
4370 end position are indistinguishable. */
4371 invisible = Foverlay_get (overlay, Qinvisible);
4372 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4373
4374 /* If overlay has a non-empty before-string, record it. */
4375 if ((start == charpos || (end == charpos && invis_p))
4376 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4377 && SCHARS (str))
4378 RECORD_OVERLAY_STRING (overlay, str, 0);
4379
4380 /* If overlay has a non-empty after-string, record it. */
4381 if ((end == charpos || (start == charpos && invis_p))
4382 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4383 && SCHARS (str))
4384 RECORD_OVERLAY_STRING (overlay, str, 1);
4385 }
4386
4387 /* Process overlays after the overlay center. */
4388 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4389 {
4390 XSETMISC (overlay, ov);
4391 xassert (OVERLAYP (overlay));
4392 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4393 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4394
4395 if (start > charpos)
4396 break;
4397
4398 /* Skip this overlay if it doesn't start or end at IT's current
4399 position. */
4400 if (end != charpos && start != charpos)
4401 continue;
4402
4403 /* Skip this overlay if it doesn't apply to IT->w. */
4404 window = Foverlay_get (overlay, Qwindow);
4405 if (WINDOWP (window) && XWINDOW (window) != it->w)
4406 continue;
4407
4408 /* If the text ``under'' the overlay is invisible, it has a zero
4409 dimension, and both before- and after-strings apply. */
4410 invisible = Foverlay_get (overlay, Qinvisible);
4411 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4412
4413 /* If overlay has a non-empty before-string, record it. */
4414 if ((start == charpos || (end == charpos && invis_p))
4415 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4416 && SCHARS (str))
4417 RECORD_OVERLAY_STRING (overlay, str, 0);
4418
4419 /* If overlay has a non-empty after-string, record it. */
4420 if ((end == charpos || (start == charpos && invis_p))
4421 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4422 && SCHARS (str))
4423 RECORD_OVERLAY_STRING (overlay, str, 1);
4424 }
4425
4426 #undef RECORD_OVERLAY_STRING
4427
4428 /* Sort entries. */
4429 if (n > 1)
4430 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4431
4432 /* Record the total number of strings to process. */
4433 it->n_overlay_strings = n;
4434
4435 /* IT->current.overlay_string_index is the number of overlay strings
4436 that have already been consumed by IT. Copy some of the
4437 remaining overlay strings to IT->overlay_strings. */
4438 i = 0;
4439 j = it->current.overlay_string_index;
4440 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4441 it->overlay_strings[i++] = entries[j++].string;
4442
4443 CHECK_IT (it);
4444 }
4445
4446
4447 /* Get the first chunk of overlay strings at IT's current buffer
4448 position, or at CHARPOS if that is > 0. Value is non-zero if at
4449 least one overlay string was found. */
4450
4451 static int
4452 get_overlay_strings (it, charpos)
4453 struct it *it;
4454 int charpos;
4455 {
4456 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4457 process. This fills IT->overlay_strings with strings, and sets
4458 IT->n_overlay_strings to the total number of strings to process.
4459 IT->pos.overlay_string_index has to be set temporarily to zero
4460 because load_overlay_strings needs this; it must be set to -1
4461 when no overlay strings are found because a zero value would
4462 indicate a position in the first overlay string. */
4463 it->current.overlay_string_index = 0;
4464 load_overlay_strings (it, charpos);
4465
4466 /* If we found overlay strings, set up IT to deliver display
4467 elements from the first one. Otherwise set up IT to deliver
4468 from current_buffer. */
4469 if (it->n_overlay_strings)
4470 {
4471 /* Make sure we know settings in current_buffer, so that we can
4472 restore meaningful values when we're done with the overlay
4473 strings. */
4474 compute_stop_pos (it);
4475 xassert (it->face_id >= 0);
4476
4477 /* Save IT's settings. They are restored after all overlay
4478 strings have been processed. */
4479 xassert (it->sp == 0);
4480 push_it (it);
4481
4482 /* Set up IT to deliver display elements from the first overlay
4483 string. */
4484 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4485 it->string = it->overlay_strings[0];
4486 it->stop_charpos = 0;
4487 xassert (STRINGP (it->string));
4488 it->end_charpos = SCHARS (it->string);
4489 it->multibyte_p = STRING_MULTIBYTE (it->string);
4490 it->method = GET_FROM_STRING;
4491 }
4492 else
4493 {
4494 it->string = Qnil;
4495 it->current.overlay_string_index = -1;
4496 it->method = GET_FROM_BUFFER;
4497 }
4498
4499 CHECK_IT (it);
4500
4501 /* Value is non-zero if we found at least one overlay string. */
4502 return STRINGP (it->string);
4503 }
4504
4505
4506 \f
4507 /***********************************************************************
4508 Saving and restoring state
4509 ***********************************************************************/
4510
4511 /* Save current settings of IT on IT->stack. Called, for example,
4512 before setting up IT for an overlay string, to be able to restore
4513 IT's settings to what they were after the overlay string has been
4514 processed. */
4515
4516 static void
4517 push_it (it)
4518 struct it *it;
4519 {
4520 struct iterator_stack_entry *p;
4521
4522 xassert (it->sp < 2);
4523 p = it->stack + it->sp;
4524
4525 p->stop_charpos = it->stop_charpos;
4526 xassert (it->face_id >= 0);
4527 p->face_id = it->face_id;
4528 p->string = it->string;
4529 p->pos = it->current;
4530 p->end_charpos = it->end_charpos;
4531 p->string_nchars = it->string_nchars;
4532 p->area = it->area;
4533 p->multibyte_p = it->multibyte_p;
4534 p->slice = it->slice;
4535 p->space_width = it->space_width;
4536 p->font_height = it->font_height;
4537 p->voffset = it->voffset;
4538 p->string_from_display_prop_p = it->string_from_display_prop_p;
4539 p->display_ellipsis_p = 0;
4540 ++it->sp;
4541 }
4542
4543
4544 /* Restore IT's settings from IT->stack. Called, for example, when no
4545 more overlay strings must be processed, and we return to delivering
4546 display elements from a buffer, or when the end of a string from a
4547 `display' property is reached and we return to delivering display
4548 elements from an overlay string, or from a buffer. */
4549
4550 static void
4551 pop_it (it)
4552 struct it *it;
4553 {
4554 struct iterator_stack_entry *p;
4555
4556 xassert (it->sp > 0);
4557 --it->sp;
4558 p = it->stack + it->sp;
4559 it->stop_charpos = p->stop_charpos;
4560 it->face_id = p->face_id;
4561 it->string = p->string;
4562 it->current = p->pos;
4563 it->end_charpos = p->end_charpos;
4564 it->string_nchars = p->string_nchars;
4565 it->area = p->area;
4566 it->multibyte_p = p->multibyte_p;
4567 it->slice = p->slice;
4568 it->space_width = p->space_width;
4569 it->font_height = p->font_height;
4570 it->voffset = p->voffset;
4571 it->string_from_display_prop_p = p->string_from_display_prop_p;
4572 }
4573
4574
4575 \f
4576 /***********************************************************************
4577 Moving over lines
4578 ***********************************************************************/
4579
4580 /* Set IT's current position to the previous line start. */
4581
4582 static void
4583 back_to_previous_line_start (it)
4584 struct it *it;
4585 {
4586 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4587 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4588 }
4589
4590
4591 /* Move IT to the next line start.
4592
4593 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4594 we skipped over part of the text (as opposed to moving the iterator
4595 continuously over the text). Otherwise, don't change the value
4596 of *SKIPPED_P.
4597
4598 Newlines may come from buffer text, overlay strings, or strings
4599 displayed via the `display' property. That's the reason we can't
4600 simply use find_next_newline_no_quit.
4601
4602 Note that this function may not skip over invisible text that is so
4603 because of text properties and immediately follows a newline. If
4604 it would, function reseat_at_next_visible_line_start, when called
4605 from set_iterator_to_next, would effectively make invisible
4606 characters following a newline part of the wrong glyph row, which
4607 leads to wrong cursor motion. */
4608
4609 static int
4610 forward_to_next_line_start (it, skipped_p)
4611 struct it *it;
4612 int *skipped_p;
4613 {
4614 int old_selective, newline_found_p, n;
4615 const int MAX_NEWLINE_DISTANCE = 500;
4616
4617 /* If already on a newline, just consume it to avoid unintended
4618 skipping over invisible text below. */
4619 if (it->what == IT_CHARACTER
4620 && it->c == '\n'
4621 && CHARPOS (it->position) == IT_CHARPOS (*it))
4622 {
4623 set_iterator_to_next (it, 0);
4624 it->c = 0;
4625 return 1;
4626 }
4627
4628 /* Don't handle selective display in the following. It's (a)
4629 unnecessary because it's done by the caller, and (b) leads to an
4630 infinite recursion because next_element_from_ellipsis indirectly
4631 calls this function. */
4632 old_selective = it->selective;
4633 it->selective = 0;
4634
4635 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4636 from buffer text. */
4637 for (n = newline_found_p = 0;
4638 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4639 n += STRINGP (it->string) ? 0 : 1)
4640 {
4641 if (!get_next_display_element (it))
4642 return 0;
4643 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4644 set_iterator_to_next (it, 0);
4645 }
4646
4647 /* If we didn't find a newline near enough, see if we can use a
4648 short-cut. */
4649 if (!newline_found_p)
4650 {
4651 int start = IT_CHARPOS (*it);
4652 int limit = find_next_newline_no_quit (start, 1);
4653 Lisp_Object pos;
4654
4655 xassert (!STRINGP (it->string));
4656
4657 /* If there isn't any `display' property in sight, and no
4658 overlays, we can just use the position of the newline in
4659 buffer text. */
4660 if (it->stop_charpos >= limit
4661 || ((pos = Fnext_single_property_change (make_number (start),
4662 Qdisplay,
4663 Qnil, make_number (limit)),
4664 NILP (pos))
4665 && next_overlay_change (start) == ZV))
4666 {
4667 IT_CHARPOS (*it) = limit;
4668 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4669 *skipped_p = newline_found_p = 1;
4670 }
4671 else
4672 {
4673 while (get_next_display_element (it)
4674 && !newline_found_p)
4675 {
4676 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4677 set_iterator_to_next (it, 0);
4678 }
4679 }
4680 }
4681
4682 it->selective = old_selective;
4683 return newline_found_p;
4684 }
4685
4686
4687 /* Set IT's current position to the previous visible line start. Skip
4688 invisible text that is so either due to text properties or due to
4689 selective display. Caution: this does not change IT->current_x and
4690 IT->hpos. */
4691
4692 static void
4693 back_to_previous_visible_line_start (it)
4694 struct it *it;
4695 {
4696 while (IT_CHARPOS (*it) > BEGV)
4697 {
4698 back_to_previous_line_start (it);
4699 if (IT_CHARPOS (*it) <= BEGV)
4700 break;
4701
4702 /* If selective > 0, then lines indented more than that values
4703 are invisible. */
4704 if (it->selective > 0
4705 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4706 (double) it->selective)) /* iftc */
4707 continue;
4708
4709 /* Check the newline before point for invisibility. */
4710 {
4711 Lisp_Object prop;
4712 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4713 Qinvisible, it->window);
4714 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4715 continue;
4716 }
4717
4718 /* If newline has a display property that replaces the newline with something
4719 else (image or text), find start of overlay or interval and continue search
4720 from that point. */
4721 if (IT_CHARPOS (*it) > BEGV)
4722 {
4723 struct it it2 = *it;
4724 int pos;
4725 int beg, end;
4726 Lisp_Object val, overlay;
4727
4728 pos = --IT_CHARPOS (it2);
4729 --IT_BYTEPOS (it2);
4730 it2.sp = 0;
4731 if (handle_display_prop (&it2) == HANDLED_RETURN
4732 && !NILP (val = get_char_property_and_overlay
4733 (make_number (pos), Qdisplay, Qnil, &overlay))
4734 && (OVERLAYP (overlay)
4735 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
4736 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
4737 {
4738 if (beg < BEGV)
4739 beg = BEGV;
4740 IT_CHARPOS (*it) = beg;
4741 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
4742 continue;
4743 }
4744 }
4745
4746 break;
4747 }
4748
4749 xassert (IT_CHARPOS (*it) >= BEGV);
4750 xassert (IT_CHARPOS (*it) == BEGV
4751 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4752 CHECK_IT (it);
4753 }
4754
4755
4756 /* Reseat iterator IT at the previous visible line start. Skip
4757 invisible text that is so either due to text properties or due to
4758 selective display. At the end, update IT's overlay information,
4759 face information etc. */
4760
4761 void
4762 reseat_at_previous_visible_line_start (it)
4763 struct it *it;
4764 {
4765 back_to_previous_visible_line_start (it);
4766 reseat (it, it->current.pos, 1);
4767 CHECK_IT (it);
4768 }
4769
4770
4771 /* Reseat iterator IT on the next visible line start in the current
4772 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4773 preceding the line start. Skip over invisible text that is so
4774 because of selective display. Compute faces, overlays etc at the
4775 new position. Note that this function does not skip over text that
4776 is invisible because of text properties. */
4777
4778 static void
4779 reseat_at_next_visible_line_start (it, on_newline_p)
4780 struct it *it;
4781 int on_newline_p;
4782 {
4783 int newline_found_p, skipped_p = 0;
4784
4785 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4786
4787 /* Skip over lines that are invisible because they are indented
4788 more than the value of IT->selective. */
4789 if (it->selective > 0)
4790 while (IT_CHARPOS (*it) < ZV
4791 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4792 (double) it->selective)) /* iftc */
4793 {
4794 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4795 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4796 }
4797
4798 /* Position on the newline if that's what's requested. */
4799 if (on_newline_p && newline_found_p)
4800 {
4801 if (STRINGP (it->string))
4802 {
4803 if (IT_STRING_CHARPOS (*it) > 0)
4804 {
4805 --IT_STRING_CHARPOS (*it);
4806 --IT_STRING_BYTEPOS (*it);
4807 }
4808 }
4809 else if (IT_CHARPOS (*it) > BEGV)
4810 {
4811 --IT_CHARPOS (*it);
4812 --IT_BYTEPOS (*it);
4813 reseat (it, it->current.pos, 0);
4814 }
4815 }
4816 else if (skipped_p)
4817 reseat (it, it->current.pos, 0);
4818
4819 CHECK_IT (it);
4820 }
4821
4822
4823 \f
4824 /***********************************************************************
4825 Changing an iterator's position
4826 ***********************************************************************/
4827
4828 /* Change IT's current position to POS in current_buffer. If FORCE_P
4829 is non-zero, always check for text properties at the new position.
4830 Otherwise, text properties are only looked up if POS >=
4831 IT->check_charpos of a property. */
4832
4833 static void
4834 reseat (it, pos, force_p)
4835 struct it *it;
4836 struct text_pos pos;
4837 int force_p;
4838 {
4839 int original_pos = IT_CHARPOS (*it);
4840
4841 reseat_1 (it, pos, 0);
4842
4843 /* Determine where to check text properties. Avoid doing it
4844 where possible because text property lookup is very expensive. */
4845 if (force_p
4846 || CHARPOS (pos) > it->stop_charpos
4847 || CHARPOS (pos) < original_pos)
4848 handle_stop (it);
4849
4850 CHECK_IT (it);
4851 }
4852
4853
4854 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4855 IT->stop_pos to POS, also. */
4856
4857 static void
4858 reseat_1 (it, pos, set_stop_p)
4859 struct it *it;
4860 struct text_pos pos;
4861 int set_stop_p;
4862 {
4863 /* Don't call this function when scanning a C string. */
4864 xassert (it->s == NULL);
4865
4866 /* POS must be a reasonable value. */
4867 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4868
4869 it->current.pos = it->position = pos;
4870 XSETBUFFER (it->object, current_buffer);
4871 it->end_charpos = ZV;
4872 it->dpvec = NULL;
4873 it->current.dpvec_index = -1;
4874 it->current.overlay_string_index = -1;
4875 IT_STRING_CHARPOS (*it) = -1;
4876 IT_STRING_BYTEPOS (*it) = -1;
4877 it->string = Qnil;
4878 it->method = GET_FROM_BUFFER;
4879 /* RMS: I added this to fix a bug in move_it_vertically_backward
4880 where it->area continued to relate to the starting point
4881 for the backward motion. Bug report from
4882 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4883 However, I am not sure whether reseat still does the right thing
4884 in general after this change. */
4885 it->area = TEXT_AREA;
4886 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4887 it->sp = 0;
4888 it->face_before_selective_p = 0;
4889
4890 if (set_stop_p)
4891 it->stop_charpos = CHARPOS (pos);
4892 }
4893
4894
4895 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4896 If S is non-null, it is a C string to iterate over. Otherwise,
4897 STRING gives a Lisp string to iterate over.
4898
4899 If PRECISION > 0, don't return more then PRECISION number of
4900 characters from the string.
4901
4902 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4903 characters have been returned. FIELD_WIDTH < 0 means an infinite
4904 field width.
4905
4906 MULTIBYTE = 0 means disable processing of multibyte characters,
4907 MULTIBYTE > 0 means enable it,
4908 MULTIBYTE < 0 means use IT->multibyte_p.
4909
4910 IT must be initialized via a prior call to init_iterator before
4911 calling this function. */
4912
4913 static void
4914 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4915 struct it *it;
4916 unsigned char *s;
4917 Lisp_Object string;
4918 int charpos;
4919 int precision, field_width, multibyte;
4920 {
4921 /* No region in strings. */
4922 it->region_beg_charpos = it->region_end_charpos = -1;
4923
4924 /* No text property checks performed by default, but see below. */
4925 it->stop_charpos = -1;
4926
4927 /* Set iterator position and end position. */
4928 bzero (&it->current, sizeof it->current);
4929 it->current.overlay_string_index = -1;
4930 it->current.dpvec_index = -1;
4931 xassert (charpos >= 0);
4932
4933 /* If STRING is specified, use its multibyteness, otherwise use the
4934 setting of MULTIBYTE, if specified. */
4935 if (multibyte >= 0)
4936 it->multibyte_p = multibyte > 0;
4937
4938 if (s == NULL)
4939 {
4940 xassert (STRINGP (string));
4941 it->string = string;
4942 it->s = NULL;
4943 it->end_charpos = it->string_nchars = SCHARS (string);
4944 it->method = GET_FROM_STRING;
4945 it->current.string_pos = string_pos (charpos, string);
4946 }
4947 else
4948 {
4949 it->s = s;
4950 it->string = Qnil;
4951
4952 /* Note that we use IT->current.pos, not it->current.string_pos,
4953 for displaying C strings. */
4954 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4955 if (it->multibyte_p)
4956 {
4957 it->current.pos = c_string_pos (charpos, s, 1);
4958 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4959 }
4960 else
4961 {
4962 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4963 it->end_charpos = it->string_nchars = strlen (s);
4964 }
4965
4966 it->method = GET_FROM_C_STRING;
4967 }
4968
4969 /* PRECISION > 0 means don't return more than PRECISION characters
4970 from the string. */
4971 if (precision > 0 && it->end_charpos - charpos > precision)
4972 it->end_charpos = it->string_nchars = charpos + precision;
4973
4974 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4975 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4976 FIELD_WIDTH < 0 means infinite field width. This is useful for
4977 padding with `-' at the end of a mode line. */
4978 if (field_width < 0)
4979 field_width = INFINITY;
4980 if (field_width > it->end_charpos - charpos)
4981 it->end_charpos = charpos + field_width;
4982
4983 /* Use the standard display table for displaying strings. */
4984 if (DISP_TABLE_P (Vstandard_display_table))
4985 it->dp = XCHAR_TABLE (Vstandard_display_table);
4986
4987 it->stop_charpos = charpos;
4988 CHECK_IT (it);
4989 }
4990
4991
4992 \f
4993 /***********************************************************************
4994 Iteration
4995 ***********************************************************************/
4996
4997 /* Map enum it_method value to corresponding next_element_from_* function. */
4998
4999 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5000 {
5001 next_element_from_buffer,
5002 next_element_from_display_vector,
5003 next_element_from_composition,
5004 next_element_from_string,
5005 next_element_from_c_string,
5006 next_element_from_image,
5007 next_element_from_stretch
5008 };
5009
5010
5011 /* Load IT's display element fields with information about the next
5012 display element from the current position of IT. Value is zero if
5013 end of buffer (or C string) is reached. */
5014
5015 int
5016 get_next_display_element (it)
5017 struct it *it;
5018 {
5019 /* Non-zero means that we found a display element. Zero means that
5020 we hit the end of what we iterate over. Performance note: the
5021 function pointer `method' used here turns out to be faster than
5022 using a sequence of if-statements. */
5023 int success_p;
5024
5025 get_next:
5026 success_p = (*get_next_element[it->method]) (it);
5027
5028 if (it->what == IT_CHARACTER)
5029 {
5030 /* Map via display table or translate control characters.
5031 IT->c, IT->len etc. have been set to the next character by
5032 the function call above. If we have a display table, and it
5033 contains an entry for IT->c, translate it. Don't do this if
5034 IT->c itself comes from a display table, otherwise we could
5035 end up in an infinite recursion. (An alternative could be to
5036 count the recursion depth of this function and signal an
5037 error when a certain maximum depth is reached.) Is it worth
5038 it? */
5039 if (success_p && it->dpvec == NULL)
5040 {
5041 Lisp_Object dv;
5042
5043 if (it->dp
5044 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5045 VECTORP (dv)))
5046 {
5047 struct Lisp_Vector *v = XVECTOR (dv);
5048
5049 /* Return the first character from the display table
5050 entry, if not empty. If empty, don't display the
5051 current character. */
5052 if (v->size)
5053 {
5054 it->dpvec_char_len = it->len;
5055 it->dpvec = v->contents;
5056 it->dpend = v->contents + v->size;
5057 it->current.dpvec_index = 0;
5058 it->dpvec_face_id = -1;
5059 it->saved_face_id = it->face_id;
5060 it->method = GET_FROM_DISPLAY_VECTOR;
5061 it->ellipsis_p = 0;
5062 }
5063 else
5064 {
5065 set_iterator_to_next (it, 0);
5066 }
5067 goto get_next;
5068 }
5069
5070 /* Translate control characters into `\003' or `^C' form.
5071 Control characters coming from a display table entry are
5072 currently not translated because we use IT->dpvec to hold
5073 the translation. This could easily be changed but I
5074 don't believe that it is worth doing.
5075
5076 If it->multibyte_p is nonzero, eight-bit characters and
5077 non-printable multibyte characters are also translated to
5078 octal form.
5079
5080 If it->multibyte_p is zero, eight-bit characters that
5081 don't have corresponding multibyte char code are also
5082 translated to octal form. */
5083 else if ((it->c < ' '
5084 && (it->area != TEXT_AREA
5085 /* In mode line, treat \n like other crl chars. */
5086 || (it->c != '\t'
5087 && it->glyph_row && it->glyph_row->mode_line_p)
5088 || (it->c != '\n' && it->c != '\t')))
5089 || (it->multibyte_p
5090 ? ((it->c >= 127
5091 && it->len == 1)
5092 || !CHAR_PRINTABLE_P (it->c)
5093 || (!NILP (Vshow_nonbreak_escape)
5094 && (it->c == 0x8ad || it->c == 0x8a0
5095 || it->c == 0xf2d || it->c == 0xf20)))
5096 : (it->c >= 127
5097 && (!unibyte_display_via_language_environment
5098 || it->c == unibyte_char_to_multibyte (it->c)))))
5099 {
5100 /* IT->c is a control character which must be displayed
5101 either as '\003' or as `^C' where the '\\' and '^'
5102 can be defined in the display table. Fill
5103 IT->ctl_chars with glyphs for what we have to
5104 display. Then, set IT->dpvec to these glyphs. */
5105 GLYPH g;
5106 int ctl_len;
5107 int face_id, lface_id = 0 ;
5108 GLYPH escape_glyph;
5109
5110 if (it->c < 128 && it->ctl_arrow_p)
5111 {
5112 g = '^'; /* default glyph for Control */
5113 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5114 if (it->dp
5115 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5116 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5117 {
5118 g = XINT (DISP_CTRL_GLYPH (it->dp));
5119 lface_id = FAST_GLYPH_FACE (g);
5120 }
5121 if (lface_id)
5122 {
5123 g = FAST_GLYPH_CHAR (g);
5124 face_id = merge_faces (it->f, Qt, lface_id,
5125 it->face_id);
5126 }
5127 else
5128 {
5129 /* Merge the escape-glyph face into the current face. */
5130 face_id = merge_faces (it->f, Qescape_glyph, 0,
5131 it->face_id);
5132 }
5133
5134 XSETINT (it->ctl_chars[0], g);
5135 g = it->c ^ 0100;
5136 XSETINT (it->ctl_chars[1], g);
5137 ctl_len = 2;
5138 goto display_control;
5139 }
5140
5141 escape_glyph = '\\'; /* default for Octal display */
5142 if (it->dp
5143 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5144 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5145 {
5146 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5147 lface_id = FAST_GLYPH_FACE (escape_glyph);
5148 }
5149 if (lface_id)
5150 {
5151 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5152 face_id = merge_faces (it->f, Qt, lface_id,
5153 it->face_id);
5154 }
5155 else
5156 {
5157 /* Merge the escape-glyph face into the current face. */
5158 face_id = merge_faces (it->f, Qescape_glyph, 0,
5159 it->face_id);
5160 }
5161
5162 if (it->c == 0x8a0 || it->c == 0x8ad
5163 || it->c == 0xf20 || it->c == 0xf2d)
5164 {
5165 XSETINT (it->ctl_chars[0], escape_glyph);
5166 g = it->c;
5167 XSETINT (it->ctl_chars[1], g);
5168 ctl_len = 2;
5169 goto display_control;
5170 }
5171
5172 {
5173 unsigned char str[MAX_MULTIBYTE_LENGTH];
5174 int len;
5175 int i;
5176
5177 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5178 if (SINGLE_BYTE_CHAR_P (it->c))
5179 str[0] = it->c, len = 1;
5180 else
5181 {
5182 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5183 if (len < 0)
5184 {
5185 /* It's an invalid character, which shouldn't
5186 happen actually, but due to bugs it may
5187 happen. Let's print the char as is, there's
5188 not much meaningful we can do with it. */
5189 str[0] = it->c;
5190 str[1] = it->c >> 8;
5191 str[2] = it->c >> 16;
5192 str[3] = it->c >> 24;
5193 len = 4;
5194 }
5195 }
5196
5197 for (i = 0; i < len; i++)
5198 {
5199 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5200 /* Insert three more glyphs into IT->ctl_chars for
5201 the octal display of the character. */
5202 g = ((str[i] >> 6) & 7) + '0';
5203 XSETINT (it->ctl_chars[i * 4 + 1], g);
5204 g = ((str[i] >> 3) & 7) + '0';
5205 XSETINT (it->ctl_chars[i * 4 + 2], g);
5206 g = (str[i] & 7) + '0';
5207 XSETINT (it->ctl_chars[i * 4 + 3], g);
5208 }
5209 ctl_len = len * 4;
5210 }
5211
5212 display_control:
5213 /* Set up IT->dpvec and return first character from it. */
5214 it->dpvec_char_len = it->len;
5215 it->dpvec = it->ctl_chars;
5216 it->dpend = it->dpvec + ctl_len;
5217 it->current.dpvec_index = 0;
5218 it->dpvec_face_id = face_id;
5219 it->saved_face_id = it->face_id;
5220 it->method = GET_FROM_DISPLAY_VECTOR;
5221 it->ellipsis_p = 0;
5222 goto get_next;
5223 }
5224 }
5225
5226 /* Adjust face id for a multibyte character. There are no
5227 multibyte character in unibyte text. */
5228 if (it->multibyte_p
5229 && success_p
5230 && FRAME_WINDOW_P (it->f))
5231 {
5232 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5233 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5234 }
5235 }
5236
5237 /* Is this character the last one of a run of characters with
5238 box? If yes, set IT->end_of_box_run_p to 1. */
5239 if (it->face_box_p
5240 && it->s == NULL)
5241 {
5242 int face_id;
5243 struct face *face;
5244
5245 it->end_of_box_run_p
5246 = ((face_id = face_after_it_pos (it),
5247 face_id != it->face_id)
5248 && (face = FACE_FROM_ID (it->f, face_id),
5249 face->box == FACE_NO_BOX));
5250 }
5251
5252 /* Value is 0 if end of buffer or string reached. */
5253 return success_p;
5254 }
5255
5256
5257 /* Move IT to the next display element.
5258
5259 RESEAT_P non-zero means if called on a newline in buffer text,
5260 skip to the next visible line start.
5261
5262 Functions get_next_display_element and set_iterator_to_next are
5263 separate because I find this arrangement easier to handle than a
5264 get_next_display_element function that also increments IT's
5265 position. The way it is we can first look at an iterator's current
5266 display element, decide whether it fits on a line, and if it does,
5267 increment the iterator position. The other way around we probably
5268 would either need a flag indicating whether the iterator has to be
5269 incremented the next time, or we would have to implement a
5270 decrement position function which would not be easy to write. */
5271
5272 void
5273 set_iterator_to_next (it, reseat_p)
5274 struct it *it;
5275 int reseat_p;
5276 {
5277 /* Reset flags indicating start and end of a sequence of characters
5278 with box. Reset them at the start of this function because
5279 moving the iterator to a new position might set them. */
5280 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5281
5282 switch (it->method)
5283 {
5284 case GET_FROM_BUFFER:
5285 /* The current display element of IT is a character from
5286 current_buffer. Advance in the buffer, and maybe skip over
5287 invisible lines that are so because of selective display. */
5288 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5289 reseat_at_next_visible_line_start (it, 0);
5290 else
5291 {
5292 xassert (it->len != 0);
5293 IT_BYTEPOS (*it) += it->len;
5294 IT_CHARPOS (*it) += 1;
5295 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5296 }
5297 break;
5298
5299 case GET_FROM_COMPOSITION:
5300 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5301 if (STRINGP (it->string))
5302 {
5303 IT_STRING_BYTEPOS (*it) += it->len;
5304 IT_STRING_CHARPOS (*it) += it->cmp_len;
5305 it->method = GET_FROM_STRING;
5306 goto consider_string_end;
5307 }
5308 else
5309 {
5310 IT_BYTEPOS (*it) += it->len;
5311 IT_CHARPOS (*it) += it->cmp_len;
5312 it->method = GET_FROM_BUFFER;
5313 }
5314 break;
5315
5316 case GET_FROM_C_STRING:
5317 /* Current display element of IT is from a C string. */
5318 IT_BYTEPOS (*it) += it->len;
5319 IT_CHARPOS (*it) += 1;
5320 break;
5321
5322 case GET_FROM_DISPLAY_VECTOR:
5323 /* Current display element of IT is from a display table entry.
5324 Advance in the display table definition. Reset it to null if
5325 end reached, and continue with characters from buffers/
5326 strings. */
5327 ++it->current.dpvec_index;
5328
5329 /* Restore face of the iterator to what they were before the
5330 display vector entry (these entries may contain faces). */
5331 it->face_id = it->saved_face_id;
5332
5333 if (it->dpvec + it->current.dpvec_index == it->dpend)
5334 {
5335 if (it->s)
5336 it->method = GET_FROM_C_STRING;
5337 else if (STRINGP (it->string))
5338 it->method = GET_FROM_STRING;
5339 else
5340 it->method = GET_FROM_BUFFER;
5341
5342 it->dpvec = NULL;
5343 it->current.dpvec_index = -1;
5344
5345 /* Skip over characters which were displayed via IT->dpvec. */
5346 if (it->dpvec_char_len < 0)
5347 reseat_at_next_visible_line_start (it, 1);
5348 else if (it->dpvec_char_len > 0)
5349 {
5350 it->len = it->dpvec_char_len;
5351 set_iterator_to_next (it, reseat_p);
5352 }
5353
5354 /* Recheck faces after display vector */
5355 it->stop_charpos = IT_CHARPOS (*it);
5356 }
5357 break;
5358
5359 case GET_FROM_STRING:
5360 /* Current display element is a character from a Lisp string. */
5361 xassert (it->s == NULL && STRINGP (it->string));
5362 IT_STRING_BYTEPOS (*it) += it->len;
5363 IT_STRING_CHARPOS (*it) += 1;
5364
5365 consider_string_end:
5366
5367 if (it->current.overlay_string_index >= 0)
5368 {
5369 /* IT->string is an overlay string. Advance to the
5370 next, if there is one. */
5371 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5372 next_overlay_string (it);
5373 }
5374 else
5375 {
5376 /* IT->string is not an overlay string. If we reached
5377 its end, and there is something on IT->stack, proceed
5378 with what is on the stack. This can be either another
5379 string, this time an overlay string, or a buffer. */
5380 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5381 && it->sp > 0)
5382 {
5383 pop_it (it);
5384 if (STRINGP (it->string))
5385 goto consider_string_end;
5386 it->method = GET_FROM_BUFFER;
5387 }
5388 }
5389 break;
5390
5391 case GET_FROM_IMAGE:
5392 case GET_FROM_STRETCH:
5393 /* The position etc with which we have to proceed are on
5394 the stack. The position may be at the end of a string,
5395 if the `display' property takes up the whole string. */
5396 xassert (it->sp > 0);
5397 pop_it (it);
5398 it->image_id = 0;
5399 if (STRINGP (it->string))
5400 {
5401 it->method = GET_FROM_STRING;
5402 goto consider_string_end;
5403 }
5404 it->method = GET_FROM_BUFFER;
5405 break;
5406
5407 default:
5408 /* There are no other methods defined, so this should be a bug. */
5409 abort ();
5410 }
5411
5412 xassert (it->method != GET_FROM_STRING
5413 || (STRINGP (it->string)
5414 && IT_STRING_CHARPOS (*it) >= 0));
5415 }
5416
5417 /* Load IT's display element fields with information about the next
5418 display element which comes from a display table entry or from the
5419 result of translating a control character to one of the forms `^C'
5420 or `\003'.
5421
5422 IT->dpvec holds the glyphs to return as characters.
5423 IT->saved_face_id holds the face id before the display vector--
5424 it is restored into IT->face_idin set_iterator_to_next. */
5425
5426 static int
5427 next_element_from_display_vector (it)
5428 struct it *it;
5429 {
5430 /* Precondition. */
5431 xassert (it->dpvec && it->current.dpvec_index >= 0);
5432
5433 it->face_id = it->saved_face_id;
5434
5435 if (INTEGERP (*it->dpvec)
5436 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5437 {
5438 GLYPH g;
5439
5440 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5441 it->c = FAST_GLYPH_CHAR (g);
5442 it->len = CHAR_BYTES (it->c);
5443
5444 /* The entry may contain a face id to use. Such a face id is
5445 the id of a Lisp face, not a realized face. A face id of
5446 zero means no face is specified. */
5447 if (it->dpvec_face_id >= 0)
5448 it->face_id = it->dpvec_face_id;
5449 else
5450 {
5451 int lface_id = FAST_GLYPH_FACE (g);
5452 if (lface_id > 0)
5453 it->face_id = merge_faces (it->f, Qt, lface_id,
5454 it->saved_face_id);
5455 }
5456 }
5457 else
5458 /* Display table entry is invalid. Return a space. */
5459 it->c = ' ', it->len = 1;
5460
5461 /* Don't change position and object of the iterator here. They are
5462 still the values of the character that had this display table
5463 entry or was translated, and that's what we want. */
5464 it->what = IT_CHARACTER;
5465 return 1;
5466 }
5467
5468
5469 /* Load IT with the next display element from Lisp string IT->string.
5470 IT->current.string_pos is the current position within the string.
5471 If IT->current.overlay_string_index >= 0, the Lisp string is an
5472 overlay string. */
5473
5474 static int
5475 next_element_from_string (it)
5476 struct it *it;
5477 {
5478 struct text_pos position;
5479
5480 xassert (STRINGP (it->string));
5481 xassert (IT_STRING_CHARPOS (*it) >= 0);
5482 position = it->current.string_pos;
5483
5484 /* Time to check for invisible text? */
5485 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5486 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5487 {
5488 handle_stop (it);
5489
5490 /* Since a handler may have changed IT->method, we must
5491 recurse here. */
5492 return get_next_display_element (it);
5493 }
5494
5495 if (it->current.overlay_string_index >= 0)
5496 {
5497 /* Get the next character from an overlay string. In overlay
5498 strings, There is no field width or padding with spaces to
5499 do. */
5500 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5501 {
5502 it->what = IT_EOB;
5503 return 0;
5504 }
5505 else if (STRING_MULTIBYTE (it->string))
5506 {
5507 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5508 const unsigned char *s = (SDATA (it->string)
5509 + IT_STRING_BYTEPOS (*it));
5510 it->c = string_char_and_length (s, remaining, &it->len);
5511 }
5512 else
5513 {
5514 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5515 it->len = 1;
5516 }
5517 }
5518 else
5519 {
5520 /* Get the next character from a Lisp string that is not an
5521 overlay string. Such strings come from the mode line, for
5522 example. We may have to pad with spaces, or truncate the
5523 string. See also next_element_from_c_string. */
5524 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5525 {
5526 it->what = IT_EOB;
5527 return 0;
5528 }
5529 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5530 {
5531 /* Pad with spaces. */
5532 it->c = ' ', it->len = 1;
5533 CHARPOS (position) = BYTEPOS (position) = -1;
5534 }
5535 else if (STRING_MULTIBYTE (it->string))
5536 {
5537 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5538 const unsigned char *s = (SDATA (it->string)
5539 + IT_STRING_BYTEPOS (*it));
5540 it->c = string_char_and_length (s, maxlen, &it->len);
5541 }
5542 else
5543 {
5544 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5545 it->len = 1;
5546 }
5547 }
5548
5549 /* Record what we have and where it came from. Note that we store a
5550 buffer position in IT->position although it could arguably be a
5551 string position. */
5552 it->what = IT_CHARACTER;
5553 it->object = it->string;
5554 it->position = position;
5555 return 1;
5556 }
5557
5558
5559 /* Load IT with next display element from C string IT->s.
5560 IT->string_nchars is the maximum number of characters to return
5561 from the string. IT->end_charpos may be greater than
5562 IT->string_nchars when this function is called, in which case we
5563 may have to return padding spaces. Value is zero if end of string
5564 reached, including padding spaces. */
5565
5566 static int
5567 next_element_from_c_string (it)
5568 struct it *it;
5569 {
5570 int success_p = 1;
5571
5572 xassert (it->s);
5573 it->what = IT_CHARACTER;
5574 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5575 it->object = Qnil;
5576
5577 /* IT's position can be greater IT->string_nchars in case a field
5578 width or precision has been specified when the iterator was
5579 initialized. */
5580 if (IT_CHARPOS (*it) >= it->end_charpos)
5581 {
5582 /* End of the game. */
5583 it->what = IT_EOB;
5584 success_p = 0;
5585 }
5586 else if (IT_CHARPOS (*it) >= it->string_nchars)
5587 {
5588 /* Pad with spaces. */
5589 it->c = ' ', it->len = 1;
5590 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5591 }
5592 else if (it->multibyte_p)
5593 {
5594 /* Implementation note: The calls to strlen apparently aren't a
5595 performance problem because there is no noticeable performance
5596 difference between Emacs running in unibyte or multibyte mode. */
5597 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5598 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5599 maxlen, &it->len);
5600 }
5601 else
5602 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5603
5604 return success_p;
5605 }
5606
5607
5608 /* Set up IT to return characters from an ellipsis, if appropriate.
5609 The definition of the ellipsis glyphs may come from a display table
5610 entry. This function Fills IT with the first glyph from the
5611 ellipsis if an ellipsis is to be displayed. */
5612
5613 static int
5614 next_element_from_ellipsis (it)
5615 struct it *it;
5616 {
5617 if (it->selective_display_ellipsis_p)
5618 setup_for_ellipsis (it, it->len);
5619 else
5620 {
5621 /* The face at the current position may be different from the
5622 face we find after the invisible text. Remember what it
5623 was in IT->saved_face_id, and signal that it's there by
5624 setting face_before_selective_p. */
5625 it->saved_face_id = it->face_id;
5626 it->method = GET_FROM_BUFFER;
5627 reseat_at_next_visible_line_start (it, 1);
5628 it->face_before_selective_p = 1;
5629 }
5630
5631 return get_next_display_element (it);
5632 }
5633
5634
5635 /* Deliver an image display element. The iterator IT is already
5636 filled with image information (done in handle_display_prop). Value
5637 is always 1. */
5638
5639
5640 static int
5641 next_element_from_image (it)
5642 struct it *it;
5643 {
5644 it->what = IT_IMAGE;
5645 return 1;
5646 }
5647
5648
5649 /* Fill iterator IT with next display element from a stretch glyph
5650 property. IT->object is the value of the text property. Value is
5651 always 1. */
5652
5653 static int
5654 next_element_from_stretch (it)
5655 struct it *it;
5656 {
5657 it->what = IT_STRETCH;
5658 return 1;
5659 }
5660
5661
5662 /* Load IT with the next display element from current_buffer. Value
5663 is zero if end of buffer reached. IT->stop_charpos is the next
5664 position at which to stop and check for text properties or buffer
5665 end. */
5666
5667 static int
5668 next_element_from_buffer (it)
5669 struct it *it;
5670 {
5671 int success_p = 1;
5672
5673 /* Check this assumption, otherwise, we would never enter the
5674 if-statement, below. */
5675 xassert (IT_CHARPOS (*it) >= BEGV
5676 && IT_CHARPOS (*it) <= it->stop_charpos);
5677
5678 if (IT_CHARPOS (*it) >= it->stop_charpos)
5679 {
5680 if (IT_CHARPOS (*it) >= it->end_charpos)
5681 {
5682 int overlay_strings_follow_p;
5683
5684 /* End of the game, except when overlay strings follow that
5685 haven't been returned yet. */
5686 if (it->overlay_strings_at_end_processed_p)
5687 overlay_strings_follow_p = 0;
5688 else
5689 {
5690 it->overlay_strings_at_end_processed_p = 1;
5691 overlay_strings_follow_p = get_overlay_strings (it, 0);
5692 }
5693
5694 if (overlay_strings_follow_p)
5695 success_p = get_next_display_element (it);
5696 else
5697 {
5698 it->what = IT_EOB;
5699 it->position = it->current.pos;
5700 success_p = 0;
5701 }
5702 }
5703 else
5704 {
5705 handle_stop (it);
5706 return get_next_display_element (it);
5707 }
5708 }
5709 else
5710 {
5711 /* No face changes, overlays etc. in sight, so just return a
5712 character from current_buffer. */
5713 unsigned char *p;
5714
5715 /* Maybe run the redisplay end trigger hook. Performance note:
5716 This doesn't seem to cost measurable time. */
5717 if (it->redisplay_end_trigger_charpos
5718 && it->glyph_row
5719 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5720 run_redisplay_end_trigger_hook (it);
5721
5722 /* Get the next character, maybe multibyte. */
5723 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5724 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5725 {
5726 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5727 - IT_BYTEPOS (*it));
5728 it->c = string_char_and_length (p, maxlen, &it->len);
5729 }
5730 else
5731 it->c = *p, it->len = 1;
5732
5733 /* Record what we have and where it came from. */
5734 it->what = IT_CHARACTER;;
5735 it->object = it->w->buffer;
5736 it->position = it->current.pos;
5737
5738 /* Normally we return the character found above, except when we
5739 really want to return an ellipsis for selective display. */
5740 if (it->selective)
5741 {
5742 if (it->c == '\n')
5743 {
5744 /* A value of selective > 0 means hide lines indented more
5745 than that number of columns. */
5746 if (it->selective > 0
5747 && IT_CHARPOS (*it) + 1 < ZV
5748 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5749 IT_BYTEPOS (*it) + 1,
5750 (double) it->selective)) /* iftc */
5751 {
5752 success_p = next_element_from_ellipsis (it);
5753 it->dpvec_char_len = -1;
5754 }
5755 }
5756 else if (it->c == '\r' && it->selective == -1)
5757 {
5758 /* A value of selective == -1 means that everything from the
5759 CR to the end of the line is invisible, with maybe an
5760 ellipsis displayed for it. */
5761 success_p = next_element_from_ellipsis (it);
5762 it->dpvec_char_len = -1;
5763 }
5764 }
5765 }
5766
5767 /* Value is zero if end of buffer reached. */
5768 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5769 return success_p;
5770 }
5771
5772
5773 /* Run the redisplay end trigger hook for IT. */
5774
5775 static void
5776 run_redisplay_end_trigger_hook (it)
5777 struct it *it;
5778 {
5779 Lisp_Object args[3];
5780
5781 /* IT->glyph_row should be non-null, i.e. we should be actually
5782 displaying something, or otherwise we should not run the hook. */
5783 xassert (it->glyph_row);
5784
5785 /* Set up hook arguments. */
5786 args[0] = Qredisplay_end_trigger_functions;
5787 args[1] = it->window;
5788 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5789 it->redisplay_end_trigger_charpos = 0;
5790
5791 /* Since we are *trying* to run these functions, don't try to run
5792 them again, even if they get an error. */
5793 it->w->redisplay_end_trigger = Qnil;
5794 Frun_hook_with_args (3, args);
5795
5796 /* Notice if it changed the face of the character we are on. */
5797 handle_face_prop (it);
5798 }
5799
5800
5801 /* Deliver a composition display element. The iterator IT is already
5802 filled with composition information (done in
5803 handle_composition_prop). Value is always 1. */
5804
5805 static int
5806 next_element_from_composition (it)
5807 struct it *it;
5808 {
5809 it->what = IT_COMPOSITION;
5810 it->position = (STRINGP (it->string)
5811 ? it->current.string_pos
5812 : it->current.pos);
5813 return 1;
5814 }
5815
5816
5817 \f
5818 /***********************************************************************
5819 Moving an iterator without producing glyphs
5820 ***********************************************************************/
5821
5822 /* Move iterator IT to a specified buffer or X position within one
5823 line on the display without producing glyphs.
5824
5825 OP should be a bit mask including some or all of these bits:
5826 MOVE_TO_X: Stop on reaching x-position TO_X.
5827 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5828 Regardless of OP's value, stop in reaching the end of the display line.
5829
5830 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5831 This means, in particular, that TO_X includes window's horizontal
5832 scroll amount.
5833
5834 The return value has several possible values that
5835 say what condition caused the scan to stop:
5836
5837 MOVE_POS_MATCH_OR_ZV
5838 - when TO_POS or ZV was reached.
5839
5840 MOVE_X_REACHED
5841 -when TO_X was reached before TO_POS or ZV were reached.
5842
5843 MOVE_LINE_CONTINUED
5844 - when we reached the end of the display area and the line must
5845 be continued.
5846
5847 MOVE_LINE_TRUNCATED
5848 - when we reached the end of the display area and the line is
5849 truncated.
5850
5851 MOVE_NEWLINE_OR_CR
5852 - when we stopped at a line end, i.e. a newline or a CR and selective
5853 display is on. */
5854
5855 static enum move_it_result
5856 move_it_in_display_line_to (it, to_charpos, to_x, op)
5857 struct it *it;
5858 int to_charpos, to_x, op;
5859 {
5860 enum move_it_result result = MOVE_UNDEFINED;
5861 struct glyph_row *saved_glyph_row;
5862
5863 /* Don't produce glyphs in produce_glyphs. */
5864 saved_glyph_row = it->glyph_row;
5865 it->glyph_row = NULL;
5866
5867 #define BUFFER_POS_REACHED_P() \
5868 ((op & MOVE_TO_POS) != 0 \
5869 && BUFFERP (it->object) \
5870 && IT_CHARPOS (*it) >= to_charpos \
5871 && (it->method == GET_FROM_BUFFER \
5872 || (it->method == GET_FROM_DISPLAY_VECTOR \
5873 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
5874
5875
5876 while (1)
5877 {
5878 int x, i, ascent = 0, descent = 0;
5879
5880 /* Stop when ZV reached.
5881 We used to stop here when TO_CHARPOS reached as well, but that is
5882 too soon if this glyph does not fit on this line. So we handle it
5883 explicitly below. */
5884 if (!get_next_display_element (it)
5885 || (it->truncate_lines_p
5886 && BUFFER_POS_REACHED_P ()))
5887 {
5888 result = MOVE_POS_MATCH_OR_ZV;
5889 break;
5890 }
5891
5892 /* The call to produce_glyphs will get the metrics of the
5893 display element IT is loaded with. We record in x the
5894 x-position before this display element in case it does not
5895 fit on the line. */
5896 x = it->current_x;
5897
5898 /* Remember the line height so far in case the next element doesn't
5899 fit on the line. */
5900 if (!it->truncate_lines_p)
5901 {
5902 ascent = it->max_ascent;
5903 descent = it->max_descent;
5904 }
5905
5906 PRODUCE_GLYPHS (it);
5907
5908 if (it->area != TEXT_AREA)
5909 {
5910 set_iterator_to_next (it, 1);
5911 continue;
5912 }
5913
5914 /* The number of glyphs we get back in IT->nglyphs will normally
5915 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5916 character on a terminal frame, or (iii) a line end. For the
5917 second case, IT->nglyphs - 1 padding glyphs will be present
5918 (on X frames, there is only one glyph produced for a
5919 composite character.
5920
5921 The behavior implemented below means, for continuation lines,
5922 that as many spaces of a TAB as fit on the current line are
5923 displayed there. For terminal frames, as many glyphs of a
5924 multi-glyph character are displayed in the current line, too.
5925 This is what the old redisplay code did, and we keep it that
5926 way. Under X, the whole shape of a complex character must
5927 fit on the line or it will be completely displayed in the
5928 next line.
5929
5930 Note that both for tabs and padding glyphs, all glyphs have
5931 the same width. */
5932 if (it->nglyphs)
5933 {
5934 /* More than one glyph or glyph doesn't fit on line. All
5935 glyphs have the same width. */
5936 int single_glyph_width = it->pixel_width / it->nglyphs;
5937 int new_x;
5938
5939 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5940 {
5941 new_x = x + single_glyph_width;
5942
5943 /* We want to leave anything reaching TO_X to the caller. */
5944 if ((op & MOVE_TO_X) && new_x > to_x)
5945 {
5946 if (BUFFER_POS_REACHED_P ())
5947 goto buffer_pos_reached;
5948 it->current_x = x;
5949 result = MOVE_X_REACHED;
5950 break;
5951 }
5952 else if (/* Lines are continued. */
5953 !it->truncate_lines_p
5954 && (/* And glyph doesn't fit on the line. */
5955 new_x > it->last_visible_x
5956 /* Or it fits exactly and we're on a window
5957 system frame. */
5958 || (new_x == it->last_visible_x
5959 && FRAME_WINDOW_P (it->f))))
5960 {
5961 if (/* IT->hpos == 0 means the very first glyph
5962 doesn't fit on the line, e.g. a wide image. */
5963 it->hpos == 0
5964 || (new_x == it->last_visible_x
5965 && FRAME_WINDOW_P (it->f)))
5966 {
5967 ++it->hpos;
5968 it->current_x = new_x;
5969 if (i == it->nglyphs - 1)
5970 {
5971 set_iterator_to_next (it, 1);
5972 #ifdef HAVE_WINDOW_SYSTEM
5973 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5974 {
5975 if (!get_next_display_element (it))
5976 {
5977 result = MOVE_POS_MATCH_OR_ZV;
5978 break;
5979 }
5980 if (BUFFER_POS_REACHED_P ())
5981 {
5982 if (ITERATOR_AT_END_OF_LINE_P (it))
5983 result = MOVE_POS_MATCH_OR_ZV;
5984 else
5985 result = MOVE_LINE_CONTINUED;
5986 break;
5987 }
5988 if (ITERATOR_AT_END_OF_LINE_P (it))
5989 {
5990 result = MOVE_NEWLINE_OR_CR;
5991 break;
5992 }
5993 }
5994 #endif /* HAVE_WINDOW_SYSTEM */
5995 }
5996 }
5997 else
5998 {
5999 it->current_x = x;
6000 it->max_ascent = ascent;
6001 it->max_descent = descent;
6002 }
6003
6004 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6005 IT_CHARPOS (*it)));
6006 result = MOVE_LINE_CONTINUED;
6007 break;
6008 }
6009 else if (BUFFER_POS_REACHED_P ())
6010 goto buffer_pos_reached;
6011 else if (new_x > it->first_visible_x)
6012 {
6013 /* Glyph is visible. Increment number of glyphs that
6014 would be displayed. */
6015 ++it->hpos;
6016 }
6017 else
6018 {
6019 /* Glyph is completely off the left margin of the display
6020 area. Nothing to do. */
6021 }
6022 }
6023
6024 if (result != MOVE_UNDEFINED)
6025 break;
6026 }
6027 else if (BUFFER_POS_REACHED_P ())
6028 {
6029 buffer_pos_reached:
6030 it->current_x = x;
6031 it->max_ascent = ascent;
6032 it->max_descent = descent;
6033 result = MOVE_POS_MATCH_OR_ZV;
6034 break;
6035 }
6036 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6037 {
6038 /* Stop when TO_X specified and reached. This check is
6039 necessary here because of lines consisting of a line end,
6040 only. The line end will not produce any glyphs and we
6041 would never get MOVE_X_REACHED. */
6042 xassert (it->nglyphs == 0);
6043 result = MOVE_X_REACHED;
6044 break;
6045 }
6046
6047 /* Is this a line end? If yes, we're done. */
6048 if (ITERATOR_AT_END_OF_LINE_P (it))
6049 {
6050 result = MOVE_NEWLINE_OR_CR;
6051 break;
6052 }
6053
6054 /* The current display element has been consumed. Advance
6055 to the next. */
6056 set_iterator_to_next (it, 1);
6057
6058 /* Stop if lines are truncated and IT's current x-position is
6059 past the right edge of the window now. */
6060 if (it->truncate_lines_p
6061 && it->current_x >= it->last_visible_x)
6062 {
6063 #ifdef HAVE_WINDOW_SYSTEM
6064 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6065 {
6066 if (!get_next_display_element (it)
6067 || BUFFER_POS_REACHED_P ())
6068 {
6069 result = MOVE_POS_MATCH_OR_ZV;
6070 break;
6071 }
6072 if (ITERATOR_AT_END_OF_LINE_P (it))
6073 {
6074 result = MOVE_NEWLINE_OR_CR;
6075 break;
6076 }
6077 }
6078 #endif /* HAVE_WINDOW_SYSTEM */
6079 result = MOVE_LINE_TRUNCATED;
6080 break;
6081 }
6082 }
6083
6084 #undef BUFFER_POS_REACHED_P
6085
6086 /* Restore the iterator settings altered at the beginning of this
6087 function. */
6088 it->glyph_row = saved_glyph_row;
6089 return result;
6090 }
6091
6092
6093 /* Move IT forward until it satisfies one or more of the criteria in
6094 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6095
6096 OP is a bit-mask that specifies where to stop, and in particular,
6097 which of those four position arguments makes a difference. See the
6098 description of enum move_operation_enum.
6099
6100 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6101 screen line, this function will set IT to the next position >
6102 TO_CHARPOS. */
6103
6104 void
6105 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6106 struct it *it;
6107 int to_charpos, to_x, to_y, to_vpos;
6108 int op;
6109 {
6110 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6111 int line_height;
6112 int reached = 0;
6113
6114 for (;;)
6115 {
6116 if (op & MOVE_TO_VPOS)
6117 {
6118 /* If no TO_CHARPOS and no TO_X specified, stop at the
6119 start of the line TO_VPOS. */
6120 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6121 {
6122 if (it->vpos == to_vpos)
6123 {
6124 reached = 1;
6125 break;
6126 }
6127 else
6128 skip = move_it_in_display_line_to (it, -1, -1, 0);
6129 }
6130 else
6131 {
6132 /* TO_VPOS >= 0 means stop at TO_X in the line at
6133 TO_VPOS, or at TO_POS, whichever comes first. */
6134 if (it->vpos == to_vpos)
6135 {
6136 reached = 2;
6137 break;
6138 }
6139
6140 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6141
6142 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6143 {
6144 reached = 3;
6145 break;
6146 }
6147 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6148 {
6149 /* We have reached TO_X but not in the line we want. */
6150 skip = move_it_in_display_line_to (it, to_charpos,
6151 -1, MOVE_TO_POS);
6152 if (skip == MOVE_POS_MATCH_OR_ZV)
6153 {
6154 reached = 4;
6155 break;
6156 }
6157 }
6158 }
6159 }
6160 else if (op & MOVE_TO_Y)
6161 {
6162 struct it it_backup;
6163
6164 /* TO_Y specified means stop at TO_X in the line containing
6165 TO_Y---or at TO_CHARPOS if this is reached first. The
6166 problem is that we can't really tell whether the line
6167 contains TO_Y before we have completely scanned it, and
6168 this may skip past TO_X. What we do is to first scan to
6169 TO_X.
6170
6171 If TO_X is not specified, use a TO_X of zero. The reason
6172 is to make the outcome of this function more predictable.
6173 If we didn't use TO_X == 0, we would stop at the end of
6174 the line which is probably not what a caller would expect
6175 to happen. */
6176 skip = move_it_in_display_line_to (it, to_charpos,
6177 ((op & MOVE_TO_X)
6178 ? to_x : 0),
6179 (MOVE_TO_X
6180 | (op & MOVE_TO_POS)));
6181
6182 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6183 if (skip == MOVE_POS_MATCH_OR_ZV)
6184 {
6185 reached = 5;
6186 break;
6187 }
6188
6189 /* If TO_X was reached, we would like to know whether TO_Y
6190 is in the line. This can only be said if we know the
6191 total line height which requires us to scan the rest of
6192 the line. */
6193 if (skip == MOVE_X_REACHED)
6194 {
6195 it_backup = *it;
6196 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6197 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6198 op & MOVE_TO_POS);
6199 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6200 }
6201
6202 /* Now, decide whether TO_Y is in this line. */
6203 line_height = it->max_ascent + it->max_descent;
6204 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6205
6206 if (to_y >= it->current_y
6207 && to_y < it->current_y + line_height)
6208 {
6209 if (skip == MOVE_X_REACHED)
6210 /* If TO_Y is in this line and TO_X was reached above,
6211 we scanned too far. We have to restore IT's settings
6212 to the ones before skipping. */
6213 *it = it_backup;
6214 reached = 6;
6215 }
6216 else if (skip == MOVE_X_REACHED)
6217 {
6218 skip = skip2;
6219 if (skip == MOVE_POS_MATCH_OR_ZV)
6220 reached = 7;
6221 }
6222
6223 if (reached)
6224 break;
6225 }
6226 else
6227 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6228
6229 switch (skip)
6230 {
6231 case MOVE_POS_MATCH_OR_ZV:
6232 reached = 8;
6233 goto out;
6234
6235 case MOVE_NEWLINE_OR_CR:
6236 set_iterator_to_next (it, 1);
6237 it->continuation_lines_width = 0;
6238 break;
6239
6240 case MOVE_LINE_TRUNCATED:
6241 it->continuation_lines_width = 0;
6242 reseat_at_next_visible_line_start (it, 0);
6243 if ((op & MOVE_TO_POS) != 0
6244 && IT_CHARPOS (*it) > to_charpos)
6245 {
6246 reached = 9;
6247 goto out;
6248 }
6249 break;
6250
6251 case MOVE_LINE_CONTINUED:
6252 it->continuation_lines_width += it->current_x;
6253 break;
6254
6255 default:
6256 abort ();
6257 }
6258
6259 /* Reset/increment for the next run. */
6260 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6261 it->current_x = it->hpos = 0;
6262 it->current_y += it->max_ascent + it->max_descent;
6263 ++it->vpos;
6264 last_height = it->max_ascent + it->max_descent;
6265 last_max_ascent = it->max_ascent;
6266 it->max_ascent = it->max_descent = 0;
6267 }
6268
6269 out:
6270
6271 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6272 }
6273
6274
6275 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6276
6277 If DY > 0, move IT backward at least that many pixels. DY = 0
6278 means move IT backward to the preceding line start or BEGV. This
6279 function may move over more than DY pixels if IT->current_y - DY
6280 ends up in the middle of a line; in this case IT->current_y will be
6281 set to the top of the line moved to. */
6282
6283 void
6284 move_it_vertically_backward (it, dy)
6285 struct it *it;
6286 int dy;
6287 {
6288 int nlines, h;
6289 struct it it2, it3;
6290 int start_pos;
6291
6292 move_further_back:
6293 xassert (dy >= 0);
6294
6295 start_pos = IT_CHARPOS (*it);
6296
6297 /* Estimate how many newlines we must move back. */
6298 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6299
6300 /* Set the iterator's position that many lines back. */
6301 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6302 back_to_previous_visible_line_start (it);
6303
6304 /* Reseat the iterator here. When moving backward, we don't want
6305 reseat to skip forward over invisible text, set up the iterator
6306 to deliver from overlay strings at the new position etc. So,
6307 use reseat_1 here. */
6308 reseat_1 (it, it->current.pos, 1);
6309
6310 /* We are now surely at a line start. */
6311 it->current_x = it->hpos = 0;
6312 it->continuation_lines_width = 0;
6313
6314 /* Move forward and see what y-distance we moved. First move to the
6315 start of the next line so that we get its height. We need this
6316 height to be able to tell whether we reached the specified
6317 y-distance. */
6318 it2 = *it;
6319 it2.max_ascent = it2.max_descent = 0;
6320 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6321 MOVE_TO_POS | MOVE_TO_VPOS);
6322 xassert (IT_CHARPOS (*it) >= BEGV);
6323 it3 = it2;
6324
6325 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6326 xassert (IT_CHARPOS (*it) >= BEGV);
6327 /* H is the actual vertical distance from the position in *IT
6328 and the starting position. */
6329 h = it2.current_y - it->current_y;
6330 /* NLINES is the distance in number of lines. */
6331 nlines = it2.vpos - it->vpos;
6332
6333 /* Correct IT's y and vpos position
6334 so that they are relative to the starting point. */
6335 it->vpos -= nlines;
6336 it->current_y -= h;
6337
6338 if (dy == 0)
6339 {
6340 /* DY == 0 means move to the start of the screen line. The
6341 value of nlines is > 0 if continuation lines were involved. */
6342 if (nlines > 0)
6343 move_it_by_lines (it, nlines, 1);
6344 #if 0
6345 /* I think this assert is bogus if buffer contains
6346 invisible text or images. KFS. */
6347 xassert (IT_CHARPOS (*it) <= start_pos);
6348 #endif
6349 }
6350 else
6351 {
6352 /* The y-position we try to reach, relative to *IT.
6353 Note that H has been subtracted in front of the if-statement. */
6354 int target_y = it->current_y + h - dy;
6355 int y0 = it3.current_y;
6356 int y1 = line_bottom_y (&it3);
6357 int line_height = y1 - y0;
6358
6359 /* If we did not reach target_y, try to move further backward if
6360 we can. If we moved too far backward, try to move forward. */
6361 if (target_y < it->current_y
6362 /* This is heuristic. In a window that's 3 lines high, with
6363 a line height of 13 pixels each, recentering with point
6364 on the bottom line will try to move -39/2 = 19 pixels
6365 backward. Try to avoid moving into the first line. */
6366 && (it->current_y - target_y
6367 > min (window_box_height (it->w), line_height * 2 / 3))
6368 && IT_CHARPOS (*it) > BEGV)
6369 {
6370 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6371 target_y - it->current_y));
6372 dy = it->current_y - target_y;
6373 goto move_further_back;
6374 }
6375 else if (target_y >= it->current_y + line_height
6376 && IT_CHARPOS (*it) < ZV)
6377 {
6378 /* Should move forward by at least one line, maybe more.
6379
6380 Note: Calling move_it_by_lines can be expensive on
6381 terminal frames, where compute_motion is used (via
6382 vmotion) to do the job, when there are very long lines
6383 and truncate-lines is nil. That's the reason for
6384 treating terminal frames specially here. */
6385
6386 if (!FRAME_WINDOW_P (it->f))
6387 move_it_vertically (it, target_y - (it->current_y + line_height));
6388 else
6389 {
6390 do
6391 {
6392 move_it_by_lines (it, 1, 1);
6393 }
6394 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6395 }
6396
6397 #if 0
6398 /* I think this assert is bogus if buffer contains
6399 invisible text or images. KFS. */
6400 xassert (IT_CHARPOS (*it) >= BEGV);
6401 #endif
6402 }
6403 }
6404 }
6405
6406
6407 /* Move IT by a specified amount of pixel lines DY. DY negative means
6408 move backwards. DY = 0 means move to start of screen line. At the
6409 end, IT will be on the start of a screen line. */
6410
6411 void
6412 move_it_vertically (it, dy)
6413 struct it *it;
6414 int dy;
6415 {
6416 if (dy <= 0)
6417 move_it_vertically_backward (it, -dy);
6418 else
6419 {
6420 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6421 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6422 MOVE_TO_POS | MOVE_TO_Y);
6423 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6424
6425 /* If buffer ends in ZV without a newline, move to the start of
6426 the line to satisfy the post-condition. */
6427 if (IT_CHARPOS (*it) == ZV
6428 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6429 move_it_by_lines (it, 0, 0);
6430 }
6431 }
6432
6433
6434 /* Move iterator IT past the end of the text line it is in. */
6435
6436 void
6437 move_it_past_eol (it)
6438 struct it *it;
6439 {
6440 enum move_it_result rc;
6441
6442 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6443 if (rc == MOVE_NEWLINE_OR_CR)
6444 set_iterator_to_next (it, 0);
6445 }
6446
6447
6448 #if 0 /* Currently not used. */
6449
6450 /* Return non-zero if some text between buffer positions START_CHARPOS
6451 and END_CHARPOS is invisible. IT->window is the window for text
6452 property lookup. */
6453
6454 static int
6455 invisible_text_between_p (it, start_charpos, end_charpos)
6456 struct it *it;
6457 int start_charpos, end_charpos;
6458 {
6459 Lisp_Object prop, limit;
6460 int invisible_found_p;
6461
6462 xassert (it != NULL && start_charpos <= end_charpos);
6463
6464 /* Is text at START invisible? */
6465 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6466 it->window);
6467 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6468 invisible_found_p = 1;
6469 else
6470 {
6471 limit = Fnext_single_char_property_change (make_number (start_charpos),
6472 Qinvisible, Qnil,
6473 make_number (end_charpos));
6474 invisible_found_p = XFASTINT (limit) < end_charpos;
6475 }
6476
6477 return invisible_found_p;
6478 }
6479
6480 #endif /* 0 */
6481
6482
6483 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6484 negative means move up. DVPOS == 0 means move to the start of the
6485 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6486 NEED_Y_P is zero, IT->current_y will be left unchanged.
6487
6488 Further optimization ideas: If we would know that IT->f doesn't use
6489 a face with proportional font, we could be faster for
6490 truncate-lines nil. */
6491
6492 void
6493 move_it_by_lines (it, dvpos, need_y_p)
6494 struct it *it;
6495 int dvpos, need_y_p;
6496 {
6497 struct position pos;
6498
6499 if (!FRAME_WINDOW_P (it->f))
6500 {
6501 struct text_pos textpos;
6502
6503 /* We can use vmotion on frames without proportional fonts. */
6504 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6505 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6506 reseat (it, textpos, 1);
6507 it->vpos += pos.vpos;
6508 it->current_y += pos.vpos;
6509 }
6510 else if (dvpos == 0)
6511 {
6512 /* DVPOS == 0 means move to the start of the screen line. */
6513 move_it_vertically_backward (it, 0);
6514 xassert (it->current_x == 0 && it->hpos == 0);
6515 /* Let next call to line_bottom_y calculate real line height */
6516 last_height = 0;
6517 }
6518 else if (dvpos > 0)
6519 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6520 else
6521 {
6522 struct it it2;
6523 int start_charpos, i;
6524
6525 /* Start at the beginning of the screen line containing IT's
6526 position. */
6527 move_it_vertically_backward (it, 0);
6528
6529 /* Go back -DVPOS visible lines and reseat the iterator there. */
6530 start_charpos = IT_CHARPOS (*it);
6531 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6532 back_to_previous_visible_line_start (it);
6533 reseat (it, it->current.pos, 1);
6534 it->current_x = it->hpos = 0;
6535
6536 /* Above call may have moved too far if continuation lines
6537 are involved. Scan forward and see if it did. */
6538 it2 = *it;
6539 it2.vpos = it2.current_y = 0;
6540 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6541 it->vpos -= it2.vpos;
6542 it->current_y -= it2.current_y;
6543 it->current_x = it->hpos = 0;
6544
6545 /* If we moved too far back, move IT some lines forward. */
6546 if (it2.vpos > -dvpos)
6547 {
6548 int delta = it2.vpos + dvpos;
6549 it2 = *it;
6550 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6551 /* Move back again if we got too far ahead. */
6552 if (IT_CHARPOS (*it) >= start_charpos)
6553 *it = it2;
6554 }
6555 }
6556 }
6557
6558 /* Return 1 if IT points into the middle of a display vector. */
6559
6560 int
6561 in_display_vector_p (it)
6562 struct it *it;
6563 {
6564 return (it->method == GET_FROM_DISPLAY_VECTOR
6565 && it->current.dpvec_index > 0
6566 && it->dpvec + it->current.dpvec_index != it->dpend);
6567 }
6568
6569 \f
6570 /***********************************************************************
6571 Messages
6572 ***********************************************************************/
6573
6574
6575 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6576 to *Messages*. */
6577
6578 void
6579 add_to_log (format, arg1, arg2)
6580 char *format;
6581 Lisp_Object arg1, arg2;
6582 {
6583 Lisp_Object args[3];
6584 Lisp_Object msg, fmt;
6585 char *buffer;
6586 int len;
6587 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6588 USE_SAFE_ALLOCA;
6589
6590 /* Do nothing if called asynchronously. Inserting text into
6591 a buffer may call after-change-functions and alike and
6592 that would means running Lisp asynchronously. */
6593 if (handling_signal)
6594 return;
6595
6596 fmt = msg = Qnil;
6597 GCPRO4 (fmt, msg, arg1, arg2);
6598
6599 args[0] = fmt = build_string (format);
6600 args[1] = arg1;
6601 args[2] = arg2;
6602 msg = Fformat (3, args);
6603
6604 len = SBYTES (msg) + 1;
6605 SAFE_ALLOCA (buffer, char *, len);
6606 bcopy (SDATA (msg), buffer, len);
6607
6608 message_dolog (buffer, len - 1, 1, 0);
6609 SAFE_FREE ();
6610
6611 UNGCPRO;
6612 }
6613
6614
6615 /* Output a newline in the *Messages* buffer if "needs" one. */
6616
6617 void
6618 message_log_maybe_newline ()
6619 {
6620 if (message_log_need_newline)
6621 message_dolog ("", 0, 1, 0);
6622 }
6623
6624
6625 /* Add a string M of length NBYTES to the message log, optionally
6626 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6627 nonzero, means interpret the contents of M as multibyte. This
6628 function calls low-level routines in order to bypass text property
6629 hooks, etc. which might not be safe to run. */
6630
6631 void
6632 message_dolog (m, nbytes, nlflag, multibyte)
6633 const char *m;
6634 int nbytes, nlflag, multibyte;
6635 {
6636 if (!NILP (Vmemory_full))
6637 return;
6638
6639 if (!NILP (Vmessage_log_max))
6640 {
6641 struct buffer *oldbuf;
6642 Lisp_Object oldpoint, oldbegv, oldzv;
6643 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6644 int point_at_end = 0;
6645 int zv_at_end = 0;
6646 Lisp_Object old_deactivate_mark, tem;
6647 struct gcpro gcpro1;
6648
6649 old_deactivate_mark = Vdeactivate_mark;
6650 oldbuf = current_buffer;
6651 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6652 current_buffer->undo_list = Qt;
6653
6654 oldpoint = message_dolog_marker1;
6655 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6656 oldbegv = message_dolog_marker2;
6657 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6658 oldzv = message_dolog_marker3;
6659 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6660 GCPRO1 (old_deactivate_mark);
6661
6662 if (PT == Z)
6663 point_at_end = 1;
6664 if (ZV == Z)
6665 zv_at_end = 1;
6666
6667 BEGV = BEG;
6668 BEGV_BYTE = BEG_BYTE;
6669 ZV = Z;
6670 ZV_BYTE = Z_BYTE;
6671 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6672
6673 /* Insert the string--maybe converting multibyte to single byte
6674 or vice versa, so that all the text fits the buffer. */
6675 if (multibyte
6676 && NILP (current_buffer->enable_multibyte_characters))
6677 {
6678 int i, c, char_bytes;
6679 unsigned char work[1];
6680
6681 /* Convert a multibyte string to single-byte
6682 for the *Message* buffer. */
6683 for (i = 0; i < nbytes; i += char_bytes)
6684 {
6685 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6686 work[0] = (SINGLE_BYTE_CHAR_P (c)
6687 ? c
6688 : multibyte_char_to_unibyte (c, Qnil));
6689 insert_1_both (work, 1, 1, 1, 0, 0);
6690 }
6691 }
6692 else if (! multibyte
6693 && ! NILP (current_buffer->enable_multibyte_characters))
6694 {
6695 int i, c, char_bytes;
6696 unsigned char *msg = (unsigned char *) m;
6697 unsigned char str[MAX_MULTIBYTE_LENGTH];
6698 /* Convert a single-byte string to multibyte
6699 for the *Message* buffer. */
6700 for (i = 0; i < nbytes; i++)
6701 {
6702 c = unibyte_char_to_multibyte (msg[i]);
6703 char_bytes = CHAR_STRING (c, str);
6704 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6705 }
6706 }
6707 else if (nbytes)
6708 insert_1 (m, nbytes, 1, 0, 0);
6709
6710 if (nlflag)
6711 {
6712 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6713 insert_1 ("\n", 1, 1, 0, 0);
6714
6715 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6716 this_bol = PT;
6717 this_bol_byte = PT_BYTE;
6718
6719 /* See if this line duplicates the previous one.
6720 If so, combine duplicates. */
6721 if (this_bol > BEG)
6722 {
6723 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6724 prev_bol = PT;
6725 prev_bol_byte = PT_BYTE;
6726
6727 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6728 this_bol, this_bol_byte);
6729 if (dup)
6730 {
6731 del_range_both (prev_bol, prev_bol_byte,
6732 this_bol, this_bol_byte, 0);
6733 if (dup > 1)
6734 {
6735 char dupstr[40];
6736 int duplen;
6737
6738 /* If you change this format, don't forget to also
6739 change message_log_check_duplicate. */
6740 sprintf (dupstr, " [%d times]", dup);
6741 duplen = strlen (dupstr);
6742 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6743 insert_1 (dupstr, duplen, 1, 0, 1);
6744 }
6745 }
6746 }
6747
6748 /* If we have more than the desired maximum number of lines
6749 in the *Messages* buffer now, delete the oldest ones.
6750 This is safe because we don't have undo in this buffer. */
6751
6752 if (NATNUMP (Vmessage_log_max))
6753 {
6754 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6755 -XFASTINT (Vmessage_log_max) - 1, 0);
6756 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6757 }
6758 }
6759 BEGV = XMARKER (oldbegv)->charpos;
6760 BEGV_BYTE = marker_byte_position (oldbegv);
6761
6762 if (zv_at_end)
6763 {
6764 ZV = Z;
6765 ZV_BYTE = Z_BYTE;
6766 }
6767 else
6768 {
6769 ZV = XMARKER (oldzv)->charpos;
6770 ZV_BYTE = marker_byte_position (oldzv);
6771 }
6772
6773 if (point_at_end)
6774 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6775 else
6776 /* We can't do Fgoto_char (oldpoint) because it will run some
6777 Lisp code. */
6778 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6779 XMARKER (oldpoint)->bytepos);
6780
6781 UNGCPRO;
6782 unchain_marker (XMARKER (oldpoint));
6783 unchain_marker (XMARKER (oldbegv));
6784 unchain_marker (XMARKER (oldzv));
6785
6786 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6787 set_buffer_internal (oldbuf);
6788 if (NILP (tem))
6789 windows_or_buffers_changed = old_windows_or_buffers_changed;
6790 message_log_need_newline = !nlflag;
6791 Vdeactivate_mark = old_deactivate_mark;
6792 }
6793 }
6794
6795
6796 /* We are at the end of the buffer after just having inserted a newline.
6797 (Note: We depend on the fact we won't be crossing the gap.)
6798 Check to see if the most recent message looks a lot like the previous one.
6799 Return 0 if different, 1 if the new one should just replace it, or a
6800 value N > 1 if we should also append " [N times]". */
6801
6802 static int
6803 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6804 int prev_bol, this_bol;
6805 int prev_bol_byte, this_bol_byte;
6806 {
6807 int i;
6808 int len = Z_BYTE - 1 - this_bol_byte;
6809 int seen_dots = 0;
6810 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6811 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6812
6813 for (i = 0; i < len; i++)
6814 {
6815 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6816 seen_dots = 1;
6817 if (p1[i] != p2[i])
6818 return seen_dots;
6819 }
6820 p1 += len;
6821 if (*p1 == '\n')
6822 return 2;
6823 if (*p1++ == ' ' && *p1++ == '[')
6824 {
6825 int n = 0;
6826 while (*p1 >= '0' && *p1 <= '9')
6827 n = n * 10 + *p1++ - '0';
6828 if (strncmp (p1, " times]\n", 8) == 0)
6829 return n+1;
6830 }
6831 return 0;
6832 }
6833 \f
6834
6835 /* Display an echo area message M with a specified length of NBYTES
6836 bytes. The string may include null characters. If M is 0, clear
6837 out any existing message, and let the mini-buffer text show
6838 through.
6839
6840 The buffer M must continue to exist until after the echo area gets
6841 cleared or some other message gets displayed there. This means do
6842 not pass text that is stored in a Lisp string; do not pass text in
6843 a buffer that was alloca'd. */
6844
6845 void
6846 message2 (m, nbytes, multibyte)
6847 const char *m;
6848 int nbytes;
6849 int multibyte;
6850 {
6851 /* First flush out any partial line written with print. */
6852 message_log_maybe_newline ();
6853 if (m)
6854 message_dolog (m, nbytes, 1, multibyte);
6855 message2_nolog (m, nbytes, multibyte);
6856 }
6857
6858
6859 /* The non-logging counterpart of message2. */
6860
6861 void
6862 message2_nolog (m, nbytes, multibyte)
6863 const char *m;
6864 int nbytes, multibyte;
6865 {
6866 struct frame *sf = SELECTED_FRAME ();
6867 message_enable_multibyte = multibyte;
6868
6869 if (noninteractive)
6870 {
6871 if (noninteractive_need_newline)
6872 putc ('\n', stderr);
6873 noninteractive_need_newline = 0;
6874 if (m)
6875 fwrite (m, nbytes, 1, stderr);
6876 if (cursor_in_echo_area == 0)
6877 fprintf (stderr, "\n");
6878 fflush (stderr);
6879 }
6880 /* A null message buffer means that the frame hasn't really been
6881 initialized yet. Error messages get reported properly by
6882 cmd_error, so this must be just an informative message; toss it. */
6883 else if (INTERACTIVE
6884 && sf->glyphs_initialized_p
6885 && FRAME_MESSAGE_BUF (sf))
6886 {
6887 Lisp_Object mini_window;
6888 struct frame *f;
6889
6890 /* Get the frame containing the mini-buffer
6891 that the selected frame is using. */
6892 mini_window = FRAME_MINIBUF_WINDOW (sf);
6893 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6894
6895 FRAME_SAMPLE_VISIBILITY (f);
6896 if (FRAME_VISIBLE_P (sf)
6897 && ! FRAME_VISIBLE_P (f))
6898 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6899
6900 if (m)
6901 {
6902 set_message (m, Qnil, nbytes, multibyte);
6903 if (minibuffer_auto_raise)
6904 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6905 }
6906 else
6907 clear_message (1, 1);
6908
6909 do_pending_window_change (0);
6910 echo_area_display (1);
6911 do_pending_window_change (0);
6912 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6913 (*frame_up_to_date_hook) (f);
6914 }
6915 }
6916
6917
6918 /* Display an echo area message M with a specified length of NBYTES
6919 bytes. The string may include null characters. If M is not a
6920 string, clear out any existing message, and let the mini-buffer
6921 text show through. */
6922
6923 void
6924 message3 (m, nbytes, multibyte)
6925 Lisp_Object m;
6926 int nbytes;
6927 int multibyte;
6928 {
6929 struct gcpro gcpro1;
6930
6931 GCPRO1 (m);
6932 clear_message (1,1);
6933
6934 /* First flush out any partial line written with print. */
6935 message_log_maybe_newline ();
6936 if (STRINGP (m))
6937 message_dolog (SDATA (m), nbytes, 1, multibyte);
6938 message3_nolog (m, nbytes, multibyte);
6939
6940 UNGCPRO;
6941 }
6942
6943
6944 /* The non-logging version of message3. */
6945
6946 void
6947 message3_nolog (m, nbytes, multibyte)
6948 Lisp_Object m;
6949 int nbytes, multibyte;
6950 {
6951 struct frame *sf = SELECTED_FRAME ();
6952 message_enable_multibyte = multibyte;
6953
6954 if (noninteractive)
6955 {
6956 if (noninteractive_need_newline)
6957 putc ('\n', stderr);
6958 noninteractive_need_newline = 0;
6959 if (STRINGP (m))
6960 fwrite (SDATA (m), nbytes, 1, stderr);
6961 if (cursor_in_echo_area == 0)
6962 fprintf (stderr, "\n");
6963 fflush (stderr);
6964 }
6965 /* A null message buffer means that the frame hasn't really been
6966 initialized yet. Error messages get reported properly by
6967 cmd_error, so this must be just an informative message; toss it. */
6968 else if (INTERACTIVE
6969 && sf->glyphs_initialized_p
6970 && FRAME_MESSAGE_BUF (sf))
6971 {
6972 Lisp_Object mini_window;
6973 Lisp_Object frame;
6974 struct frame *f;
6975
6976 /* Get the frame containing the mini-buffer
6977 that the selected frame is using. */
6978 mini_window = FRAME_MINIBUF_WINDOW (sf);
6979 frame = XWINDOW (mini_window)->frame;
6980 f = XFRAME (frame);
6981
6982 FRAME_SAMPLE_VISIBILITY (f);
6983 if (FRAME_VISIBLE_P (sf)
6984 && !FRAME_VISIBLE_P (f))
6985 Fmake_frame_visible (frame);
6986
6987 if (STRINGP (m) && SCHARS (m) > 0)
6988 {
6989 set_message (NULL, m, nbytes, multibyte);
6990 if (minibuffer_auto_raise)
6991 Fraise_frame (frame);
6992 }
6993 else
6994 clear_message (1, 1);
6995
6996 do_pending_window_change (0);
6997 echo_area_display (1);
6998 do_pending_window_change (0);
6999 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
7000 (*frame_up_to_date_hook) (f);
7001 }
7002 }
7003
7004
7005 /* Display a null-terminated echo area message M. If M is 0, clear
7006 out any existing message, and let the mini-buffer text show through.
7007
7008 The buffer M must continue to exist until after the echo area gets
7009 cleared or some other message gets displayed there. Do not pass
7010 text that is stored in a Lisp string. Do not pass text in a buffer
7011 that was alloca'd. */
7012
7013 void
7014 message1 (m)
7015 char *m;
7016 {
7017 message2 (m, (m ? strlen (m) : 0), 0);
7018 }
7019
7020
7021 /* The non-logging counterpart of message1. */
7022
7023 void
7024 message1_nolog (m)
7025 char *m;
7026 {
7027 message2_nolog (m, (m ? strlen (m) : 0), 0);
7028 }
7029
7030 /* Display a message M which contains a single %s
7031 which gets replaced with STRING. */
7032
7033 void
7034 message_with_string (m, string, log)
7035 char *m;
7036 Lisp_Object string;
7037 int log;
7038 {
7039 CHECK_STRING (string);
7040
7041 if (noninteractive)
7042 {
7043 if (m)
7044 {
7045 if (noninteractive_need_newline)
7046 putc ('\n', stderr);
7047 noninteractive_need_newline = 0;
7048 fprintf (stderr, m, SDATA (string));
7049 if (cursor_in_echo_area == 0)
7050 fprintf (stderr, "\n");
7051 fflush (stderr);
7052 }
7053 }
7054 else if (INTERACTIVE)
7055 {
7056 /* The frame whose minibuffer we're going to display the message on.
7057 It may be larger than the selected frame, so we need
7058 to use its buffer, not the selected frame's buffer. */
7059 Lisp_Object mini_window;
7060 struct frame *f, *sf = SELECTED_FRAME ();
7061
7062 /* Get the frame containing the minibuffer
7063 that the selected frame is using. */
7064 mini_window = FRAME_MINIBUF_WINDOW (sf);
7065 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7066
7067 /* A null message buffer means that the frame hasn't really been
7068 initialized yet. Error messages get reported properly by
7069 cmd_error, so this must be just an informative message; toss it. */
7070 if (FRAME_MESSAGE_BUF (f))
7071 {
7072 Lisp_Object args[2], message;
7073 struct gcpro gcpro1, gcpro2;
7074
7075 args[0] = build_string (m);
7076 args[1] = message = string;
7077 GCPRO2 (args[0], message);
7078 gcpro1.nvars = 2;
7079
7080 message = Fformat (2, args);
7081
7082 if (log)
7083 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7084 else
7085 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7086
7087 UNGCPRO;
7088
7089 /* Print should start at the beginning of the message
7090 buffer next time. */
7091 message_buf_print = 0;
7092 }
7093 }
7094 }
7095
7096
7097 /* Dump an informative message to the minibuf. If M is 0, clear out
7098 any existing message, and let the mini-buffer text show through. */
7099
7100 /* VARARGS 1 */
7101 void
7102 message (m, a1, a2, a3)
7103 char *m;
7104 EMACS_INT a1, a2, a3;
7105 {
7106 if (noninteractive)
7107 {
7108 if (m)
7109 {
7110 if (noninteractive_need_newline)
7111 putc ('\n', stderr);
7112 noninteractive_need_newline = 0;
7113 fprintf (stderr, m, a1, a2, a3);
7114 if (cursor_in_echo_area == 0)
7115 fprintf (stderr, "\n");
7116 fflush (stderr);
7117 }
7118 }
7119 else if (INTERACTIVE)
7120 {
7121 /* The frame whose mini-buffer we're going to display the message
7122 on. It may be larger than the selected frame, so we need to
7123 use its buffer, not the selected frame's buffer. */
7124 Lisp_Object mini_window;
7125 struct frame *f, *sf = SELECTED_FRAME ();
7126
7127 /* Get the frame containing the mini-buffer
7128 that the selected frame is using. */
7129 mini_window = FRAME_MINIBUF_WINDOW (sf);
7130 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7131
7132 /* A null message buffer means that the frame hasn't really been
7133 initialized yet. Error messages get reported properly by
7134 cmd_error, so this must be just an informative message; toss
7135 it. */
7136 if (FRAME_MESSAGE_BUF (f))
7137 {
7138 if (m)
7139 {
7140 int len;
7141 #ifdef NO_ARG_ARRAY
7142 char *a[3];
7143 a[0] = (char *) a1;
7144 a[1] = (char *) a2;
7145 a[2] = (char *) a3;
7146
7147 len = doprnt (FRAME_MESSAGE_BUF (f),
7148 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7149 #else
7150 len = doprnt (FRAME_MESSAGE_BUF (f),
7151 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7152 (char **) &a1);
7153 #endif /* NO_ARG_ARRAY */
7154
7155 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7156 }
7157 else
7158 message1 (0);
7159
7160 /* Print should start at the beginning of the message
7161 buffer next time. */
7162 message_buf_print = 0;
7163 }
7164 }
7165 }
7166
7167
7168 /* The non-logging version of message. */
7169
7170 void
7171 message_nolog (m, a1, a2, a3)
7172 char *m;
7173 EMACS_INT a1, a2, a3;
7174 {
7175 Lisp_Object old_log_max;
7176 old_log_max = Vmessage_log_max;
7177 Vmessage_log_max = Qnil;
7178 message (m, a1, a2, a3);
7179 Vmessage_log_max = old_log_max;
7180 }
7181
7182
7183 /* Display the current message in the current mini-buffer. This is
7184 only called from error handlers in process.c, and is not time
7185 critical. */
7186
7187 void
7188 update_echo_area ()
7189 {
7190 if (!NILP (echo_area_buffer[0]))
7191 {
7192 Lisp_Object string;
7193 string = Fcurrent_message ();
7194 message3 (string, SBYTES (string),
7195 !NILP (current_buffer->enable_multibyte_characters));
7196 }
7197 }
7198
7199
7200 /* Make sure echo area buffers in `echo_buffers' are live.
7201 If they aren't, make new ones. */
7202
7203 static void
7204 ensure_echo_area_buffers ()
7205 {
7206 int i;
7207
7208 for (i = 0; i < 2; ++i)
7209 if (!BUFFERP (echo_buffer[i])
7210 || NILP (XBUFFER (echo_buffer[i])->name))
7211 {
7212 char name[30];
7213 Lisp_Object old_buffer;
7214 int j;
7215
7216 old_buffer = echo_buffer[i];
7217 sprintf (name, " *Echo Area %d*", i);
7218 echo_buffer[i] = Fget_buffer_create (build_string (name));
7219 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7220
7221 for (j = 0; j < 2; ++j)
7222 if (EQ (old_buffer, echo_area_buffer[j]))
7223 echo_area_buffer[j] = echo_buffer[i];
7224 }
7225 }
7226
7227
7228 /* Call FN with args A1..A4 with either the current or last displayed
7229 echo_area_buffer as current buffer.
7230
7231 WHICH zero means use the current message buffer
7232 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7233 from echo_buffer[] and clear it.
7234
7235 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7236 suitable buffer from echo_buffer[] and clear it.
7237
7238 Value is what FN returns. */
7239
7240 static int
7241 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7242 struct window *w;
7243 int which;
7244 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7245 EMACS_INT a1;
7246 Lisp_Object a2;
7247 EMACS_INT a3, a4;
7248 {
7249 Lisp_Object buffer;
7250 int this_one, the_other, clear_buffer_p, rc;
7251 int count = SPECPDL_INDEX ();
7252
7253 /* If buffers aren't live, make new ones. */
7254 ensure_echo_area_buffers ();
7255
7256 clear_buffer_p = 0;
7257
7258 if (which == 0)
7259 this_one = 0, the_other = 1;
7260 else if (which > 0)
7261 this_one = 1, the_other = 0;
7262
7263 /* Choose a suitable buffer from echo_buffer[] is we don't
7264 have one. */
7265 if (NILP (echo_area_buffer[this_one]))
7266 {
7267 echo_area_buffer[this_one]
7268 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7269 ? echo_buffer[the_other]
7270 : echo_buffer[this_one]);
7271 clear_buffer_p = 1;
7272 }
7273
7274 buffer = echo_area_buffer[this_one];
7275
7276 /* Don't get confused by reusing the buffer used for echoing
7277 for a different purpose. */
7278 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7279 cancel_echoing ();
7280
7281 record_unwind_protect (unwind_with_echo_area_buffer,
7282 with_echo_area_buffer_unwind_data (w));
7283
7284 /* Make the echo area buffer current. Note that for display
7285 purposes, it is not necessary that the displayed window's buffer
7286 == current_buffer, except for text property lookup. So, let's
7287 only set that buffer temporarily here without doing a full
7288 Fset_window_buffer. We must also change w->pointm, though,
7289 because otherwise an assertions in unshow_buffer fails, and Emacs
7290 aborts. */
7291 set_buffer_internal_1 (XBUFFER (buffer));
7292 if (w)
7293 {
7294 w->buffer = buffer;
7295 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7296 }
7297
7298 current_buffer->undo_list = Qt;
7299 current_buffer->read_only = Qnil;
7300 specbind (Qinhibit_read_only, Qt);
7301 specbind (Qinhibit_modification_hooks, Qt);
7302
7303 if (clear_buffer_p && Z > BEG)
7304 del_range (BEG, Z);
7305
7306 xassert (BEGV >= BEG);
7307 xassert (ZV <= Z && ZV >= BEGV);
7308
7309 rc = fn (a1, a2, a3, a4);
7310
7311 xassert (BEGV >= BEG);
7312 xassert (ZV <= Z && ZV >= BEGV);
7313
7314 unbind_to (count, Qnil);
7315 return rc;
7316 }
7317
7318
7319 /* Save state that should be preserved around the call to the function
7320 FN called in with_echo_area_buffer. */
7321
7322 static Lisp_Object
7323 with_echo_area_buffer_unwind_data (w)
7324 struct window *w;
7325 {
7326 int i = 0;
7327 Lisp_Object vector;
7328
7329 /* Reduce consing by keeping one vector in
7330 Vwith_echo_area_save_vector. */
7331 vector = Vwith_echo_area_save_vector;
7332 Vwith_echo_area_save_vector = Qnil;
7333
7334 if (NILP (vector))
7335 vector = Fmake_vector (make_number (7), Qnil);
7336
7337 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7338 AREF (vector, i) = Vdeactivate_mark, ++i;
7339 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7340
7341 if (w)
7342 {
7343 XSETWINDOW (AREF (vector, i), w); ++i;
7344 AREF (vector, i) = w->buffer; ++i;
7345 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7346 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7347 }
7348 else
7349 {
7350 int end = i + 4;
7351 for (; i < end; ++i)
7352 AREF (vector, i) = Qnil;
7353 }
7354
7355 xassert (i == ASIZE (vector));
7356 return vector;
7357 }
7358
7359
7360 /* Restore global state from VECTOR which was created by
7361 with_echo_area_buffer_unwind_data. */
7362
7363 static Lisp_Object
7364 unwind_with_echo_area_buffer (vector)
7365 Lisp_Object vector;
7366 {
7367 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7368 Vdeactivate_mark = AREF (vector, 1);
7369 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7370
7371 if (WINDOWP (AREF (vector, 3)))
7372 {
7373 struct window *w;
7374 Lisp_Object buffer, charpos, bytepos;
7375
7376 w = XWINDOW (AREF (vector, 3));
7377 buffer = AREF (vector, 4);
7378 charpos = AREF (vector, 5);
7379 bytepos = AREF (vector, 6);
7380
7381 w->buffer = buffer;
7382 set_marker_both (w->pointm, buffer,
7383 XFASTINT (charpos), XFASTINT (bytepos));
7384 }
7385
7386 Vwith_echo_area_save_vector = vector;
7387 return Qnil;
7388 }
7389
7390
7391 /* Set up the echo area for use by print functions. MULTIBYTE_P
7392 non-zero means we will print multibyte. */
7393
7394 void
7395 setup_echo_area_for_printing (multibyte_p)
7396 int multibyte_p;
7397 {
7398 /* If we can't find an echo area any more, exit. */
7399 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7400 Fkill_emacs (Qnil);
7401
7402 ensure_echo_area_buffers ();
7403
7404 if (!message_buf_print)
7405 {
7406 /* A message has been output since the last time we printed.
7407 Choose a fresh echo area buffer. */
7408 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7409 echo_area_buffer[0] = echo_buffer[1];
7410 else
7411 echo_area_buffer[0] = echo_buffer[0];
7412
7413 /* Switch to that buffer and clear it. */
7414 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7415 current_buffer->truncate_lines = Qnil;
7416
7417 if (Z > BEG)
7418 {
7419 int count = SPECPDL_INDEX ();
7420 specbind (Qinhibit_read_only, Qt);
7421 /* Note that undo recording is always disabled. */
7422 del_range (BEG, Z);
7423 unbind_to (count, Qnil);
7424 }
7425 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7426
7427 /* Set up the buffer for the multibyteness we need. */
7428 if (multibyte_p
7429 != !NILP (current_buffer->enable_multibyte_characters))
7430 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7431
7432 /* Raise the frame containing the echo area. */
7433 if (minibuffer_auto_raise)
7434 {
7435 struct frame *sf = SELECTED_FRAME ();
7436 Lisp_Object mini_window;
7437 mini_window = FRAME_MINIBUF_WINDOW (sf);
7438 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7439 }
7440
7441 message_log_maybe_newline ();
7442 message_buf_print = 1;
7443 }
7444 else
7445 {
7446 if (NILP (echo_area_buffer[0]))
7447 {
7448 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7449 echo_area_buffer[0] = echo_buffer[1];
7450 else
7451 echo_area_buffer[0] = echo_buffer[0];
7452 }
7453
7454 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7455 {
7456 /* Someone switched buffers between print requests. */
7457 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7458 current_buffer->truncate_lines = Qnil;
7459 }
7460 }
7461 }
7462
7463
7464 /* Display an echo area message in window W. Value is non-zero if W's
7465 height is changed. If display_last_displayed_message_p is
7466 non-zero, display the message that was last displayed, otherwise
7467 display the current message. */
7468
7469 static int
7470 display_echo_area (w)
7471 struct window *w;
7472 {
7473 int i, no_message_p, window_height_changed_p, count;
7474
7475 /* Temporarily disable garbage collections while displaying the echo
7476 area. This is done because a GC can print a message itself.
7477 That message would modify the echo area buffer's contents while a
7478 redisplay of the buffer is going on, and seriously confuse
7479 redisplay. */
7480 count = inhibit_garbage_collection ();
7481
7482 /* If there is no message, we must call display_echo_area_1
7483 nevertheless because it resizes the window. But we will have to
7484 reset the echo_area_buffer in question to nil at the end because
7485 with_echo_area_buffer will sets it to an empty buffer. */
7486 i = display_last_displayed_message_p ? 1 : 0;
7487 no_message_p = NILP (echo_area_buffer[i]);
7488
7489 window_height_changed_p
7490 = with_echo_area_buffer (w, display_last_displayed_message_p,
7491 display_echo_area_1,
7492 (EMACS_INT) w, Qnil, 0, 0);
7493
7494 if (no_message_p)
7495 echo_area_buffer[i] = Qnil;
7496
7497 unbind_to (count, Qnil);
7498 return window_height_changed_p;
7499 }
7500
7501
7502 /* Helper for display_echo_area. Display the current buffer which
7503 contains the current echo area message in window W, a mini-window,
7504 a pointer to which is passed in A1. A2..A4 are currently not used.
7505 Change the height of W so that all of the message is displayed.
7506 Value is non-zero if height of W was changed. */
7507
7508 static int
7509 display_echo_area_1 (a1, a2, a3, a4)
7510 EMACS_INT a1;
7511 Lisp_Object a2;
7512 EMACS_INT a3, a4;
7513 {
7514 struct window *w = (struct window *) a1;
7515 Lisp_Object window;
7516 struct text_pos start;
7517 int window_height_changed_p = 0;
7518
7519 /* Do this before displaying, so that we have a large enough glyph
7520 matrix for the display. */
7521 window_height_changed_p = resize_mini_window (w, 0);
7522
7523 /* Display. */
7524 clear_glyph_matrix (w->desired_matrix);
7525 XSETWINDOW (window, w);
7526 SET_TEXT_POS (start, BEG, BEG_BYTE);
7527 try_window (window, start);
7528
7529 return window_height_changed_p;
7530 }
7531
7532
7533 /* Resize the echo area window to exactly the size needed for the
7534 currently displayed message, if there is one. If a mini-buffer
7535 is active, don't shrink it. */
7536
7537 void
7538 resize_echo_area_exactly ()
7539 {
7540 if (BUFFERP (echo_area_buffer[0])
7541 && WINDOWP (echo_area_window))
7542 {
7543 struct window *w = XWINDOW (echo_area_window);
7544 int resized_p;
7545 Lisp_Object resize_exactly;
7546
7547 if (minibuf_level == 0)
7548 resize_exactly = Qt;
7549 else
7550 resize_exactly = Qnil;
7551
7552 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7553 (EMACS_INT) w, resize_exactly, 0, 0);
7554 if (resized_p)
7555 {
7556 ++windows_or_buffers_changed;
7557 ++update_mode_lines;
7558 redisplay_internal (0);
7559 }
7560 }
7561 }
7562
7563
7564 /* Callback function for with_echo_area_buffer, when used from
7565 resize_echo_area_exactly. A1 contains a pointer to the window to
7566 resize, EXACTLY non-nil means resize the mini-window exactly to the
7567 size of the text displayed. A3 and A4 are not used. Value is what
7568 resize_mini_window returns. */
7569
7570 static int
7571 resize_mini_window_1 (a1, exactly, a3, a4)
7572 EMACS_INT a1;
7573 Lisp_Object exactly;
7574 EMACS_INT a3, a4;
7575 {
7576 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7577 }
7578
7579
7580 /* Resize mini-window W to fit the size of its contents. EXACT:P
7581 means size the window exactly to the size needed. Otherwise, it's
7582 only enlarged until W's buffer is empty. Value is non-zero if
7583 the window height has been changed. */
7584
7585 int
7586 resize_mini_window (w, exact_p)
7587 struct window *w;
7588 int exact_p;
7589 {
7590 struct frame *f = XFRAME (w->frame);
7591 int window_height_changed_p = 0;
7592
7593 xassert (MINI_WINDOW_P (w));
7594
7595 /* Don't resize windows while redisplaying a window; it would
7596 confuse redisplay functions when the size of the window they are
7597 displaying changes from under them. Such a resizing can happen,
7598 for instance, when which-func prints a long message while
7599 we are running fontification-functions. We're running these
7600 functions with safe_call which binds inhibit-redisplay to t. */
7601 if (!NILP (Vinhibit_redisplay))
7602 return 0;
7603
7604 /* Nil means don't try to resize. */
7605 if (NILP (Vresize_mini_windows)
7606 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7607 return 0;
7608
7609 if (!FRAME_MINIBUF_ONLY_P (f))
7610 {
7611 struct it it;
7612 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7613 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7614 int height, max_height;
7615 int unit = FRAME_LINE_HEIGHT (f);
7616 struct text_pos start;
7617 struct buffer *old_current_buffer = NULL;
7618
7619 if (current_buffer != XBUFFER (w->buffer))
7620 {
7621 old_current_buffer = current_buffer;
7622 set_buffer_internal (XBUFFER (w->buffer));
7623 }
7624
7625 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7626
7627 /* Compute the max. number of lines specified by the user. */
7628 if (FLOATP (Vmax_mini_window_height))
7629 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7630 else if (INTEGERP (Vmax_mini_window_height))
7631 max_height = XINT (Vmax_mini_window_height);
7632 else
7633 max_height = total_height / 4;
7634
7635 /* Correct that max. height if it's bogus. */
7636 max_height = max (1, max_height);
7637 max_height = min (total_height, max_height);
7638
7639 /* Find out the height of the text in the window. */
7640 if (it.truncate_lines_p)
7641 height = 1;
7642 else
7643 {
7644 last_height = 0;
7645 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7646 if (it.max_ascent == 0 && it.max_descent == 0)
7647 height = it.current_y + last_height;
7648 else
7649 height = it.current_y + it.max_ascent + it.max_descent;
7650 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
7651 height = (height + unit - 1) / unit;
7652 }
7653
7654 /* Compute a suitable window start. */
7655 if (height > max_height)
7656 {
7657 height = max_height;
7658 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7659 move_it_vertically_backward (&it, (height - 1) * unit);
7660 start = it.current.pos;
7661 }
7662 else
7663 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7664 SET_MARKER_FROM_TEXT_POS (w->start, start);
7665
7666 if (EQ (Vresize_mini_windows, Qgrow_only))
7667 {
7668 /* Let it grow only, until we display an empty message, in which
7669 case the window shrinks again. */
7670 if (height > WINDOW_TOTAL_LINES (w))
7671 {
7672 int old_height = WINDOW_TOTAL_LINES (w);
7673 freeze_window_starts (f, 1);
7674 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7675 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7676 }
7677 else if (height < WINDOW_TOTAL_LINES (w)
7678 && (exact_p || BEGV == ZV))
7679 {
7680 int old_height = WINDOW_TOTAL_LINES (w);
7681 freeze_window_starts (f, 0);
7682 shrink_mini_window (w);
7683 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7684 }
7685 }
7686 else
7687 {
7688 /* Always resize to exact size needed. */
7689 if (height > WINDOW_TOTAL_LINES (w))
7690 {
7691 int old_height = WINDOW_TOTAL_LINES (w);
7692 freeze_window_starts (f, 1);
7693 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7694 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7695 }
7696 else if (height < WINDOW_TOTAL_LINES (w))
7697 {
7698 int old_height = WINDOW_TOTAL_LINES (w);
7699 freeze_window_starts (f, 0);
7700 shrink_mini_window (w);
7701
7702 if (height)
7703 {
7704 freeze_window_starts (f, 1);
7705 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7706 }
7707
7708 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7709 }
7710 }
7711
7712 if (old_current_buffer)
7713 set_buffer_internal (old_current_buffer);
7714 }
7715
7716 return window_height_changed_p;
7717 }
7718
7719
7720 /* Value is the current message, a string, or nil if there is no
7721 current message. */
7722
7723 Lisp_Object
7724 current_message ()
7725 {
7726 Lisp_Object msg;
7727
7728 if (NILP (echo_area_buffer[0]))
7729 msg = Qnil;
7730 else
7731 {
7732 with_echo_area_buffer (0, 0, current_message_1,
7733 (EMACS_INT) &msg, Qnil, 0, 0);
7734 if (NILP (msg))
7735 echo_area_buffer[0] = Qnil;
7736 }
7737
7738 return msg;
7739 }
7740
7741
7742 static int
7743 current_message_1 (a1, a2, a3, a4)
7744 EMACS_INT a1;
7745 Lisp_Object a2;
7746 EMACS_INT a3, a4;
7747 {
7748 Lisp_Object *msg = (Lisp_Object *) a1;
7749
7750 if (Z > BEG)
7751 *msg = make_buffer_string (BEG, Z, 1);
7752 else
7753 *msg = Qnil;
7754 return 0;
7755 }
7756
7757
7758 /* Push the current message on Vmessage_stack for later restauration
7759 by restore_message. Value is non-zero if the current message isn't
7760 empty. This is a relatively infrequent operation, so it's not
7761 worth optimizing. */
7762
7763 int
7764 push_message ()
7765 {
7766 Lisp_Object msg;
7767 msg = current_message ();
7768 Vmessage_stack = Fcons (msg, Vmessage_stack);
7769 return STRINGP (msg);
7770 }
7771
7772
7773 /* Restore message display from the top of Vmessage_stack. */
7774
7775 void
7776 restore_message ()
7777 {
7778 Lisp_Object msg;
7779
7780 xassert (CONSP (Vmessage_stack));
7781 msg = XCAR (Vmessage_stack);
7782 if (STRINGP (msg))
7783 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7784 else
7785 message3_nolog (msg, 0, 0);
7786 }
7787
7788
7789 /* Handler for record_unwind_protect calling pop_message. */
7790
7791 Lisp_Object
7792 pop_message_unwind (dummy)
7793 Lisp_Object dummy;
7794 {
7795 pop_message ();
7796 return Qnil;
7797 }
7798
7799 /* Pop the top-most entry off Vmessage_stack. */
7800
7801 void
7802 pop_message ()
7803 {
7804 xassert (CONSP (Vmessage_stack));
7805 Vmessage_stack = XCDR (Vmessage_stack);
7806 }
7807
7808
7809 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7810 exits. If the stack is not empty, we have a missing pop_message
7811 somewhere. */
7812
7813 void
7814 check_message_stack ()
7815 {
7816 if (!NILP (Vmessage_stack))
7817 abort ();
7818 }
7819
7820
7821 /* Truncate to NCHARS what will be displayed in the echo area the next
7822 time we display it---but don't redisplay it now. */
7823
7824 void
7825 truncate_echo_area (nchars)
7826 int nchars;
7827 {
7828 if (nchars == 0)
7829 echo_area_buffer[0] = Qnil;
7830 /* A null message buffer means that the frame hasn't really been
7831 initialized yet. Error messages get reported properly by
7832 cmd_error, so this must be just an informative message; toss it. */
7833 else if (!noninteractive
7834 && INTERACTIVE
7835 && !NILP (echo_area_buffer[0]))
7836 {
7837 struct frame *sf = SELECTED_FRAME ();
7838 if (FRAME_MESSAGE_BUF (sf))
7839 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7840 }
7841 }
7842
7843
7844 /* Helper function for truncate_echo_area. Truncate the current
7845 message to at most NCHARS characters. */
7846
7847 static int
7848 truncate_message_1 (nchars, a2, a3, a4)
7849 EMACS_INT nchars;
7850 Lisp_Object a2;
7851 EMACS_INT a3, a4;
7852 {
7853 if (BEG + nchars < Z)
7854 del_range (BEG + nchars, Z);
7855 if (Z == BEG)
7856 echo_area_buffer[0] = Qnil;
7857 return 0;
7858 }
7859
7860
7861 /* Set the current message to a substring of S or STRING.
7862
7863 If STRING is a Lisp string, set the message to the first NBYTES
7864 bytes from STRING. NBYTES zero means use the whole string. If
7865 STRING is multibyte, the message will be displayed multibyte.
7866
7867 If S is not null, set the message to the first LEN bytes of S. LEN
7868 zero means use the whole string. MULTIBYTE_P non-zero means S is
7869 multibyte. Display the message multibyte in that case. */
7870
7871 void
7872 set_message (s, string, nbytes, multibyte_p)
7873 const char *s;
7874 Lisp_Object string;
7875 int nbytes, multibyte_p;
7876 {
7877 message_enable_multibyte
7878 = ((s && multibyte_p)
7879 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7880
7881 with_echo_area_buffer (0, 0, set_message_1,
7882 (EMACS_INT) s, string, nbytes, multibyte_p);
7883 message_buf_print = 0;
7884 help_echo_showing_p = 0;
7885 }
7886
7887
7888 /* Helper function for set_message. Arguments have the same meaning
7889 as there, with A1 corresponding to S and A2 corresponding to STRING
7890 This function is called with the echo area buffer being
7891 current. */
7892
7893 static int
7894 set_message_1 (a1, a2, nbytes, multibyte_p)
7895 EMACS_INT a1;
7896 Lisp_Object a2;
7897 EMACS_INT nbytes, multibyte_p;
7898 {
7899 const char *s = (const char *) a1;
7900 Lisp_Object string = a2;
7901
7902 xassert (BEG == Z);
7903
7904 /* Change multibyteness of the echo buffer appropriately. */
7905 if (message_enable_multibyte
7906 != !NILP (current_buffer->enable_multibyte_characters))
7907 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7908
7909 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7910
7911 /* Insert new message at BEG. */
7912 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7913 Ferase_buffer ();
7914
7915 if (STRINGP (string))
7916 {
7917 int nchars;
7918
7919 if (nbytes == 0)
7920 nbytes = SBYTES (string);
7921 nchars = string_byte_to_char (string, nbytes);
7922
7923 /* This function takes care of single/multibyte conversion. We
7924 just have to ensure that the echo area buffer has the right
7925 setting of enable_multibyte_characters. */
7926 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7927 }
7928 else if (s)
7929 {
7930 if (nbytes == 0)
7931 nbytes = strlen (s);
7932
7933 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7934 {
7935 /* Convert from multi-byte to single-byte. */
7936 int i, c, n;
7937 unsigned char work[1];
7938
7939 /* Convert a multibyte string to single-byte. */
7940 for (i = 0; i < nbytes; i += n)
7941 {
7942 c = string_char_and_length (s + i, nbytes - i, &n);
7943 work[0] = (SINGLE_BYTE_CHAR_P (c)
7944 ? c
7945 : multibyte_char_to_unibyte (c, Qnil));
7946 insert_1_both (work, 1, 1, 1, 0, 0);
7947 }
7948 }
7949 else if (!multibyte_p
7950 && !NILP (current_buffer->enable_multibyte_characters))
7951 {
7952 /* Convert from single-byte to multi-byte. */
7953 int i, c, n;
7954 const unsigned char *msg = (const unsigned char *) s;
7955 unsigned char str[MAX_MULTIBYTE_LENGTH];
7956
7957 /* Convert a single-byte string to multibyte. */
7958 for (i = 0; i < nbytes; i++)
7959 {
7960 c = unibyte_char_to_multibyte (msg[i]);
7961 n = CHAR_STRING (c, str);
7962 insert_1_both (str, 1, n, 1, 0, 0);
7963 }
7964 }
7965 else
7966 insert_1 (s, nbytes, 1, 0, 0);
7967 }
7968
7969 return 0;
7970 }
7971
7972
7973 /* Clear messages. CURRENT_P non-zero means clear the current
7974 message. LAST_DISPLAYED_P non-zero means clear the message
7975 last displayed. */
7976
7977 void
7978 clear_message (current_p, last_displayed_p)
7979 int current_p, last_displayed_p;
7980 {
7981 if (current_p)
7982 {
7983 echo_area_buffer[0] = Qnil;
7984 message_cleared_p = 1;
7985 }
7986
7987 if (last_displayed_p)
7988 echo_area_buffer[1] = Qnil;
7989
7990 message_buf_print = 0;
7991 }
7992
7993 /* Clear garbaged frames.
7994
7995 This function is used where the old redisplay called
7996 redraw_garbaged_frames which in turn called redraw_frame which in
7997 turn called clear_frame. The call to clear_frame was a source of
7998 flickering. I believe a clear_frame is not necessary. It should
7999 suffice in the new redisplay to invalidate all current matrices,
8000 and ensure a complete redisplay of all windows. */
8001
8002 static void
8003 clear_garbaged_frames ()
8004 {
8005 if (frame_garbaged)
8006 {
8007 Lisp_Object tail, frame;
8008 int changed_count = 0;
8009
8010 FOR_EACH_FRAME (tail, frame)
8011 {
8012 struct frame *f = XFRAME (frame);
8013
8014 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8015 {
8016 if (f->resized_p)
8017 {
8018 Fredraw_frame (frame);
8019 f->force_flush_display_p = 1;
8020 }
8021 clear_current_matrices (f);
8022 changed_count++;
8023 f->garbaged = 0;
8024 f->resized_p = 0;
8025 }
8026 }
8027
8028 frame_garbaged = 0;
8029 if (changed_count)
8030 ++windows_or_buffers_changed;
8031 }
8032 }
8033
8034
8035 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8036 is non-zero update selected_frame. Value is non-zero if the
8037 mini-windows height has been changed. */
8038
8039 static int
8040 echo_area_display (update_frame_p)
8041 int update_frame_p;
8042 {
8043 Lisp_Object mini_window;
8044 struct window *w;
8045 struct frame *f;
8046 int window_height_changed_p = 0;
8047 struct frame *sf = SELECTED_FRAME ();
8048
8049 mini_window = FRAME_MINIBUF_WINDOW (sf);
8050 w = XWINDOW (mini_window);
8051 f = XFRAME (WINDOW_FRAME (w));
8052
8053 /* Don't display if frame is invisible or not yet initialized. */
8054 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8055 return 0;
8056
8057 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8058 #ifndef MAC_OS8
8059 #ifdef HAVE_WINDOW_SYSTEM
8060 /* When Emacs starts, selected_frame may be a visible terminal
8061 frame, even if we run under a window system. If we let this
8062 through, a message would be displayed on the terminal. */
8063 if (EQ (selected_frame, Vterminal_frame)
8064 && !NILP (Vwindow_system))
8065 return 0;
8066 #endif /* HAVE_WINDOW_SYSTEM */
8067 #endif
8068
8069 /* Redraw garbaged frames. */
8070 if (frame_garbaged)
8071 clear_garbaged_frames ();
8072
8073 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8074 {
8075 echo_area_window = mini_window;
8076 window_height_changed_p = display_echo_area (w);
8077 w->must_be_updated_p = 1;
8078
8079 /* Update the display, unless called from redisplay_internal.
8080 Also don't update the screen during redisplay itself. The
8081 update will happen at the end of redisplay, and an update
8082 here could cause confusion. */
8083 if (update_frame_p && !redisplaying_p)
8084 {
8085 int n = 0;
8086
8087 /* If the display update has been interrupted by pending
8088 input, update mode lines in the frame. Due to the
8089 pending input, it might have been that redisplay hasn't
8090 been called, so that mode lines above the echo area are
8091 garbaged. This looks odd, so we prevent it here. */
8092 if (!display_completed)
8093 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8094
8095 if (window_height_changed_p
8096 /* Don't do this if Emacs is shutting down. Redisplay
8097 needs to run hooks. */
8098 && !NILP (Vrun_hooks))
8099 {
8100 /* Must update other windows. Likewise as in other
8101 cases, don't let this update be interrupted by
8102 pending input. */
8103 int count = SPECPDL_INDEX ();
8104 specbind (Qredisplay_dont_pause, Qt);
8105 windows_or_buffers_changed = 1;
8106 redisplay_internal (0);
8107 unbind_to (count, Qnil);
8108 }
8109 else if (FRAME_WINDOW_P (f) && n == 0)
8110 {
8111 /* Window configuration is the same as before.
8112 Can do with a display update of the echo area,
8113 unless we displayed some mode lines. */
8114 update_single_window (w, 1);
8115 rif->flush_display (f);
8116 }
8117 else
8118 update_frame (f, 1, 1);
8119
8120 /* If cursor is in the echo area, make sure that the next
8121 redisplay displays the minibuffer, so that the cursor will
8122 be replaced with what the minibuffer wants. */
8123 if (cursor_in_echo_area)
8124 ++windows_or_buffers_changed;
8125 }
8126 }
8127 else if (!EQ (mini_window, selected_window))
8128 windows_or_buffers_changed++;
8129
8130 /* The current message is now also the last one displayed. */
8131 echo_area_buffer[1] = echo_area_buffer[0];
8132
8133 /* Prevent redisplay optimization in redisplay_internal by resetting
8134 this_line_start_pos. This is done because the mini-buffer now
8135 displays the message instead of its buffer text. */
8136 if (EQ (mini_window, selected_window))
8137 CHARPOS (this_line_start_pos) = 0;
8138
8139 return window_height_changed_p;
8140 }
8141
8142
8143 \f
8144 /***********************************************************************
8145 Frame Titles
8146 ***********************************************************************/
8147
8148
8149 /* The frame title buffering code is also used by Fformat_mode_line.
8150 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
8151
8152 /* A buffer for constructing frame titles in it; allocated from the
8153 heap in init_xdisp and resized as needed in store_frame_title_char. */
8154
8155 static char *frame_title_buf;
8156
8157 /* The buffer's end, and a current output position in it. */
8158
8159 static char *frame_title_buf_end;
8160 static char *frame_title_ptr;
8161
8162
8163 /* Store a single character C for the frame title in frame_title_buf.
8164 Re-allocate frame_title_buf if necessary. */
8165
8166 static void
8167 #ifdef PROTOTYPES
8168 store_frame_title_char (char c)
8169 #else
8170 store_frame_title_char (c)
8171 char c;
8172 #endif
8173 {
8174 /* If output position has reached the end of the allocated buffer,
8175 double the buffer's size. */
8176 if (frame_title_ptr == frame_title_buf_end)
8177 {
8178 int len = frame_title_ptr - frame_title_buf;
8179 int new_size = 2 * len * sizeof *frame_title_buf;
8180 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
8181 frame_title_buf_end = frame_title_buf + new_size;
8182 frame_title_ptr = frame_title_buf + len;
8183 }
8184
8185 *frame_title_ptr++ = c;
8186 }
8187
8188
8189 /* Store part of a frame title in frame_title_buf, beginning at
8190 frame_title_ptr. STR is the string to store. Do not copy
8191 characters that yield more columns than PRECISION; PRECISION <= 0
8192 means copy the whole string. Pad with spaces until FIELD_WIDTH
8193 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8194 pad. Called from display_mode_element when it is used to build a
8195 frame title. */
8196
8197 static int
8198 store_frame_title (str, field_width, precision)
8199 const unsigned char *str;
8200 int field_width, precision;
8201 {
8202 int n = 0;
8203 int dummy, nbytes;
8204
8205 /* Copy at most PRECISION chars from STR. */
8206 nbytes = strlen (str);
8207 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8208 while (nbytes--)
8209 store_frame_title_char (*str++);
8210
8211 /* Fill up with spaces until FIELD_WIDTH reached. */
8212 while (field_width > 0
8213 && n < field_width)
8214 {
8215 store_frame_title_char (' ');
8216 ++n;
8217 }
8218
8219 return n;
8220 }
8221
8222 #ifdef HAVE_WINDOW_SYSTEM
8223
8224 /* Set the title of FRAME, if it has changed. The title format is
8225 Vicon_title_format if FRAME is iconified, otherwise it is
8226 frame_title_format. */
8227
8228 static void
8229 x_consider_frame_title (frame)
8230 Lisp_Object frame;
8231 {
8232 struct frame *f = XFRAME (frame);
8233
8234 if (FRAME_WINDOW_P (f)
8235 || FRAME_MINIBUF_ONLY_P (f)
8236 || f->explicit_name)
8237 {
8238 /* Do we have more than one visible frame on this X display? */
8239 Lisp_Object tail;
8240 Lisp_Object fmt;
8241 struct buffer *obuf;
8242 int len;
8243 struct it it;
8244
8245 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8246 {
8247 Lisp_Object other_frame = XCAR (tail);
8248 struct frame *tf = XFRAME (other_frame);
8249
8250 if (tf != f
8251 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8252 && !FRAME_MINIBUF_ONLY_P (tf)
8253 && !EQ (other_frame, tip_frame)
8254 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8255 break;
8256 }
8257
8258 /* Set global variable indicating that multiple frames exist. */
8259 multiple_frames = CONSP (tail);
8260
8261 /* Switch to the buffer of selected window of the frame. Set up
8262 frame_title_ptr so that display_mode_element will output into it;
8263 then display the title. */
8264 obuf = current_buffer;
8265 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8266 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8267 frame_title_ptr = frame_title_buf;
8268 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8269 NULL, DEFAULT_FACE_ID);
8270 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8271 len = frame_title_ptr - frame_title_buf;
8272 frame_title_ptr = NULL;
8273 set_buffer_internal_1 (obuf);
8274
8275 /* Set the title only if it's changed. This avoids consing in
8276 the common case where it hasn't. (If it turns out that we've
8277 already wasted too much time by walking through the list with
8278 display_mode_element, then we might need to optimize at a
8279 higher level than this.) */
8280 if (! STRINGP (f->name)
8281 || SBYTES (f->name) != len
8282 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8283 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8284 }
8285 }
8286
8287 #endif /* not HAVE_WINDOW_SYSTEM */
8288
8289
8290
8291 \f
8292 /***********************************************************************
8293 Menu Bars
8294 ***********************************************************************/
8295
8296
8297 /* Prepare for redisplay by updating menu-bar item lists when
8298 appropriate. This can call eval. */
8299
8300 void
8301 prepare_menu_bars ()
8302 {
8303 int all_windows;
8304 struct gcpro gcpro1, gcpro2;
8305 struct frame *f;
8306 Lisp_Object tooltip_frame;
8307
8308 #ifdef HAVE_WINDOW_SYSTEM
8309 tooltip_frame = tip_frame;
8310 #else
8311 tooltip_frame = Qnil;
8312 #endif
8313
8314 /* Update all frame titles based on their buffer names, etc. We do
8315 this before the menu bars so that the buffer-menu will show the
8316 up-to-date frame titles. */
8317 #ifdef HAVE_WINDOW_SYSTEM
8318 if (windows_or_buffers_changed || update_mode_lines)
8319 {
8320 Lisp_Object tail, frame;
8321
8322 FOR_EACH_FRAME (tail, frame)
8323 {
8324 f = XFRAME (frame);
8325 if (!EQ (frame, tooltip_frame)
8326 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8327 x_consider_frame_title (frame);
8328 }
8329 }
8330 #endif /* HAVE_WINDOW_SYSTEM */
8331
8332 /* Update the menu bar item lists, if appropriate. This has to be
8333 done before any actual redisplay or generation of display lines. */
8334 all_windows = (update_mode_lines
8335 || buffer_shared > 1
8336 || windows_or_buffers_changed);
8337 if (all_windows)
8338 {
8339 Lisp_Object tail, frame;
8340 int count = SPECPDL_INDEX ();
8341
8342 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8343
8344 FOR_EACH_FRAME (tail, frame)
8345 {
8346 f = XFRAME (frame);
8347
8348 /* Ignore tooltip frame. */
8349 if (EQ (frame, tooltip_frame))
8350 continue;
8351
8352 /* If a window on this frame changed size, report that to
8353 the user and clear the size-change flag. */
8354 if (FRAME_WINDOW_SIZES_CHANGED (f))
8355 {
8356 Lisp_Object functions;
8357
8358 /* Clear flag first in case we get an error below. */
8359 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8360 functions = Vwindow_size_change_functions;
8361 GCPRO2 (tail, functions);
8362
8363 while (CONSP (functions))
8364 {
8365 call1 (XCAR (functions), frame);
8366 functions = XCDR (functions);
8367 }
8368 UNGCPRO;
8369 }
8370
8371 GCPRO1 (tail);
8372 update_menu_bar (f, 0);
8373 #ifdef HAVE_WINDOW_SYSTEM
8374 update_tool_bar (f, 0);
8375 #endif
8376 UNGCPRO;
8377 }
8378
8379 unbind_to (count, Qnil);
8380 }
8381 else
8382 {
8383 struct frame *sf = SELECTED_FRAME ();
8384 update_menu_bar (sf, 1);
8385 #ifdef HAVE_WINDOW_SYSTEM
8386 update_tool_bar (sf, 1);
8387 #endif
8388 }
8389
8390 /* Motif needs this. See comment in xmenu.c. Turn it off when
8391 pending_menu_activation is not defined. */
8392 #ifdef USE_X_TOOLKIT
8393 pending_menu_activation = 0;
8394 #endif
8395 }
8396
8397
8398 /* Update the menu bar item list for frame F. This has to be done
8399 before we start to fill in any display lines, because it can call
8400 eval.
8401
8402 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8403
8404 static void
8405 update_menu_bar (f, save_match_data)
8406 struct frame *f;
8407 int save_match_data;
8408 {
8409 Lisp_Object window;
8410 register struct window *w;
8411
8412 /* If called recursively during a menu update, do nothing. This can
8413 happen when, for instance, an activate-menubar-hook causes a
8414 redisplay. */
8415 if (inhibit_menubar_update)
8416 return;
8417
8418 window = FRAME_SELECTED_WINDOW (f);
8419 w = XWINDOW (window);
8420
8421 #if 0 /* The if statement below this if statement used to include the
8422 condition !NILP (w->update_mode_line), rather than using
8423 update_mode_lines directly, and this if statement may have
8424 been added to make that condition work. Now the if
8425 statement below matches its comment, this isn't needed. */
8426 if (update_mode_lines)
8427 w->update_mode_line = Qt;
8428 #endif
8429
8430 if (FRAME_WINDOW_P (f)
8431 ?
8432 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8433 || defined (USE_GTK)
8434 FRAME_EXTERNAL_MENU_BAR (f)
8435 #else
8436 FRAME_MENU_BAR_LINES (f) > 0
8437 #endif
8438 : FRAME_MENU_BAR_LINES (f) > 0)
8439 {
8440 /* If the user has switched buffers or windows, we need to
8441 recompute to reflect the new bindings. But we'll
8442 recompute when update_mode_lines is set too; that means
8443 that people can use force-mode-line-update to request
8444 that the menu bar be recomputed. The adverse effect on
8445 the rest of the redisplay algorithm is about the same as
8446 windows_or_buffers_changed anyway. */
8447 if (windows_or_buffers_changed
8448 /* This used to test w->update_mode_line, but we believe
8449 there is no need to recompute the menu in that case. */
8450 || update_mode_lines
8451 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8452 < BUF_MODIFF (XBUFFER (w->buffer)))
8453 != !NILP (w->last_had_star))
8454 || ((!NILP (Vtransient_mark_mode)
8455 && !NILP (XBUFFER (w->buffer)->mark_active))
8456 != !NILP (w->region_showing)))
8457 {
8458 struct buffer *prev = current_buffer;
8459 int count = SPECPDL_INDEX ();
8460
8461 specbind (Qinhibit_menubar_update, Qt);
8462
8463 set_buffer_internal_1 (XBUFFER (w->buffer));
8464 if (save_match_data)
8465 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8466 if (NILP (Voverriding_local_map_menu_flag))
8467 {
8468 specbind (Qoverriding_terminal_local_map, Qnil);
8469 specbind (Qoverriding_local_map, Qnil);
8470 }
8471
8472 /* Run the Lucid hook. */
8473 safe_run_hooks (Qactivate_menubar_hook);
8474
8475 /* If it has changed current-menubar from previous value,
8476 really recompute the menu-bar from the value. */
8477 if (! NILP (Vlucid_menu_bar_dirty_flag))
8478 call0 (Qrecompute_lucid_menubar);
8479
8480 safe_run_hooks (Qmenu_bar_update_hook);
8481 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8482
8483 /* Redisplay the menu bar in case we changed it. */
8484 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8485 || defined (USE_GTK)
8486 if (FRAME_WINDOW_P (f)
8487 #if defined (MAC_OS)
8488 /* All frames on Mac OS share the same menubar. So only the
8489 selected frame should be allowed to set it. */
8490 && f == SELECTED_FRAME ()
8491 #endif
8492 )
8493 set_frame_menubar (f, 0, 0);
8494 else
8495 /* On a terminal screen, the menu bar is an ordinary screen
8496 line, and this makes it get updated. */
8497 w->update_mode_line = Qt;
8498 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8499 /* In the non-toolkit version, the menu bar is an ordinary screen
8500 line, and this makes it get updated. */
8501 w->update_mode_line = Qt;
8502 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8503
8504 unbind_to (count, Qnil);
8505 set_buffer_internal_1 (prev);
8506 }
8507 }
8508 }
8509
8510
8511 \f
8512 /***********************************************************************
8513 Output Cursor
8514 ***********************************************************************/
8515
8516 #ifdef HAVE_WINDOW_SYSTEM
8517
8518 /* EXPORT:
8519 Nominal cursor position -- where to draw output.
8520 HPOS and VPOS are window relative glyph matrix coordinates.
8521 X and Y are window relative pixel coordinates. */
8522
8523 struct cursor_pos output_cursor;
8524
8525
8526 /* EXPORT:
8527 Set the global variable output_cursor to CURSOR. All cursor
8528 positions are relative to updated_window. */
8529
8530 void
8531 set_output_cursor (cursor)
8532 struct cursor_pos *cursor;
8533 {
8534 output_cursor.hpos = cursor->hpos;
8535 output_cursor.vpos = cursor->vpos;
8536 output_cursor.x = cursor->x;
8537 output_cursor.y = cursor->y;
8538 }
8539
8540
8541 /* EXPORT for RIF:
8542 Set a nominal cursor position.
8543
8544 HPOS and VPOS are column/row positions in a window glyph matrix. X
8545 and Y are window text area relative pixel positions.
8546
8547 If this is done during an update, updated_window will contain the
8548 window that is being updated and the position is the future output
8549 cursor position for that window. If updated_window is null, use
8550 selected_window and display the cursor at the given position. */
8551
8552 void
8553 x_cursor_to (vpos, hpos, y, x)
8554 int vpos, hpos, y, x;
8555 {
8556 struct window *w;
8557
8558 /* If updated_window is not set, work on selected_window. */
8559 if (updated_window)
8560 w = updated_window;
8561 else
8562 w = XWINDOW (selected_window);
8563
8564 /* Set the output cursor. */
8565 output_cursor.hpos = hpos;
8566 output_cursor.vpos = vpos;
8567 output_cursor.x = x;
8568 output_cursor.y = y;
8569
8570 /* If not called as part of an update, really display the cursor.
8571 This will also set the cursor position of W. */
8572 if (updated_window == NULL)
8573 {
8574 BLOCK_INPUT;
8575 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8576 if (rif->flush_display_optional)
8577 rif->flush_display_optional (SELECTED_FRAME ());
8578 UNBLOCK_INPUT;
8579 }
8580 }
8581
8582 #endif /* HAVE_WINDOW_SYSTEM */
8583
8584 \f
8585 /***********************************************************************
8586 Tool-bars
8587 ***********************************************************************/
8588
8589 #ifdef HAVE_WINDOW_SYSTEM
8590
8591 /* Where the mouse was last time we reported a mouse event. */
8592
8593 FRAME_PTR last_mouse_frame;
8594
8595 /* Tool-bar item index of the item on which a mouse button was pressed
8596 or -1. */
8597
8598 int last_tool_bar_item;
8599
8600
8601 /* Update the tool-bar item list for frame F. This has to be done
8602 before we start to fill in any display lines. Called from
8603 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8604 and restore it here. */
8605
8606 static void
8607 update_tool_bar (f, save_match_data)
8608 struct frame *f;
8609 int save_match_data;
8610 {
8611 #ifdef USE_GTK
8612 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8613 #else
8614 int do_update = WINDOWP (f->tool_bar_window)
8615 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8616 #endif
8617
8618 if (do_update)
8619 {
8620 Lisp_Object window;
8621 struct window *w;
8622
8623 window = FRAME_SELECTED_WINDOW (f);
8624 w = XWINDOW (window);
8625
8626 /* If the user has switched buffers or windows, we need to
8627 recompute to reflect the new bindings. But we'll
8628 recompute when update_mode_lines is set too; that means
8629 that people can use force-mode-line-update to request
8630 that the menu bar be recomputed. The adverse effect on
8631 the rest of the redisplay algorithm is about the same as
8632 windows_or_buffers_changed anyway. */
8633 if (windows_or_buffers_changed
8634 || !NILP (w->update_mode_line)
8635 || update_mode_lines
8636 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8637 < BUF_MODIFF (XBUFFER (w->buffer)))
8638 != !NILP (w->last_had_star))
8639 || ((!NILP (Vtransient_mark_mode)
8640 && !NILP (XBUFFER (w->buffer)->mark_active))
8641 != !NILP (w->region_showing)))
8642 {
8643 struct buffer *prev = current_buffer;
8644 int count = SPECPDL_INDEX ();
8645 Lisp_Object new_tool_bar;
8646 int new_n_tool_bar;
8647 struct gcpro gcpro1;
8648
8649 /* Set current_buffer to the buffer of the selected
8650 window of the frame, so that we get the right local
8651 keymaps. */
8652 set_buffer_internal_1 (XBUFFER (w->buffer));
8653
8654 /* Save match data, if we must. */
8655 if (save_match_data)
8656 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8657
8658 /* Make sure that we don't accidentally use bogus keymaps. */
8659 if (NILP (Voverriding_local_map_menu_flag))
8660 {
8661 specbind (Qoverriding_terminal_local_map, Qnil);
8662 specbind (Qoverriding_local_map, Qnil);
8663 }
8664
8665 GCPRO1 (new_tool_bar);
8666
8667 /* Build desired tool-bar items from keymaps. */
8668 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8669 &new_n_tool_bar);
8670
8671 /* Redisplay the tool-bar if we changed it. */
8672 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8673 {
8674 /* Redisplay that happens asynchronously due to an expose event
8675 may access f->tool_bar_items. Make sure we update both
8676 variables within BLOCK_INPUT so no such event interrupts. */
8677 BLOCK_INPUT;
8678 f->tool_bar_items = new_tool_bar;
8679 f->n_tool_bar_items = new_n_tool_bar;
8680 w->update_mode_line = Qt;
8681 UNBLOCK_INPUT;
8682 }
8683
8684 UNGCPRO;
8685
8686 unbind_to (count, Qnil);
8687 set_buffer_internal_1 (prev);
8688 }
8689 }
8690 }
8691
8692
8693 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8694 F's desired tool-bar contents. F->tool_bar_items must have
8695 been set up previously by calling prepare_menu_bars. */
8696
8697 static void
8698 build_desired_tool_bar_string (f)
8699 struct frame *f;
8700 {
8701 int i, size, size_needed;
8702 struct gcpro gcpro1, gcpro2, gcpro3;
8703 Lisp_Object image, plist, props;
8704
8705 image = plist = props = Qnil;
8706 GCPRO3 (image, plist, props);
8707
8708 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8709 Otherwise, make a new string. */
8710
8711 /* The size of the string we might be able to reuse. */
8712 size = (STRINGP (f->desired_tool_bar_string)
8713 ? SCHARS (f->desired_tool_bar_string)
8714 : 0);
8715
8716 /* We need one space in the string for each image. */
8717 size_needed = f->n_tool_bar_items;
8718
8719 /* Reuse f->desired_tool_bar_string, if possible. */
8720 if (size < size_needed || NILP (f->desired_tool_bar_string))
8721 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8722 make_number (' '));
8723 else
8724 {
8725 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8726 Fremove_text_properties (make_number (0), make_number (size),
8727 props, f->desired_tool_bar_string);
8728 }
8729
8730 /* Put a `display' property on the string for the images to display,
8731 put a `menu_item' property on tool-bar items with a value that
8732 is the index of the item in F's tool-bar item vector. */
8733 for (i = 0; i < f->n_tool_bar_items; ++i)
8734 {
8735 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8736
8737 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8738 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8739 int hmargin, vmargin, relief, idx, end;
8740 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8741
8742 /* If image is a vector, choose the image according to the
8743 button state. */
8744 image = PROP (TOOL_BAR_ITEM_IMAGES);
8745 if (VECTORP (image))
8746 {
8747 if (enabled_p)
8748 idx = (selected_p
8749 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8750 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8751 else
8752 idx = (selected_p
8753 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8754 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8755
8756 xassert (ASIZE (image) >= idx);
8757 image = AREF (image, idx);
8758 }
8759 else
8760 idx = -1;
8761
8762 /* Ignore invalid image specifications. */
8763 if (!valid_image_p (image))
8764 continue;
8765
8766 /* Display the tool-bar button pressed, or depressed. */
8767 plist = Fcopy_sequence (XCDR (image));
8768
8769 /* Compute margin and relief to draw. */
8770 relief = (tool_bar_button_relief >= 0
8771 ? tool_bar_button_relief
8772 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8773 hmargin = vmargin = relief;
8774
8775 if (INTEGERP (Vtool_bar_button_margin)
8776 && XINT (Vtool_bar_button_margin) > 0)
8777 {
8778 hmargin += XFASTINT (Vtool_bar_button_margin);
8779 vmargin += XFASTINT (Vtool_bar_button_margin);
8780 }
8781 else if (CONSP (Vtool_bar_button_margin))
8782 {
8783 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8784 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8785 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8786
8787 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8788 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8789 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8790 }
8791
8792 if (auto_raise_tool_bar_buttons_p)
8793 {
8794 /* Add a `:relief' property to the image spec if the item is
8795 selected. */
8796 if (selected_p)
8797 {
8798 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8799 hmargin -= relief;
8800 vmargin -= relief;
8801 }
8802 }
8803 else
8804 {
8805 /* If image is selected, display it pressed, i.e. with a
8806 negative relief. If it's not selected, display it with a
8807 raised relief. */
8808 plist = Fplist_put (plist, QCrelief,
8809 (selected_p
8810 ? make_number (-relief)
8811 : make_number (relief)));
8812 hmargin -= relief;
8813 vmargin -= relief;
8814 }
8815
8816 /* Put a margin around the image. */
8817 if (hmargin || vmargin)
8818 {
8819 if (hmargin == vmargin)
8820 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8821 else
8822 plist = Fplist_put (plist, QCmargin,
8823 Fcons (make_number (hmargin),
8824 make_number (vmargin)));
8825 }
8826
8827 /* If button is not enabled, and we don't have special images
8828 for the disabled state, make the image appear disabled by
8829 applying an appropriate algorithm to it. */
8830 if (!enabled_p && idx < 0)
8831 plist = Fplist_put (plist, QCconversion, Qdisabled);
8832
8833 /* Put a `display' text property on the string for the image to
8834 display. Put a `menu-item' property on the string that gives
8835 the start of this item's properties in the tool-bar items
8836 vector. */
8837 image = Fcons (Qimage, plist);
8838 props = list4 (Qdisplay, image,
8839 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8840
8841 /* Let the last image hide all remaining spaces in the tool bar
8842 string. The string can be longer than needed when we reuse a
8843 previous string. */
8844 if (i + 1 == f->n_tool_bar_items)
8845 end = SCHARS (f->desired_tool_bar_string);
8846 else
8847 end = i + 1;
8848 Fadd_text_properties (make_number (i), make_number (end),
8849 props, f->desired_tool_bar_string);
8850 #undef PROP
8851 }
8852
8853 UNGCPRO;
8854 }
8855
8856
8857 /* Display one line of the tool-bar of frame IT->f. */
8858
8859 static void
8860 display_tool_bar_line (it)
8861 struct it *it;
8862 {
8863 struct glyph_row *row = it->glyph_row;
8864 int max_x = it->last_visible_x;
8865 struct glyph *last;
8866
8867 prepare_desired_row (row);
8868 row->y = it->current_y;
8869
8870 /* Note that this isn't made use of if the face hasn't a box,
8871 so there's no need to check the face here. */
8872 it->start_of_box_run_p = 1;
8873
8874 while (it->current_x < max_x)
8875 {
8876 int x_before, x, n_glyphs_before, i, nglyphs;
8877
8878 /* Get the next display element. */
8879 if (!get_next_display_element (it))
8880 break;
8881
8882 /* Produce glyphs. */
8883 x_before = it->current_x;
8884 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8885 PRODUCE_GLYPHS (it);
8886
8887 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8888 i = 0;
8889 x = x_before;
8890 while (i < nglyphs)
8891 {
8892 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8893
8894 if (x + glyph->pixel_width > max_x)
8895 {
8896 /* Glyph doesn't fit on line. */
8897 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8898 it->current_x = x;
8899 goto out;
8900 }
8901
8902 ++it->hpos;
8903 x += glyph->pixel_width;
8904 ++i;
8905 }
8906
8907 /* Stop at line ends. */
8908 if (ITERATOR_AT_END_OF_LINE_P (it))
8909 break;
8910
8911 set_iterator_to_next (it, 1);
8912 }
8913
8914 out:;
8915
8916 row->displays_text_p = row->used[TEXT_AREA] != 0;
8917 extend_face_to_end_of_line (it);
8918 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8919 last->right_box_line_p = 1;
8920 if (last == row->glyphs[TEXT_AREA])
8921 last->left_box_line_p = 1;
8922 compute_line_metrics (it);
8923
8924 /* If line is empty, make it occupy the rest of the tool-bar. */
8925 if (!row->displays_text_p)
8926 {
8927 row->height = row->phys_height = it->last_visible_y - row->y;
8928 row->ascent = row->phys_ascent = 0;
8929 row->extra_line_spacing = 0;
8930 }
8931
8932 row->full_width_p = 1;
8933 row->continued_p = 0;
8934 row->truncated_on_left_p = 0;
8935 row->truncated_on_right_p = 0;
8936
8937 it->current_x = it->hpos = 0;
8938 it->current_y += row->height;
8939 ++it->vpos;
8940 ++it->glyph_row;
8941 }
8942
8943
8944 /* Value is the number of screen lines needed to make all tool-bar
8945 items of frame F visible. */
8946
8947 static int
8948 tool_bar_lines_needed (f)
8949 struct frame *f;
8950 {
8951 struct window *w = XWINDOW (f->tool_bar_window);
8952 struct it it;
8953
8954 /* Initialize an iterator for iteration over
8955 F->desired_tool_bar_string in the tool-bar window of frame F. */
8956 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8957 it.first_visible_x = 0;
8958 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8959 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8960
8961 while (!ITERATOR_AT_END_P (&it))
8962 {
8963 it.glyph_row = w->desired_matrix->rows;
8964 clear_glyph_row (it.glyph_row);
8965 display_tool_bar_line (&it);
8966 }
8967
8968 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8969 }
8970
8971
8972 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8973 0, 1, 0,
8974 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8975 (frame)
8976 Lisp_Object frame;
8977 {
8978 struct frame *f;
8979 struct window *w;
8980 int nlines = 0;
8981
8982 if (NILP (frame))
8983 frame = selected_frame;
8984 else
8985 CHECK_FRAME (frame);
8986 f = XFRAME (frame);
8987
8988 if (WINDOWP (f->tool_bar_window)
8989 || (w = XWINDOW (f->tool_bar_window),
8990 WINDOW_TOTAL_LINES (w) > 0))
8991 {
8992 update_tool_bar (f, 1);
8993 if (f->n_tool_bar_items)
8994 {
8995 build_desired_tool_bar_string (f);
8996 nlines = tool_bar_lines_needed (f);
8997 }
8998 }
8999
9000 return make_number (nlines);
9001 }
9002
9003
9004 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9005 height should be changed. */
9006
9007 static int
9008 redisplay_tool_bar (f)
9009 struct frame *f;
9010 {
9011 struct window *w;
9012 struct it it;
9013 struct glyph_row *row;
9014 int change_height_p = 0;
9015
9016 #ifdef USE_GTK
9017 if (FRAME_EXTERNAL_TOOL_BAR (f))
9018 update_frame_tool_bar (f);
9019 return 0;
9020 #endif
9021
9022 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9023 do anything. This means you must start with tool-bar-lines
9024 non-zero to get the auto-sizing effect. Or in other words, you
9025 can turn off tool-bars by specifying tool-bar-lines zero. */
9026 if (!WINDOWP (f->tool_bar_window)
9027 || (w = XWINDOW (f->tool_bar_window),
9028 WINDOW_TOTAL_LINES (w) == 0))
9029 return 0;
9030
9031 /* Set up an iterator for the tool-bar window. */
9032 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9033 it.first_visible_x = 0;
9034 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9035 row = it.glyph_row;
9036
9037 /* Build a string that represents the contents of the tool-bar. */
9038 build_desired_tool_bar_string (f);
9039 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9040
9041 /* Display as many lines as needed to display all tool-bar items. */
9042 while (it.current_y < it.last_visible_y)
9043 display_tool_bar_line (&it);
9044
9045 /* It doesn't make much sense to try scrolling in the tool-bar
9046 window, so don't do it. */
9047 w->desired_matrix->no_scrolling_p = 1;
9048 w->must_be_updated_p = 1;
9049
9050 if (auto_resize_tool_bars_p)
9051 {
9052 int nlines;
9053
9054 /* If we couldn't display everything, change the tool-bar's
9055 height. */
9056 if (IT_STRING_CHARPOS (it) < it.end_charpos)
9057 change_height_p = 1;
9058
9059 /* If there are blank lines at the end, except for a partially
9060 visible blank line at the end that is smaller than
9061 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9062 row = it.glyph_row - 1;
9063 if (!row->displays_text_p
9064 && row->height >= FRAME_LINE_HEIGHT (f))
9065 change_height_p = 1;
9066
9067 /* If row displays tool-bar items, but is partially visible,
9068 change the tool-bar's height. */
9069 if (row->displays_text_p
9070 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
9071 change_height_p = 1;
9072
9073 /* Resize windows as needed by changing the `tool-bar-lines'
9074 frame parameter. */
9075 if (change_height_p
9076 && (nlines = tool_bar_lines_needed (f),
9077 nlines != WINDOW_TOTAL_LINES (w)))
9078 {
9079 extern Lisp_Object Qtool_bar_lines;
9080 Lisp_Object frame;
9081 int old_height = WINDOW_TOTAL_LINES (w);
9082
9083 XSETFRAME (frame, f);
9084 clear_glyph_matrix (w->desired_matrix);
9085 Fmodify_frame_parameters (frame,
9086 Fcons (Fcons (Qtool_bar_lines,
9087 make_number (nlines)),
9088 Qnil));
9089 if (WINDOW_TOTAL_LINES (w) != old_height)
9090 fonts_changed_p = 1;
9091 }
9092 }
9093
9094 return change_height_p;
9095 }
9096
9097
9098 /* Get information about the tool-bar item which is displayed in GLYPH
9099 on frame F. Return in *PROP_IDX the index where tool-bar item
9100 properties start in F->tool_bar_items. Value is zero if
9101 GLYPH doesn't display a tool-bar item. */
9102
9103 static int
9104 tool_bar_item_info (f, glyph, prop_idx)
9105 struct frame *f;
9106 struct glyph *glyph;
9107 int *prop_idx;
9108 {
9109 Lisp_Object prop;
9110 int success_p;
9111 int charpos;
9112
9113 /* This function can be called asynchronously, which means we must
9114 exclude any possibility that Fget_text_property signals an
9115 error. */
9116 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
9117 charpos = max (0, charpos);
9118
9119 /* Get the text property `menu-item' at pos. The value of that
9120 property is the start index of this item's properties in
9121 F->tool_bar_items. */
9122 prop = Fget_text_property (make_number (charpos),
9123 Qmenu_item, f->current_tool_bar_string);
9124 if (INTEGERP (prop))
9125 {
9126 *prop_idx = XINT (prop);
9127 success_p = 1;
9128 }
9129 else
9130 success_p = 0;
9131
9132 return success_p;
9133 }
9134
9135 \f
9136 /* Get information about the tool-bar item at position X/Y on frame F.
9137 Return in *GLYPH a pointer to the glyph of the tool-bar item in
9138 the current matrix of the tool-bar window of F, or NULL if not
9139 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
9140 item in F->tool_bar_items. Value is
9141
9142 -1 if X/Y is not on a tool-bar item
9143 0 if X/Y is on the same item that was highlighted before.
9144 1 otherwise. */
9145
9146 static int
9147 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
9148 struct frame *f;
9149 int x, y;
9150 struct glyph **glyph;
9151 int *hpos, *vpos, *prop_idx;
9152 {
9153 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9154 struct window *w = XWINDOW (f->tool_bar_window);
9155 int area;
9156
9157 /* Find the glyph under X/Y. */
9158 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
9159 if (*glyph == NULL)
9160 return -1;
9161
9162 /* Get the start of this tool-bar item's properties in
9163 f->tool_bar_items. */
9164 if (!tool_bar_item_info (f, *glyph, prop_idx))
9165 return -1;
9166
9167 /* Is mouse on the highlighted item? */
9168 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
9169 && *vpos >= dpyinfo->mouse_face_beg_row
9170 && *vpos <= dpyinfo->mouse_face_end_row
9171 && (*vpos > dpyinfo->mouse_face_beg_row
9172 || *hpos >= dpyinfo->mouse_face_beg_col)
9173 && (*vpos < dpyinfo->mouse_face_end_row
9174 || *hpos < dpyinfo->mouse_face_end_col
9175 || dpyinfo->mouse_face_past_end))
9176 return 0;
9177
9178 return 1;
9179 }
9180
9181
9182 /* EXPORT:
9183 Handle mouse button event on the tool-bar of frame F, at
9184 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
9185 0 for button release. MODIFIERS is event modifiers for button
9186 release. */
9187
9188 void
9189 handle_tool_bar_click (f, x, y, down_p, modifiers)
9190 struct frame *f;
9191 int x, y, down_p;
9192 unsigned int modifiers;
9193 {
9194 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9195 struct window *w = XWINDOW (f->tool_bar_window);
9196 int hpos, vpos, prop_idx;
9197 struct glyph *glyph;
9198 Lisp_Object enabled_p;
9199
9200 /* If not on the highlighted tool-bar item, return. */
9201 frame_to_window_pixel_xy (w, &x, &y);
9202 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
9203 return;
9204
9205 /* If item is disabled, do nothing. */
9206 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9207 if (NILP (enabled_p))
9208 return;
9209
9210 if (down_p)
9211 {
9212 /* Show item in pressed state. */
9213 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
9214 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
9215 last_tool_bar_item = prop_idx;
9216 }
9217 else
9218 {
9219 Lisp_Object key, frame;
9220 struct input_event event;
9221 EVENT_INIT (event);
9222
9223 /* Show item in released state. */
9224 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
9225 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9226
9227 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9228
9229 XSETFRAME (frame, f);
9230 event.kind = TOOL_BAR_EVENT;
9231 event.frame_or_window = frame;
9232 event.arg = frame;
9233 kbd_buffer_store_event (&event);
9234
9235 event.kind = TOOL_BAR_EVENT;
9236 event.frame_or_window = frame;
9237 event.arg = key;
9238 event.modifiers = modifiers;
9239 kbd_buffer_store_event (&event);
9240 last_tool_bar_item = -1;
9241 }
9242 }
9243
9244
9245 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9246 tool-bar window-relative coordinates X/Y. Called from
9247 note_mouse_highlight. */
9248
9249 static void
9250 note_tool_bar_highlight (f, x, y)
9251 struct frame *f;
9252 int x, y;
9253 {
9254 Lisp_Object window = f->tool_bar_window;
9255 struct window *w = XWINDOW (window);
9256 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9257 int hpos, vpos;
9258 struct glyph *glyph;
9259 struct glyph_row *row;
9260 int i;
9261 Lisp_Object enabled_p;
9262 int prop_idx;
9263 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9264 int mouse_down_p, rc;
9265
9266 /* Function note_mouse_highlight is called with negative x(y
9267 values when mouse moves outside of the frame. */
9268 if (x <= 0 || y <= 0)
9269 {
9270 clear_mouse_face (dpyinfo);
9271 return;
9272 }
9273
9274 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9275 if (rc < 0)
9276 {
9277 /* Not on tool-bar item. */
9278 clear_mouse_face (dpyinfo);
9279 return;
9280 }
9281 else if (rc == 0)
9282 /* On same tool-bar item as before. */
9283 goto set_help_echo;
9284
9285 clear_mouse_face (dpyinfo);
9286
9287 /* Mouse is down, but on different tool-bar item? */
9288 mouse_down_p = (dpyinfo->grabbed
9289 && f == last_mouse_frame
9290 && FRAME_LIVE_P (f));
9291 if (mouse_down_p
9292 && last_tool_bar_item != prop_idx)
9293 return;
9294
9295 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9296 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9297
9298 /* If tool-bar item is not enabled, don't highlight it. */
9299 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9300 if (!NILP (enabled_p))
9301 {
9302 /* Compute the x-position of the glyph. In front and past the
9303 image is a space. We include this in the highlighted area. */
9304 row = MATRIX_ROW (w->current_matrix, vpos);
9305 for (i = x = 0; i < hpos; ++i)
9306 x += row->glyphs[TEXT_AREA][i].pixel_width;
9307
9308 /* Record this as the current active region. */
9309 dpyinfo->mouse_face_beg_col = hpos;
9310 dpyinfo->mouse_face_beg_row = vpos;
9311 dpyinfo->mouse_face_beg_x = x;
9312 dpyinfo->mouse_face_beg_y = row->y;
9313 dpyinfo->mouse_face_past_end = 0;
9314
9315 dpyinfo->mouse_face_end_col = hpos + 1;
9316 dpyinfo->mouse_face_end_row = vpos;
9317 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9318 dpyinfo->mouse_face_end_y = row->y;
9319 dpyinfo->mouse_face_window = window;
9320 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9321
9322 /* Display it as active. */
9323 show_mouse_face (dpyinfo, draw);
9324 dpyinfo->mouse_face_image_state = draw;
9325 }
9326
9327 set_help_echo:
9328
9329 /* Set help_echo_string to a help string to display for this tool-bar item.
9330 XTread_socket does the rest. */
9331 help_echo_object = help_echo_window = Qnil;
9332 help_echo_pos = -1;
9333 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9334 if (NILP (help_echo_string))
9335 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9336 }
9337
9338 #endif /* HAVE_WINDOW_SYSTEM */
9339
9340
9341 \f
9342 /************************************************************************
9343 Horizontal scrolling
9344 ************************************************************************/
9345
9346 static int hscroll_window_tree P_ ((Lisp_Object));
9347 static int hscroll_windows P_ ((Lisp_Object));
9348
9349 /* For all leaf windows in the window tree rooted at WINDOW, set their
9350 hscroll value so that PT is (i) visible in the window, and (ii) so
9351 that it is not within a certain margin at the window's left and
9352 right border. Value is non-zero if any window's hscroll has been
9353 changed. */
9354
9355 static int
9356 hscroll_window_tree (window)
9357 Lisp_Object window;
9358 {
9359 int hscrolled_p = 0;
9360 int hscroll_relative_p = FLOATP (Vhscroll_step);
9361 int hscroll_step_abs = 0;
9362 double hscroll_step_rel = 0;
9363
9364 if (hscroll_relative_p)
9365 {
9366 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9367 if (hscroll_step_rel < 0)
9368 {
9369 hscroll_relative_p = 0;
9370 hscroll_step_abs = 0;
9371 }
9372 }
9373 else if (INTEGERP (Vhscroll_step))
9374 {
9375 hscroll_step_abs = XINT (Vhscroll_step);
9376 if (hscroll_step_abs < 0)
9377 hscroll_step_abs = 0;
9378 }
9379 else
9380 hscroll_step_abs = 0;
9381
9382 while (WINDOWP (window))
9383 {
9384 struct window *w = XWINDOW (window);
9385
9386 if (WINDOWP (w->hchild))
9387 hscrolled_p |= hscroll_window_tree (w->hchild);
9388 else if (WINDOWP (w->vchild))
9389 hscrolled_p |= hscroll_window_tree (w->vchild);
9390 else if (w->cursor.vpos >= 0)
9391 {
9392 int h_margin;
9393 int text_area_width;
9394 struct glyph_row *current_cursor_row
9395 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9396 struct glyph_row *desired_cursor_row
9397 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9398 struct glyph_row *cursor_row
9399 = (desired_cursor_row->enabled_p
9400 ? desired_cursor_row
9401 : current_cursor_row);
9402
9403 text_area_width = window_box_width (w, TEXT_AREA);
9404
9405 /* Scroll when cursor is inside this scroll margin. */
9406 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9407
9408 if ((XFASTINT (w->hscroll)
9409 && w->cursor.x <= h_margin)
9410 || (cursor_row->enabled_p
9411 && cursor_row->truncated_on_right_p
9412 && (w->cursor.x >= text_area_width - h_margin)))
9413 {
9414 struct it it;
9415 int hscroll;
9416 struct buffer *saved_current_buffer;
9417 int pt;
9418 int wanted_x;
9419
9420 /* Find point in a display of infinite width. */
9421 saved_current_buffer = current_buffer;
9422 current_buffer = XBUFFER (w->buffer);
9423
9424 if (w == XWINDOW (selected_window))
9425 pt = BUF_PT (current_buffer);
9426 else
9427 {
9428 pt = marker_position (w->pointm);
9429 pt = max (BEGV, pt);
9430 pt = min (ZV, pt);
9431 }
9432
9433 /* Move iterator to pt starting at cursor_row->start in
9434 a line with infinite width. */
9435 init_to_row_start (&it, w, cursor_row);
9436 it.last_visible_x = INFINITY;
9437 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9438 current_buffer = saved_current_buffer;
9439
9440 /* Position cursor in window. */
9441 if (!hscroll_relative_p && hscroll_step_abs == 0)
9442 hscroll = max (0, (it.current_x
9443 - (ITERATOR_AT_END_OF_LINE_P (&it)
9444 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9445 : (text_area_width / 2))))
9446 / FRAME_COLUMN_WIDTH (it.f);
9447 else if (w->cursor.x >= text_area_width - h_margin)
9448 {
9449 if (hscroll_relative_p)
9450 wanted_x = text_area_width * (1 - hscroll_step_rel)
9451 - h_margin;
9452 else
9453 wanted_x = text_area_width
9454 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9455 - h_margin;
9456 hscroll
9457 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9458 }
9459 else
9460 {
9461 if (hscroll_relative_p)
9462 wanted_x = text_area_width * hscroll_step_rel
9463 + h_margin;
9464 else
9465 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9466 + h_margin;
9467 hscroll
9468 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9469 }
9470 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9471
9472 /* Don't call Fset_window_hscroll if value hasn't
9473 changed because it will prevent redisplay
9474 optimizations. */
9475 if (XFASTINT (w->hscroll) != hscroll)
9476 {
9477 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9478 w->hscroll = make_number (hscroll);
9479 hscrolled_p = 1;
9480 }
9481 }
9482 }
9483
9484 window = w->next;
9485 }
9486
9487 /* Value is non-zero if hscroll of any leaf window has been changed. */
9488 return hscrolled_p;
9489 }
9490
9491
9492 /* Set hscroll so that cursor is visible and not inside horizontal
9493 scroll margins for all windows in the tree rooted at WINDOW. See
9494 also hscroll_window_tree above. Value is non-zero if any window's
9495 hscroll has been changed. If it has, desired matrices on the frame
9496 of WINDOW are cleared. */
9497
9498 static int
9499 hscroll_windows (window)
9500 Lisp_Object window;
9501 {
9502 int hscrolled_p;
9503
9504 if (automatic_hscrolling_p)
9505 {
9506 hscrolled_p = hscroll_window_tree (window);
9507 if (hscrolled_p)
9508 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9509 }
9510 else
9511 hscrolled_p = 0;
9512 return hscrolled_p;
9513 }
9514
9515
9516 \f
9517 /************************************************************************
9518 Redisplay
9519 ************************************************************************/
9520
9521 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9522 to a non-zero value. This is sometimes handy to have in a debugger
9523 session. */
9524
9525 #if GLYPH_DEBUG
9526
9527 /* First and last unchanged row for try_window_id. */
9528
9529 int debug_first_unchanged_at_end_vpos;
9530 int debug_last_unchanged_at_beg_vpos;
9531
9532 /* Delta vpos and y. */
9533
9534 int debug_dvpos, debug_dy;
9535
9536 /* Delta in characters and bytes for try_window_id. */
9537
9538 int debug_delta, debug_delta_bytes;
9539
9540 /* Values of window_end_pos and window_end_vpos at the end of
9541 try_window_id. */
9542
9543 EMACS_INT debug_end_pos, debug_end_vpos;
9544
9545 /* Append a string to W->desired_matrix->method. FMT is a printf
9546 format string. A1...A9 are a supplement for a variable-length
9547 argument list. If trace_redisplay_p is non-zero also printf the
9548 resulting string to stderr. */
9549
9550 static void
9551 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9552 struct window *w;
9553 char *fmt;
9554 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9555 {
9556 char buffer[512];
9557 char *method = w->desired_matrix->method;
9558 int len = strlen (method);
9559 int size = sizeof w->desired_matrix->method;
9560 int remaining = size - len - 1;
9561
9562 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9563 if (len && remaining)
9564 {
9565 method[len] = '|';
9566 --remaining, ++len;
9567 }
9568
9569 strncpy (method + len, buffer, remaining);
9570
9571 if (trace_redisplay_p)
9572 fprintf (stderr, "%p (%s): %s\n",
9573 w,
9574 ((BUFFERP (w->buffer)
9575 && STRINGP (XBUFFER (w->buffer)->name))
9576 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9577 : "no buffer"),
9578 buffer);
9579 }
9580
9581 #endif /* GLYPH_DEBUG */
9582
9583
9584 /* Value is non-zero if all changes in window W, which displays
9585 current_buffer, are in the text between START and END. START is a
9586 buffer position, END is given as a distance from Z. Used in
9587 redisplay_internal for display optimization. */
9588
9589 static INLINE int
9590 text_outside_line_unchanged_p (w, start, end)
9591 struct window *w;
9592 int start, end;
9593 {
9594 int unchanged_p = 1;
9595
9596 /* If text or overlays have changed, see where. */
9597 if (XFASTINT (w->last_modified) < MODIFF
9598 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9599 {
9600 /* Gap in the line? */
9601 if (GPT < start || Z - GPT < end)
9602 unchanged_p = 0;
9603
9604 /* Changes start in front of the line, or end after it? */
9605 if (unchanged_p
9606 && (BEG_UNCHANGED < start - 1
9607 || END_UNCHANGED < end))
9608 unchanged_p = 0;
9609
9610 /* If selective display, can't optimize if changes start at the
9611 beginning of the line. */
9612 if (unchanged_p
9613 && INTEGERP (current_buffer->selective_display)
9614 && XINT (current_buffer->selective_display) > 0
9615 && (BEG_UNCHANGED < start || GPT <= start))
9616 unchanged_p = 0;
9617
9618 /* If there are overlays at the start or end of the line, these
9619 may have overlay strings with newlines in them. A change at
9620 START, for instance, may actually concern the display of such
9621 overlay strings as well, and they are displayed on different
9622 lines. So, quickly rule out this case. (For the future, it
9623 might be desirable to implement something more telling than
9624 just BEG/END_UNCHANGED.) */
9625 if (unchanged_p)
9626 {
9627 if (BEG + BEG_UNCHANGED == start
9628 && overlay_touches_p (start))
9629 unchanged_p = 0;
9630 if (END_UNCHANGED == end
9631 && overlay_touches_p (Z - end))
9632 unchanged_p = 0;
9633 }
9634 }
9635
9636 return unchanged_p;
9637 }
9638
9639
9640 /* Do a frame update, taking possible shortcuts into account. This is
9641 the main external entry point for redisplay.
9642
9643 If the last redisplay displayed an echo area message and that message
9644 is no longer requested, we clear the echo area or bring back the
9645 mini-buffer if that is in use. */
9646
9647 void
9648 redisplay ()
9649 {
9650 redisplay_internal (0);
9651 }
9652
9653
9654 static Lisp_Object
9655 overlay_arrow_string_or_property (var)
9656 Lisp_Object var;
9657 {
9658 Lisp_Object val;
9659
9660 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
9661 return val;
9662
9663 return Voverlay_arrow_string;
9664 }
9665
9666 /* Return 1 if there are any overlay-arrows in current_buffer. */
9667 static int
9668 overlay_arrow_in_current_buffer_p ()
9669 {
9670 Lisp_Object vlist;
9671
9672 for (vlist = Voverlay_arrow_variable_list;
9673 CONSP (vlist);
9674 vlist = XCDR (vlist))
9675 {
9676 Lisp_Object var = XCAR (vlist);
9677 Lisp_Object val;
9678
9679 if (!SYMBOLP (var))
9680 continue;
9681 val = find_symbol_value (var);
9682 if (MARKERP (val)
9683 && current_buffer == XMARKER (val)->buffer)
9684 return 1;
9685 }
9686 return 0;
9687 }
9688
9689
9690 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9691 has changed. */
9692
9693 static int
9694 overlay_arrows_changed_p ()
9695 {
9696 Lisp_Object vlist;
9697
9698 for (vlist = Voverlay_arrow_variable_list;
9699 CONSP (vlist);
9700 vlist = XCDR (vlist))
9701 {
9702 Lisp_Object var = XCAR (vlist);
9703 Lisp_Object val, pstr;
9704
9705 if (!SYMBOLP (var))
9706 continue;
9707 val = find_symbol_value (var);
9708 if (!MARKERP (val))
9709 continue;
9710 if (! EQ (COERCE_MARKER (val),
9711 Fget (var, Qlast_arrow_position))
9712 || ! (pstr = overlay_arrow_string_or_property (var),
9713 EQ (pstr, Fget (var, Qlast_arrow_string))))
9714 return 1;
9715 }
9716 return 0;
9717 }
9718
9719 /* Mark overlay arrows to be updated on next redisplay. */
9720
9721 static void
9722 update_overlay_arrows (up_to_date)
9723 int up_to_date;
9724 {
9725 Lisp_Object vlist;
9726
9727 for (vlist = Voverlay_arrow_variable_list;
9728 CONSP (vlist);
9729 vlist = XCDR (vlist))
9730 {
9731 Lisp_Object var = XCAR (vlist);
9732
9733 if (!SYMBOLP (var))
9734 continue;
9735
9736 if (up_to_date > 0)
9737 {
9738 Lisp_Object val = find_symbol_value (var);
9739 Fput (var, Qlast_arrow_position,
9740 COERCE_MARKER (val));
9741 Fput (var, Qlast_arrow_string,
9742 overlay_arrow_string_or_property (var));
9743 }
9744 else if (up_to_date < 0
9745 || !NILP (Fget (var, Qlast_arrow_position)))
9746 {
9747 Fput (var, Qlast_arrow_position, Qt);
9748 Fput (var, Qlast_arrow_string, Qt);
9749 }
9750 }
9751 }
9752
9753
9754 /* Return overlay arrow string to display at row.
9755 Return integer (bitmap number) for arrow bitmap in left fringe.
9756 Return nil if no overlay arrow. */
9757
9758 static Lisp_Object
9759 overlay_arrow_at_row (it, row)
9760 struct it *it;
9761 struct glyph_row *row;
9762 {
9763 Lisp_Object vlist;
9764
9765 for (vlist = Voverlay_arrow_variable_list;
9766 CONSP (vlist);
9767 vlist = XCDR (vlist))
9768 {
9769 Lisp_Object var = XCAR (vlist);
9770 Lisp_Object val;
9771
9772 if (!SYMBOLP (var))
9773 continue;
9774
9775 val = find_symbol_value (var);
9776
9777 if (MARKERP (val)
9778 && current_buffer == XMARKER (val)->buffer
9779 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9780 {
9781 if (FRAME_WINDOW_P (it->f)
9782 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
9783 {
9784 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
9785 {
9786 int fringe_bitmap;
9787 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
9788 return make_number (fringe_bitmap);
9789 }
9790 return make_number (-1); /* Use default arrow bitmap */
9791 }
9792 return overlay_arrow_string_or_property (var);
9793 }
9794 }
9795
9796 return Qnil;
9797 }
9798
9799 /* Return 1 if point moved out of or into a composition. Otherwise
9800 return 0. PREV_BUF and PREV_PT are the last point buffer and
9801 position. BUF and PT are the current point buffer and position. */
9802
9803 int
9804 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9805 struct buffer *prev_buf, *buf;
9806 int prev_pt, pt;
9807 {
9808 int start, end;
9809 Lisp_Object prop;
9810 Lisp_Object buffer;
9811
9812 XSETBUFFER (buffer, buf);
9813 /* Check a composition at the last point if point moved within the
9814 same buffer. */
9815 if (prev_buf == buf)
9816 {
9817 if (prev_pt == pt)
9818 /* Point didn't move. */
9819 return 0;
9820
9821 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9822 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9823 && COMPOSITION_VALID_P (start, end, prop)
9824 && start < prev_pt && end > prev_pt)
9825 /* The last point was within the composition. Return 1 iff
9826 point moved out of the composition. */
9827 return (pt <= start || pt >= end);
9828 }
9829
9830 /* Check a composition at the current point. */
9831 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9832 && find_composition (pt, -1, &start, &end, &prop, buffer)
9833 && COMPOSITION_VALID_P (start, end, prop)
9834 && start < pt && end > pt);
9835 }
9836
9837
9838 /* Reconsider the setting of B->clip_changed which is displayed
9839 in window W. */
9840
9841 static INLINE void
9842 reconsider_clip_changes (w, b)
9843 struct window *w;
9844 struct buffer *b;
9845 {
9846 if (b->clip_changed
9847 && !NILP (w->window_end_valid)
9848 && w->current_matrix->buffer == b
9849 && w->current_matrix->zv == BUF_ZV (b)
9850 && w->current_matrix->begv == BUF_BEGV (b))
9851 b->clip_changed = 0;
9852
9853 /* If display wasn't paused, and W is not a tool bar window, see if
9854 point has been moved into or out of a composition. In that case,
9855 we set b->clip_changed to 1 to force updating the screen. If
9856 b->clip_changed has already been set to 1, we can skip this
9857 check. */
9858 if (!b->clip_changed
9859 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9860 {
9861 int pt;
9862
9863 if (w == XWINDOW (selected_window))
9864 pt = BUF_PT (current_buffer);
9865 else
9866 pt = marker_position (w->pointm);
9867
9868 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9869 || pt != XINT (w->last_point))
9870 && check_point_in_composition (w->current_matrix->buffer,
9871 XINT (w->last_point),
9872 XBUFFER (w->buffer), pt))
9873 b->clip_changed = 1;
9874 }
9875 }
9876 \f
9877
9878 /* Select FRAME to forward the values of frame-local variables into C
9879 variables so that the redisplay routines can access those values
9880 directly. */
9881
9882 static void
9883 select_frame_for_redisplay (frame)
9884 Lisp_Object frame;
9885 {
9886 Lisp_Object tail, sym, val;
9887 Lisp_Object old = selected_frame;
9888
9889 selected_frame = frame;
9890
9891 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9892 if (CONSP (XCAR (tail))
9893 && (sym = XCAR (XCAR (tail)),
9894 SYMBOLP (sym))
9895 && (sym = indirect_variable (sym),
9896 val = SYMBOL_VALUE (sym),
9897 (BUFFER_LOCAL_VALUEP (val)
9898 || SOME_BUFFER_LOCAL_VALUEP (val)))
9899 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9900 Fsymbol_value (sym);
9901
9902 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9903 if (CONSP (XCAR (tail))
9904 && (sym = XCAR (XCAR (tail)),
9905 SYMBOLP (sym))
9906 && (sym = indirect_variable (sym),
9907 val = SYMBOL_VALUE (sym),
9908 (BUFFER_LOCAL_VALUEP (val)
9909 || SOME_BUFFER_LOCAL_VALUEP (val)))
9910 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9911 Fsymbol_value (sym);
9912 }
9913
9914
9915 #define STOP_POLLING \
9916 do { if (! polling_stopped_here) stop_polling (); \
9917 polling_stopped_here = 1; } while (0)
9918
9919 #define RESUME_POLLING \
9920 do { if (polling_stopped_here) start_polling (); \
9921 polling_stopped_here = 0; } while (0)
9922
9923
9924 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9925 response to any user action; therefore, we should preserve the echo
9926 area. (Actually, our caller does that job.) Perhaps in the future
9927 avoid recentering windows if it is not necessary; currently that
9928 causes some problems. */
9929
9930 static void
9931 redisplay_internal (preserve_echo_area)
9932 int preserve_echo_area;
9933 {
9934 struct window *w = XWINDOW (selected_window);
9935 struct frame *f = XFRAME (w->frame);
9936 int pause;
9937 int must_finish = 0;
9938 struct text_pos tlbufpos, tlendpos;
9939 int number_of_visible_frames;
9940 int count;
9941 struct frame *sf = SELECTED_FRAME ();
9942 int polling_stopped_here = 0;
9943
9944 /* Non-zero means redisplay has to consider all windows on all
9945 frames. Zero means, only selected_window is considered. */
9946 int consider_all_windows_p;
9947
9948 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9949
9950 /* No redisplay if running in batch mode or frame is not yet fully
9951 initialized, or redisplay is explicitly turned off by setting
9952 Vinhibit_redisplay. */
9953 if (noninteractive
9954 || !NILP (Vinhibit_redisplay)
9955 || !f->glyphs_initialized_p)
9956 return;
9957
9958 /* The flag redisplay_performed_directly_p is set by
9959 direct_output_for_insert when it already did the whole screen
9960 update necessary. */
9961 if (redisplay_performed_directly_p)
9962 {
9963 redisplay_performed_directly_p = 0;
9964 if (!hscroll_windows (selected_window))
9965 return;
9966 }
9967
9968 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9969 if (popup_activated ())
9970 return;
9971 #endif
9972
9973 /* I don't think this happens but let's be paranoid. */
9974 if (redisplaying_p)
9975 return;
9976
9977 /* Record a function that resets redisplaying_p to its old value
9978 when we leave this function. */
9979 count = SPECPDL_INDEX ();
9980 record_unwind_protect (unwind_redisplay,
9981 Fcons (make_number (redisplaying_p), selected_frame));
9982 ++redisplaying_p;
9983 specbind (Qinhibit_free_realized_faces, Qnil);
9984
9985 retry:
9986 pause = 0;
9987 reconsider_clip_changes (w, current_buffer);
9988
9989 /* If new fonts have been loaded that make a glyph matrix adjustment
9990 necessary, do it. */
9991 if (fonts_changed_p)
9992 {
9993 adjust_glyphs (NULL);
9994 ++windows_or_buffers_changed;
9995 fonts_changed_p = 0;
9996 }
9997
9998 /* If face_change_count is non-zero, init_iterator will free all
9999 realized faces, which includes the faces referenced from current
10000 matrices. So, we can't reuse current matrices in this case. */
10001 if (face_change_count)
10002 ++windows_or_buffers_changed;
10003
10004 if (! FRAME_WINDOW_P (sf)
10005 && previous_terminal_frame != sf)
10006 {
10007 /* Since frames on an ASCII terminal share the same display
10008 area, displaying a different frame means redisplay the whole
10009 thing. */
10010 windows_or_buffers_changed++;
10011 SET_FRAME_GARBAGED (sf);
10012 XSETFRAME (Vterminal_frame, sf);
10013 }
10014 previous_terminal_frame = sf;
10015
10016 /* Set the visible flags for all frames. Do this before checking
10017 for resized or garbaged frames; they want to know if their frames
10018 are visible. See the comment in frame.h for
10019 FRAME_SAMPLE_VISIBILITY. */
10020 {
10021 Lisp_Object tail, frame;
10022
10023 number_of_visible_frames = 0;
10024
10025 FOR_EACH_FRAME (tail, frame)
10026 {
10027 struct frame *f = XFRAME (frame);
10028
10029 FRAME_SAMPLE_VISIBILITY (f);
10030 if (FRAME_VISIBLE_P (f))
10031 ++number_of_visible_frames;
10032 clear_desired_matrices (f);
10033 }
10034 }
10035
10036 /* Notice any pending interrupt request to change frame size. */
10037 do_pending_window_change (1);
10038
10039 /* Clear frames marked as garbaged. */
10040 if (frame_garbaged)
10041 clear_garbaged_frames ();
10042
10043 /* Build menubar and tool-bar items. */
10044 prepare_menu_bars ();
10045
10046 if (windows_or_buffers_changed)
10047 update_mode_lines++;
10048
10049 /* Detect case that we need to write or remove a star in the mode line. */
10050 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
10051 {
10052 w->update_mode_line = Qt;
10053 if (buffer_shared > 1)
10054 update_mode_lines++;
10055 }
10056
10057 /* If %c is in the mode line, update it if needed. */
10058 if (!NILP (w->column_number_displayed)
10059 /* This alternative quickly identifies a common case
10060 where no change is needed. */
10061 && !(PT == XFASTINT (w->last_point)
10062 && XFASTINT (w->last_modified) >= MODIFF
10063 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
10064 && (XFASTINT (w->column_number_displayed)
10065 != (int) current_column ())) /* iftc */
10066 w->update_mode_line = Qt;
10067
10068 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
10069
10070 /* The variable buffer_shared is set in redisplay_window and
10071 indicates that we redisplay a buffer in different windows. See
10072 there. */
10073 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
10074 || cursor_type_changed);
10075
10076 /* If specs for an arrow have changed, do thorough redisplay
10077 to ensure we remove any arrow that should no longer exist. */
10078 if (overlay_arrows_changed_p ())
10079 consider_all_windows_p = windows_or_buffers_changed = 1;
10080
10081 /* Normally the message* functions will have already displayed and
10082 updated the echo area, but the frame may have been trashed, or
10083 the update may have been preempted, so display the echo area
10084 again here. Checking message_cleared_p captures the case that
10085 the echo area should be cleared. */
10086 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
10087 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
10088 || (message_cleared_p
10089 && minibuf_level == 0
10090 /* If the mini-window is currently selected, this means the
10091 echo-area doesn't show through. */
10092 && !MINI_WINDOW_P (XWINDOW (selected_window))))
10093 {
10094 int window_height_changed_p = echo_area_display (0);
10095 must_finish = 1;
10096
10097 /* If we don't display the current message, don't clear the
10098 message_cleared_p flag, because, if we did, we wouldn't clear
10099 the echo area in the next redisplay which doesn't preserve
10100 the echo area. */
10101 if (!display_last_displayed_message_p)
10102 message_cleared_p = 0;
10103
10104 if (fonts_changed_p)
10105 goto retry;
10106 else if (window_height_changed_p)
10107 {
10108 consider_all_windows_p = 1;
10109 ++update_mode_lines;
10110 ++windows_or_buffers_changed;
10111
10112 /* If window configuration was changed, frames may have been
10113 marked garbaged. Clear them or we will experience
10114 surprises wrt scrolling. */
10115 if (frame_garbaged)
10116 clear_garbaged_frames ();
10117 }
10118 }
10119 else if (EQ (selected_window, minibuf_window)
10120 && (current_buffer->clip_changed
10121 || XFASTINT (w->last_modified) < MODIFF
10122 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10123 && resize_mini_window (w, 0))
10124 {
10125 /* Resized active mini-window to fit the size of what it is
10126 showing if its contents might have changed. */
10127 must_finish = 1;
10128 consider_all_windows_p = 1;
10129 ++windows_or_buffers_changed;
10130 ++update_mode_lines;
10131
10132 /* If window configuration was changed, frames may have been
10133 marked garbaged. Clear them or we will experience
10134 surprises wrt scrolling. */
10135 if (frame_garbaged)
10136 clear_garbaged_frames ();
10137 }
10138
10139
10140 /* If showing the region, and mark has changed, we must redisplay
10141 the whole window. The assignment to this_line_start_pos prevents
10142 the optimization directly below this if-statement. */
10143 if (((!NILP (Vtransient_mark_mode)
10144 && !NILP (XBUFFER (w->buffer)->mark_active))
10145 != !NILP (w->region_showing))
10146 || (!NILP (w->region_showing)
10147 && !EQ (w->region_showing,
10148 Fmarker_position (XBUFFER (w->buffer)->mark))))
10149 CHARPOS (this_line_start_pos) = 0;
10150
10151 /* Optimize the case that only the line containing the cursor in the
10152 selected window has changed. Variables starting with this_ are
10153 set in display_line and record information about the line
10154 containing the cursor. */
10155 tlbufpos = this_line_start_pos;
10156 tlendpos = this_line_end_pos;
10157 if (!consider_all_windows_p
10158 && CHARPOS (tlbufpos) > 0
10159 && NILP (w->update_mode_line)
10160 && !current_buffer->clip_changed
10161 && !current_buffer->prevent_redisplay_optimizations_p
10162 && FRAME_VISIBLE_P (XFRAME (w->frame))
10163 && !FRAME_OBSCURED_P (XFRAME (w->frame))
10164 /* Make sure recorded data applies to current buffer, etc. */
10165 && this_line_buffer == current_buffer
10166 && current_buffer == XBUFFER (w->buffer)
10167 && NILP (w->force_start)
10168 && NILP (w->optional_new_start)
10169 /* Point must be on the line that we have info recorded about. */
10170 && PT >= CHARPOS (tlbufpos)
10171 && PT <= Z - CHARPOS (tlendpos)
10172 /* All text outside that line, including its final newline,
10173 must be unchanged */
10174 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
10175 CHARPOS (tlendpos)))
10176 {
10177 if (CHARPOS (tlbufpos) > BEGV
10178 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
10179 && (CHARPOS (tlbufpos) == ZV
10180 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
10181 /* Former continuation line has disappeared by becoming empty */
10182 goto cancel;
10183 else if (XFASTINT (w->last_modified) < MODIFF
10184 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
10185 || MINI_WINDOW_P (w))
10186 {
10187 /* We have to handle the case of continuation around a
10188 wide-column character (See the comment in indent.c around
10189 line 885).
10190
10191 For instance, in the following case:
10192
10193 -------- Insert --------
10194 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10195 J_I_ ==> J_I_ `^^' are cursors.
10196 ^^ ^^
10197 -------- --------
10198
10199 As we have to redraw the line above, we should goto cancel. */
10200
10201 struct it it;
10202 int line_height_before = this_line_pixel_height;
10203
10204 /* Note that start_display will handle the case that the
10205 line starting at tlbufpos is a continuation lines. */
10206 start_display (&it, w, tlbufpos);
10207
10208 /* Implementation note: It this still necessary? */
10209 if (it.current_x != this_line_start_x)
10210 goto cancel;
10211
10212 TRACE ((stderr, "trying display optimization 1\n"));
10213 w->cursor.vpos = -1;
10214 overlay_arrow_seen = 0;
10215 it.vpos = this_line_vpos;
10216 it.current_y = this_line_y;
10217 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10218 display_line (&it);
10219
10220 /* If line contains point, is not continued,
10221 and ends at same distance from eob as before, we win */
10222 if (w->cursor.vpos >= 0
10223 /* Line is not continued, otherwise this_line_start_pos
10224 would have been set to 0 in display_line. */
10225 && CHARPOS (this_line_start_pos)
10226 /* Line ends as before. */
10227 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10228 /* Line has same height as before. Otherwise other lines
10229 would have to be shifted up or down. */
10230 && this_line_pixel_height == line_height_before)
10231 {
10232 /* If this is not the window's last line, we must adjust
10233 the charstarts of the lines below. */
10234 if (it.current_y < it.last_visible_y)
10235 {
10236 struct glyph_row *row
10237 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10238 int delta, delta_bytes;
10239
10240 if (Z - CHARPOS (tlendpos) == ZV)
10241 {
10242 /* This line ends at end of (accessible part of)
10243 buffer. There is no newline to count. */
10244 delta = (Z
10245 - CHARPOS (tlendpos)
10246 - MATRIX_ROW_START_CHARPOS (row));
10247 delta_bytes = (Z_BYTE
10248 - BYTEPOS (tlendpos)
10249 - MATRIX_ROW_START_BYTEPOS (row));
10250 }
10251 else
10252 {
10253 /* This line ends in a newline. Must take
10254 account of the newline and the rest of the
10255 text that follows. */
10256 delta = (Z
10257 - CHARPOS (tlendpos)
10258 - MATRIX_ROW_START_CHARPOS (row));
10259 delta_bytes = (Z_BYTE
10260 - BYTEPOS (tlendpos)
10261 - MATRIX_ROW_START_BYTEPOS (row));
10262 }
10263
10264 increment_matrix_positions (w->current_matrix,
10265 this_line_vpos + 1,
10266 w->current_matrix->nrows,
10267 delta, delta_bytes);
10268 }
10269
10270 /* If this row displays text now but previously didn't,
10271 or vice versa, w->window_end_vpos may have to be
10272 adjusted. */
10273 if ((it.glyph_row - 1)->displays_text_p)
10274 {
10275 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10276 XSETINT (w->window_end_vpos, this_line_vpos);
10277 }
10278 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10279 && this_line_vpos > 0)
10280 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10281 w->window_end_valid = Qnil;
10282
10283 /* Update hint: No need to try to scroll in update_window. */
10284 w->desired_matrix->no_scrolling_p = 1;
10285
10286 #if GLYPH_DEBUG
10287 *w->desired_matrix->method = 0;
10288 debug_method_add (w, "optimization 1");
10289 #endif
10290 #ifdef HAVE_WINDOW_SYSTEM
10291 update_window_fringes (w, 0);
10292 #endif
10293 goto update;
10294 }
10295 else
10296 goto cancel;
10297 }
10298 else if (/* Cursor position hasn't changed. */
10299 PT == XFASTINT (w->last_point)
10300 /* Make sure the cursor was last displayed
10301 in this window. Otherwise we have to reposition it. */
10302 && 0 <= w->cursor.vpos
10303 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10304 {
10305 if (!must_finish)
10306 {
10307 do_pending_window_change (1);
10308
10309 /* We used to always goto end_of_redisplay here, but this
10310 isn't enough if we have a blinking cursor. */
10311 if (w->cursor_off_p == w->last_cursor_off_p)
10312 goto end_of_redisplay;
10313 }
10314 goto update;
10315 }
10316 /* If highlighting the region, or if the cursor is in the echo area,
10317 then we can't just move the cursor. */
10318 else if (! (!NILP (Vtransient_mark_mode)
10319 && !NILP (current_buffer->mark_active))
10320 && (EQ (selected_window, current_buffer->last_selected_window)
10321 || highlight_nonselected_windows)
10322 && NILP (w->region_showing)
10323 && NILP (Vshow_trailing_whitespace)
10324 && !cursor_in_echo_area)
10325 {
10326 struct it it;
10327 struct glyph_row *row;
10328
10329 /* Skip from tlbufpos to PT and see where it is. Note that
10330 PT may be in invisible text. If so, we will end at the
10331 next visible position. */
10332 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10333 NULL, DEFAULT_FACE_ID);
10334 it.current_x = this_line_start_x;
10335 it.current_y = this_line_y;
10336 it.vpos = this_line_vpos;
10337
10338 /* The call to move_it_to stops in front of PT, but
10339 moves over before-strings. */
10340 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10341
10342 if (it.vpos == this_line_vpos
10343 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10344 row->enabled_p))
10345 {
10346 xassert (this_line_vpos == it.vpos);
10347 xassert (this_line_y == it.current_y);
10348 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10349 #if GLYPH_DEBUG
10350 *w->desired_matrix->method = 0;
10351 debug_method_add (w, "optimization 3");
10352 #endif
10353 goto update;
10354 }
10355 else
10356 goto cancel;
10357 }
10358
10359 cancel:
10360 /* Text changed drastically or point moved off of line. */
10361 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10362 }
10363
10364 CHARPOS (this_line_start_pos) = 0;
10365 consider_all_windows_p |= buffer_shared > 1;
10366 ++clear_face_cache_count;
10367 #ifdef HAVE_WINDOW_SYSTEM
10368 ++clear_image_cache_count;
10369 #endif
10370
10371 /* Build desired matrices, and update the display. If
10372 consider_all_windows_p is non-zero, do it for all windows on all
10373 frames. Otherwise do it for selected_window, only. */
10374
10375 if (consider_all_windows_p)
10376 {
10377 Lisp_Object tail, frame;
10378 int i, n = 0, size = 50;
10379 struct frame **updated
10380 = (struct frame **) alloca (size * sizeof *updated);
10381
10382 /* Recompute # windows showing selected buffer. This will be
10383 incremented each time such a window is displayed. */
10384 buffer_shared = 0;
10385
10386 FOR_EACH_FRAME (tail, frame)
10387 {
10388 struct frame *f = XFRAME (frame);
10389
10390 if (FRAME_WINDOW_P (f) || f == sf)
10391 {
10392 if (! EQ (frame, selected_frame))
10393 /* Select the frame, for the sake of frame-local
10394 variables. */
10395 select_frame_for_redisplay (frame);
10396
10397 /* Mark all the scroll bars to be removed; we'll redeem
10398 the ones we want when we redisplay their windows. */
10399 if (condemn_scroll_bars_hook)
10400 condemn_scroll_bars_hook (f);
10401
10402 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10403 redisplay_windows (FRAME_ROOT_WINDOW (f));
10404
10405 /* Any scroll bars which redisplay_windows should have
10406 nuked should now go away. */
10407 if (judge_scroll_bars_hook)
10408 judge_scroll_bars_hook (f);
10409
10410 /* If fonts changed, display again. */
10411 /* ??? rms: I suspect it is a mistake to jump all the way
10412 back to retry here. It should just retry this frame. */
10413 if (fonts_changed_p)
10414 goto retry;
10415
10416 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10417 {
10418 /* See if we have to hscroll. */
10419 if (hscroll_windows (f->root_window))
10420 goto retry;
10421
10422 /* Prevent various kinds of signals during display
10423 update. stdio is not robust about handling
10424 signals, which can cause an apparent I/O
10425 error. */
10426 if (interrupt_input)
10427 unrequest_sigio ();
10428 STOP_POLLING;
10429
10430 /* Update the display. */
10431 set_window_update_flags (XWINDOW (f->root_window), 1);
10432 pause |= update_frame (f, 0, 0);
10433 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10434 if (pause)
10435 break;
10436 #endif
10437
10438 if (n == size)
10439 {
10440 int nbytes = size * sizeof *updated;
10441 struct frame **p = (struct frame **) alloca (2 * nbytes);
10442 bcopy (updated, p, nbytes);
10443 size *= 2;
10444 }
10445
10446 updated[n++] = f;
10447 }
10448 }
10449 }
10450
10451 if (!pause)
10452 {
10453 /* Do the mark_window_display_accurate after all windows have
10454 been redisplayed because this call resets flags in buffers
10455 which are needed for proper redisplay. */
10456 for (i = 0; i < n; ++i)
10457 {
10458 struct frame *f = updated[i];
10459 mark_window_display_accurate (f->root_window, 1);
10460 if (frame_up_to_date_hook)
10461 frame_up_to_date_hook (f);
10462 }
10463 }
10464 }
10465 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10466 {
10467 Lisp_Object mini_window;
10468 struct frame *mini_frame;
10469
10470 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10471 /* Use list_of_error, not Qerror, so that
10472 we catch only errors and don't run the debugger. */
10473 internal_condition_case_1 (redisplay_window_1, selected_window,
10474 list_of_error,
10475 redisplay_window_error);
10476
10477 /* Compare desired and current matrices, perform output. */
10478
10479 update:
10480 /* If fonts changed, display again. */
10481 if (fonts_changed_p)
10482 goto retry;
10483
10484 /* Prevent various kinds of signals during display update.
10485 stdio is not robust about handling signals,
10486 which can cause an apparent I/O error. */
10487 if (interrupt_input)
10488 unrequest_sigio ();
10489 STOP_POLLING;
10490
10491 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10492 {
10493 if (hscroll_windows (selected_window))
10494 goto retry;
10495
10496 XWINDOW (selected_window)->must_be_updated_p = 1;
10497 pause = update_frame (sf, 0, 0);
10498 }
10499
10500 /* We may have called echo_area_display at the top of this
10501 function. If the echo area is on another frame, that may
10502 have put text on a frame other than the selected one, so the
10503 above call to update_frame would not have caught it. Catch
10504 it here. */
10505 mini_window = FRAME_MINIBUF_WINDOW (sf);
10506 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10507
10508 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10509 {
10510 XWINDOW (mini_window)->must_be_updated_p = 1;
10511 pause |= update_frame (mini_frame, 0, 0);
10512 if (!pause && hscroll_windows (mini_window))
10513 goto retry;
10514 }
10515 }
10516
10517 /* If display was paused because of pending input, make sure we do a
10518 thorough update the next time. */
10519 if (pause)
10520 {
10521 /* Prevent the optimization at the beginning of
10522 redisplay_internal that tries a single-line update of the
10523 line containing the cursor in the selected window. */
10524 CHARPOS (this_line_start_pos) = 0;
10525
10526 /* Let the overlay arrow be updated the next time. */
10527 update_overlay_arrows (0);
10528
10529 /* If we pause after scrolling, some rows in the current
10530 matrices of some windows are not valid. */
10531 if (!WINDOW_FULL_WIDTH_P (w)
10532 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10533 update_mode_lines = 1;
10534 }
10535 else
10536 {
10537 if (!consider_all_windows_p)
10538 {
10539 /* This has already been done above if
10540 consider_all_windows_p is set. */
10541 mark_window_display_accurate_1 (w, 1);
10542
10543 /* Say overlay arrows are up to date. */
10544 update_overlay_arrows (1);
10545
10546 if (frame_up_to_date_hook != 0)
10547 frame_up_to_date_hook (sf);
10548 }
10549
10550 update_mode_lines = 0;
10551 windows_or_buffers_changed = 0;
10552 cursor_type_changed = 0;
10553 }
10554
10555 /* Start SIGIO interrupts coming again. Having them off during the
10556 code above makes it less likely one will discard output, but not
10557 impossible, since there might be stuff in the system buffer here.
10558 But it is much hairier to try to do anything about that. */
10559 if (interrupt_input)
10560 request_sigio ();
10561 RESUME_POLLING;
10562
10563 /* If a frame has become visible which was not before, redisplay
10564 again, so that we display it. Expose events for such a frame
10565 (which it gets when becoming visible) don't call the parts of
10566 redisplay constructing glyphs, so simply exposing a frame won't
10567 display anything in this case. So, we have to display these
10568 frames here explicitly. */
10569 if (!pause)
10570 {
10571 Lisp_Object tail, frame;
10572 int new_count = 0;
10573
10574 FOR_EACH_FRAME (tail, frame)
10575 {
10576 int this_is_visible = 0;
10577
10578 if (XFRAME (frame)->visible)
10579 this_is_visible = 1;
10580 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10581 if (XFRAME (frame)->visible)
10582 this_is_visible = 1;
10583
10584 if (this_is_visible)
10585 new_count++;
10586 }
10587
10588 if (new_count != number_of_visible_frames)
10589 windows_or_buffers_changed++;
10590 }
10591
10592 /* Change frame size now if a change is pending. */
10593 do_pending_window_change (1);
10594
10595 /* If we just did a pending size change, or have additional
10596 visible frames, redisplay again. */
10597 if (windows_or_buffers_changed && !pause)
10598 goto retry;
10599
10600 /* Clear the face cache eventually. */
10601 if (consider_all_windows_p)
10602 {
10603 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10604 {
10605 clear_face_cache (0);
10606 clear_face_cache_count = 0;
10607 }
10608 #ifdef HAVE_WINDOW_SYSTEM
10609 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
10610 {
10611 Lisp_Object tail, frame;
10612 FOR_EACH_FRAME (tail, frame)
10613 {
10614 struct frame *f = XFRAME (frame);
10615 if (FRAME_WINDOW_P (f))
10616 clear_image_cache (f, 0);
10617 }
10618 clear_image_cache_count = 0;
10619 }
10620 #endif /* HAVE_WINDOW_SYSTEM */
10621 }
10622
10623 end_of_redisplay:
10624 unbind_to (count, Qnil);
10625 RESUME_POLLING;
10626 }
10627
10628
10629 /* Redisplay, but leave alone any recent echo area message unless
10630 another message has been requested in its place.
10631
10632 This is useful in situations where you need to redisplay but no
10633 user action has occurred, making it inappropriate for the message
10634 area to be cleared. See tracking_off and
10635 wait_reading_process_output for examples of these situations.
10636
10637 FROM_WHERE is an integer saying from where this function was
10638 called. This is useful for debugging. */
10639
10640 void
10641 redisplay_preserve_echo_area (from_where)
10642 int from_where;
10643 {
10644 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10645
10646 if (!NILP (echo_area_buffer[1]))
10647 {
10648 /* We have a previously displayed message, but no current
10649 message. Redisplay the previous message. */
10650 display_last_displayed_message_p = 1;
10651 redisplay_internal (1);
10652 display_last_displayed_message_p = 0;
10653 }
10654 else
10655 redisplay_internal (1);
10656
10657 if (rif != NULL && rif->flush_display_optional)
10658 rif->flush_display_optional (NULL);
10659 }
10660
10661
10662 /* Function registered with record_unwind_protect in
10663 redisplay_internal. Reset redisplaying_p to the value it had
10664 before redisplay_internal was called, and clear
10665 prevent_freeing_realized_faces_p. It also selects the previously
10666 selected frame. */
10667
10668 static Lisp_Object
10669 unwind_redisplay (val)
10670 Lisp_Object val;
10671 {
10672 Lisp_Object old_redisplaying_p, old_frame;
10673
10674 old_redisplaying_p = XCAR (val);
10675 redisplaying_p = XFASTINT (old_redisplaying_p);
10676 old_frame = XCDR (val);
10677 if (! EQ (old_frame, selected_frame))
10678 select_frame_for_redisplay (old_frame);
10679 return Qnil;
10680 }
10681
10682
10683 /* Mark the display of window W as accurate or inaccurate. If
10684 ACCURATE_P is non-zero mark display of W as accurate. If
10685 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10686 redisplay_internal is called. */
10687
10688 static void
10689 mark_window_display_accurate_1 (w, accurate_p)
10690 struct window *w;
10691 int accurate_p;
10692 {
10693 if (BUFFERP (w->buffer))
10694 {
10695 struct buffer *b = XBUFFER (w->buffer);
10696
10697 w->last_modified
10698 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10699 w->last_overlay_modified
10700 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10701 w->last_had_star
10702 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10703
10704 if (accurate_p)
10705 {
10706 b->clip_changed = 0;
10707 b->prevent_redisplay_optimizations_p = 0;
10708
10709 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10710 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10711 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10712 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10713
10714 w->current_matrix->buffer = b;
10715 w->current_matrix->begv = BUF_BEGV (b);
10716 w->current_matrix->zv = BUF_ZV (b);
10717
10718 w->last_cursor = w->cursor;
10719 w->last_cursor_off_p = w->cursor_off_p;
10720
10721 if (w == XWINDOW (selected_window))
10722 w->last_point = make_number (BUF_PT (b));
10723 else
10724 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10725 }
10726 }
10727
10728 if (accurate_p)
10729 {
10730 w->window_end_valid = w->buffer;
10731 #if 0 /* This is incorrect with variable-height lines. */
10732 xassert (XINT (w->window_end_vpos)
10733 < (WINDOW_TOTAL_LINES (w)
10734 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10735 #endif
10736 w->update_mode_line = Qnil;
10737 }
10738 }
10739
10740
10741 /* Mark the display of windows in the window tree rooted at WINDOW as
10742 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10743 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10744 be redisplayed the next time redisplay_internal is called. */
10745
10746 void
10747 mark_window_display_accurate (window, accurate_p)
10748 Lisp_Object window;
10749 int accurate_p;
10750 {
10751 struct window *w;
10752
10753 for (; !NILP (window); window = w->next)
10754 {
10755 w = XWINDOW (window);
10756 mark_window_display_accurate_1 (w, accurate_p);
10757
10758 if (!NILP (w->vchild))
10759 mark_window_display_accurate (w->vchild, accurate_p);
10760 if (!NILP (w->hchild))
10761 mark_window_display_accurate (w->hchild, accurate_p);
10762 }
10763
10764 if (accurate_p)
10765 {
10766 update_overlay_arrows (1);
10767 }
10768 else
10769 {
10770 /* Force a thorough redisplay the next time by setting
10771 last_arrow_position and last_arrow_string to t, which is
10772 unequal to any useful value of Voverlay_arrow_... */
10773 update_overlay_arrows (-1);
10774 }
10775 }
10776
10777
10778 /* Return value in display table DP (Lisp_Char_Table *) for character
10779 C. Since a display table doesn't have any parent, we don't have to
10780 follow parent. Do not call this function directly but use the
10781 macro DISP_CHAR_VECTOR. */
10782
10783 Lisp_Object
10784 disp_char_vector (dp, c)
10785 struct Lisp_Char_Table *dp;
10786 int c;
10787 {
10788 int code[4], i;
10789 Lisp_Object val;
10790
10791 if (SINGLE_BYTE_CHAR_P (c))
10792 return (dp->contents[c]);
10793
10794 SPLIT_CHAR (c, code[0], code[1], code[2]);
10795 if (code[1] < 32)
10796 code[1] = -1;
10797 else if (code[2] < 32)
10798 code[2] = -1;
10799
10800 /* Here, the possible range of code[0] (== charset ID) is
10801 128..max_charset. Since the top level char table contains data
10802 for multibyte characters after 256th element, we must increment
10803 code[0] by 128 to get a correct index. */
10804 code[0] += 128;
10805 code[3] = -1; /* anchor */
10806
10807 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10808 {
10809 val = dp->contents[code[i]];
10810 if (!SUB_CHAR_TABLE_P (val))
10811 return (NILP (val) ? dp->defalt : val);
10812 }
10813
10814 /* Here, val is a sub char table. We return the default value of
10815 it. */
10816 return (dp->defalt);
10817 }
10818
10819
10820 \f
10821 /***********************************************************************
10822 Window Redisplay
10823 ***********************************************************************/
10824
10825 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10826
10827 static void
10828 redisplay_windows (window)
10829 Lisp_Object window;
10830 {
10831 while (!NILP (window))
10832 {
10833 struct window *w = XWINDOW (window);
10834
10835 if (!NILP (w->hchild))
10836 redisplay_windows (w->hchild);
10837 else if (!NILP (w->vchild))
10838 redisplay_windows (w->vchild);
10839 else
10840 {
10841 displayed_buffer = XBUFFER (w->buffer);
10842 /* Use list_of_error, not Qerror, so that
10843 we catch only errors and don't run the debugger. */
10844 internal_condition_case_1 (redisplay_window_0, window,
10845 list_of_error,
10846 redisplay_window_error);
10847 }
10848
10849 window = w->next;
10850 }
10851 }
10852
10853 static Lisp_Object
10854 redisplay_window_error ()
10855 {
10856 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10857 return Qnil;
10858 }
10859
10860 static Lisp_Object
10861 redisplay_window_0 (window)
10862 Lisp_Object window;
10863 {
10864 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10865 redisplay_window (window, 0);
10866 return Qnil;
10867 }
10868
10869 static Lisp_Object
10870 redisplay_window_1 (window)
10871 Lisp_Object window;
10872 {
10873 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10874 redisplay_window (window, 1);
10875 return Qnil;
10876 }
10877 \f
10878
10879 /* Increment GLYPH until it reaches END or CONDITION fails while
10880 adding (GLYPH)->pixel_width to X. */
10881
10882 #define SKIP_GLYPHS(glyph, end, x, condition) \
10883 do \
10884 { \
10885 (x) += (glyph)->pixel_width; \
10886 ++(glyph); \
10887 } \
10888 while ((glyph) < (end) && (condition))
10889
10890
10891 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10892 DELTA is the number of bytes by which positions recorded in ROW
10893 differ from current buffer positions. */
10894
10895 void
10896 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10897 struct window *w;
10898 struct glyph_row *row;
10899 struct glyph_matrix *matrix;
10900 int delta, delta_bytes, dy, dvpos;
10901 {
10902 struct glyph *glyph = row->glyphs[TEXT_AREA];
10903 struct glyph *end = glyph + row->used[TEXT_AREA];
10904 struct glyph *cursor = NULL;
10905 /* The first glyph that starts a sequence of glyphs from string. */
10906 struct glyph *string_start;
10907 /* The X coordinate of string_start. */
10908 int string_start_x;
10909 /* The last known character position. */
10910 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10911 /* The last known character position before string_start. */
10912 int string_before_pos;
10913 int x = row->x;
10914 int cursor_x = x;
10915 int cursor_from_overlay_pos = 0;
10916 int pt_old = PT - delta;
10917
10918 /* Skip over glyphs not having an object at the start of the row.
10919 These are special glyphs like truncation marks on terminal
10920 frames. */
10921 if (row->displays_text_p)
10922 while (glyph < end
10923 && INTEGERP (glyph->object)
10924 && glyph->charpos < 0)
10925 {
10926 x += glyph->pixel_width;
10927 ++glyph;
10928 }
10929
10930 string_start = NULL;
10931 while (glyph < end
10932 && !INTEGERP (glyph->object)
10933 && (!BUFFERP (glyph->object)
10934 || (last_pos = glyph->charpos) < pt_old))
10935 {
10936 if (! STRINGP (glyph->object))
10937 {
10938 string_start = NULL;
10939 x += glyph->pixel_width;
10940 ++glyph;
10941 if (cursor_from_overlay_pos
10942 && last_pos > cursor_from_overlay_pos)
10943 {
10944 cursor_from_overlay_pos = 0;
10945 cursor = 0;
10946 }
10947 }
10948 else
10949 {
10950 string_before_pos = last_pos;
10951 string_start = glyph;
10952 string_start_x = x;
10953 /* Skip all glyphs from string. */
10954 do
10955 {
10956 int pos;
10957 if ((cursor == NULL || glyph > cursor)
10958 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10959 Qcursor, (glyph)->object))
10960 && (pos = string_buffer_position (w, glyph->object,
10961 string_before_pos),
10962 (pos == 0 /* From overlay */
10963 || pos == pt_old)))
10964 {
10965 /* Estimate overlay buffer position from the buffer
10966 positions of the glyphs before and after the overlay.
10967 Add 1 to last_pos so that if point corresponds to the
10968 glyph right after the overlay, we still use a 'cursor'
10969 property found in that overlay. */
10970 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10971 cursor = glyph;
10972 cursor_x = x;
10973 }
10974 x += glyph->pixel_width;
10975 ++glyph;
10976 }
10977 while (glyph < end && STRINGP (glyph->object));
10978 }
10979 }
10980
10981 if (cursor != NULL)
10982 {
10983 glyph = cursor;
10984 x = cursor_x;
10985 }
10986 else if (row->ends_in_ellipsis_p && glyph == end)
10987 {
10988 /* Scan back over the ellipsis glyphs, decrementing positions. */
10989 while (glyph > row->glyphs[TEXT_AREA]
10990 && (glyph - 1)->charpos == last_pos)
10991 glyph--, x -= glyph->pixel_width;
10992 /* That loop always goes one position too far,
10993 including the glyph before the ellipsis.
10994 So scan forward over that one. */
10995 x += glyph->pixel_width;
10996 glyph++;
10997 }
10998 else if (string_start
10999 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
11000 {
11001 /* We may have skipped over point because the previous glyphs
11002 are from string. As there's no easy way to know the
11003 character position of the current glyph, find the correct
11004 glyph on point by scanning from string_start again. */
11005 Lisp_Object limit;
11006 Lisp_Object string;
11007 int pos;
11008
11009 limit = make_number (pt_old + 1);
11010 end = glyph;
11011 glyph = string_start;
11012 x = string_start_x;
11013 string = glyph->object;
11014 pos = string_buffer_position (w, string, string_before_pos);
11015 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11016 because we always put cursor after overlay strings. */
11017 while (pos == 0 && glyph < end)
11018 {
11019 string = glyph->object;
11020 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11021 if (glyph < end)
11022 pos = string_buffer_position (w, glyph->object, string_before_pos);
11023 }
11024
11025 while (glyph < end)
11026 {
11027 pos = XINT (Fnext_single_char_property_change
11028 (make_number (pos), Qdisplay, Qnil, limit));
11029 if (pos > pt_old)
11030 break;
11031 /* Skip glyphs from the same string. */
11032 string = glyph->object;
11033 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11034 /* Skip glyphs from an overlay. */
11035 while (glyph < end
11036 && ! string_buffer_position (w, glyph->object, pos))
11037 {
11038 string = glyph->object;
11039 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11040 }
11041 }
11042 }
11043
11044 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
11045 w->cursor.x = x;
11046 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
11047 w->cursor.y = row->y + dy;
11048
11049 if (w == XWINDOW (selected_window))
11050 {
11051 if (!row->continued_p
11052 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
11053 && row->x == 0)
11054 {
11055 this_line_buffer = XBUFFER (w->buffer);
11056
11057 CHARPOS (this_line_start_pos)
11058 = MATRIX_ROW_START_CHARPOS (row) + delta;
11059 BYTEPOS (this_line_start_pos)
11060 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
11061
11062 CHARPOS (this_line_end_pos)
11063 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
11064 BYTEPOS (this_line_end_pos)
11065 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
11066
11067 this_line_y = w->cursor.y;
11068 this_line_pixel_height = row->height;
11069 this_line_vpos = w->cursor.vpos;
11070 this_line_start_x = row->x;
11071 }
11072 else
11073 CHARPOS (this_line_start_pos) = 0;
11074 }
11075 }
11076
11077
11078 /* Run window scroll functions, if any, for WINDOW with new window
11079 start STARTP. Sets the window start of WINDOW to that position.
11080
11081 We assume that the window's buffer is really current. */
11082
11083 static INLINE struct text_pos
11084 run_window_scroll_functions (window, startp)
11085 Lisp_Object window;
11086 struct text_pos startp;
11087 {
11088 struct window *w = XWINDOW (window);
11089 SET_MARKER_FROM_TEXT_POS (w->start, startp);
11090
11091 if (current_buffer != XBUFFER (w->buffer))
11092 abort ();
11093
11094 if (!NILP (Vwindow_scroll_functions))
11095 {
11096 run_hook_with_args_2 (Qwindow_scroll_functions, window,
11097 make_number (CHARPOS (startp)));
11098 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11099 /* In case the hook functions switch buffers. */
11100 if (current_buffer != XBUFFER (w->buffer))
11101 set_buffer_internal_1 (XBUFFER (w->buffer));
11102 }
11103
11104 return startp;
11105 }
11106
11107
11108 /* Make sure the line containing the cursor is fully visible.
11109 A value of 1 means there is nothing to be done.
11110 (Either the line is fully visible, or it cannot be made so,
11111 or we cannot tell.)
11112
11113 If FORCE_P is non-zero, return 0 even if partial visible cursor row
11114 is higher than window.
11115
11116 A value of 0 means the caller should do scrolling
11117 as if point had gone off the screen. */
11118
11119 static int
11120 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
11121 struct window *w;
11122 int force_p;
11123 {
11124 struct glyph_matrix *matrix;
11125 struct glyph_row *row;
11126 int window_height;
11127
11128 if (!make_cursor_line_fully_visible_p)
11129 return 1;
11130
11131 /* It's not always possible to find the cursor, e.g, when a window
11132 is full of overlay strings. Don't do anything in that case. */
11133 if (w->cursor.vpos < 0)
11134 return 1;
11135
11136 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
11137 row = MATRIX_ROW (matrix, w->cursor.vpos);
11138
11139 /* If the cursor row is not partially visible, there's nothing to do. */
11140 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
11141 return 1;
11142
11143 /* If the row the cursor is in is taller than the window's height,
11144 it's not clear what to do, so do nothing. */
11145 window_height = window_box_height (w);
11146 if (row->height >= window_height)
11147 {
11148 if (!force_p || w->vscroll)
11149 return 1;
11150 }
11151 return 0;
11152
11153 #if 0
11154 /* This code used to try to scroll the window just enough to make
11155 the line visible. It returned 0 to say that the caller should
11156 allocate larger glyph matrices. */
11157
11158 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
11159 {
11160 int dy = row->height - row->visible_height;
11161 w->vscroll = 0;
11162 w->cursor.y += dy;
11163 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11164 }
11165 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11166 {
11167 int dy = - (row->height - row->visible_height);
11168 w->vscroll = dy;
11169 w->cursor.y += dy;
11170 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11171 }
11172
11173 /* When we change the cursor y-position of the selected window,
11174 change this_line_y as well so that the display optimization for
11175 the cursor line of the selected window in redisplay_internal uses
11176 the correct y-position. */
11177 if (w == XWINDOW (selected_window))
11178 this_line_y = w->cursor.y;
11179
11180 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11181 redisplay with larger matrices. */
11182 if (matrix->nrows < required_matrix_height (w))
11183 {
11184 fonts_changed_p = 1;
11185 return 0;
11186 }
11187
11188 return 1;
11189 #endif /* 0 */
11190 }
11191
11192
11193 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11194 non-zero means only WINDOW is redisplayed in redisplay_internal.
11195 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11196 in redisplay_window to bring a partially visible line into view in
11197 the case that only the cursor has moved.
11198
11199 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11200 last screen line's vertical height extends past the end of the screen.
11201
11202 Value is
11203
11204 1 if scrolling succeeded
11205
11206 0 if scrolling didn't find point.
11207
11208 -1 if new fonts have been loaded so that we must interrupt
11209 redisplay, adjust glyph matrices, and try again. */
11210
11211 enum
11212 {
11213 SCROLLING_SUCCESS,
11214 SCROLLING_FAILED,
11215 SCROLLING_NEED_LARGER_MATRICES
11216 };
11217
11218 static int
11219 try_scrolling (window, just_this_one_p, scroll_conservatively,
11220 scroll_step, temp_scroll_step, last_line_misfit)
11221 Lisp_Object window;
11222 int just_this_one_p;
11223 EMACS_INT scroll_conservatively, scroll_step;
11224 int temp_scroll_step;
11225 int last_line_misfit;
11226 {
11227 struct window *w = XWINDOW (window);
11228 struct frame *f = XFRAME (w->frame);
11229 struct text_pos scroll_margin_pos;
11230 struct text_pos pos;
11231 struct text_pos startp;
11232 struct it it;
11233 Lisp_Object window_end;
11234 int this_scroll_margin;
11235 int dy = 0;
11236 int scroll_max;
11237 int rc;
11238 int amount_to_scroll = 0;
11239 Lisp_Object aggressive;
11240 int height;
11241 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
11242
11243 #if GLYPH_DEBUG
11244 debug_method_add (w, "try_scrolling");
11245 #endif
11246
11247 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11248
11249 /* Compute scroll margin height in pixels. We scroll when point is
11250 within this distance from the top or bottom of the window. */
11251 if (scroll_margin > 0)
11252 {
11253 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11254 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11255 }
11256 else
11257 this_scroll_margin = 0;
11258
11259 /* Force scroll_conservatively to have a reasonable value so it doesn't
11260 cause an overflow while computing how much to scroll. */
11261 if (scroll_conservatively)
11262 scroll_conservatively = min (scroll_conservatively,
11263 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11264
11265 /* Compute how much we should try to scroll maximally to bring point
11266 into view. */
11267 if (scroll_step || scroll_conservatively || temp_scroll_step)
11268 scroll_max = max (scroll_step,
11269 max (scroll_conservatively, temp_scroll_step));
11270 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11271 || NUMBERP (current_buffer->scroll_up_aggressively))
11272 /* We're trying to scroll because of aggressive scrolling
11273 but no scroll_step is set. Choose an arbitrary one. Maybe
11274 there should be a variable for this. */
11275 scroll_max = 10;
11276 else
11277 scroll_max = 0;
11278 scroll_max *= FRAME_LINE_HEIGHT (f);
11279
11280 /* Decide whether we have to scroll down. Start at the window end
11281 and move this_scroll_margin up to find the position of the scroll
11282 margin. */
11283 window_end = Fwindow_end (window, Qt);
11284
11285 too_near_end:
11286
11287 CHARPOS (scroll_margin_pos) = XINT (window_end);
11288 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11289
11290 if (this_scroll_margin || extra_scroll_margin_lines)
11291 {
11292 start_display (&it, w, scroll_margin_pos);
11293 if (this_scroll_margin)
11294 move_it_vertically_backward (&it, this_scroll_margin);
11295 if (extra_scroll_margin_lines)
11296 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11297 scroll_margin_pos = it.current.pos;
11298 }
11299
11300 if (PT >= CHARPOS (scroll_margin_pos))
11301 {
11302 int y0;
11303
11304 /* Point is in the scroll margin at the bottom of the window, or
11305 below. Compute a new window start that makes point visible. */
11306
11307 /* Compute the distance from the scroll margin to PT.
11308 Give up if the distance is greater than scroll_max. */
11309 start_display (&it, w, scroll_margin_pos);
11310 y0 = it.current_y;
11311 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11312 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11313
11314 /* To make point visible, we have to move the window start
11315 down so that the line the cursor is in is visible, which
11316 means we have to add in the height of the cursor line. */
11317 dy = line_bottom_y (&it) - y0;
11318
11319 if (dy > scroll_max)
11320 return SCROLLING_FAILED;
11321
11322 /* Move the window start down. If scrolling conservatively,
11323 move it just enough down to make point visible. If
11324 scroll_step is set, move it down by scroll_step. */
11325 start_display (&it, w, startp);
11326
11327 if (scroll_conservatively)
11328 /* Set AMOUNT_TO_SCROLL to at least one line,
11329 and at most scroll_conservatively lines. */
11330 amount_to_scroll
11331 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11332 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11333 else if (scroll_step || temp_scroll_step)
11334 amount_to_scroll = scroll_max;
11335 else
11336 {
11337 aggressive = current_buffer->scroll_up_aggressively;
11338 height = WINDOW_BOX_TEXT_HEIGHT (w);
11339 if (NUMBERP (aggressive))
11340 {
11341 double float_amount = XFLOATINT (aggressive) * height;
11342 amount_to_scroll = float_amount;
11343 if (amount_to_scroll == 0 && float_amount > 0)
11344 amount_to_scroll = 1;
11345 }
11346 }
11347
11348 if (amount_to_scroll <= 0)
11349 return SCROLLING_FAILED;
11350
11351 /* If moving by amount_to_scroll leaves STARTP unchanged,
11352 move it down one screen line. */
11353
11354 move_it_vertically (&it, amount_to_scroll);
11355 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11356 move_it_by_lines (&it, 1, 1);
11357 startp = it.current.pos;
11358 }
11359 else
11360 {
11361 /* See if point is inside the scroll margin at the top of the
11362 window. */
11363 scroll_margin_pos = startp;
11364 if (this_scroll_margin)
11365 {
11366 start_display (&it, w, startp);
11367 move_it_vertically (&it, this_scroll_margin);
11368 scroll_margin_pos = it.current.pos;
11369 }
11370
11371 if (PT < CHARPOS (scroll_margin_pos))
11372 {
11373 /* Point is in the scroll margin at the top of the window or
11374 above what is displayed in the window. */
11375 int y0;
11376
11377 /* Compute the vertical distance from PT to the scroll
11378 margin position. Give up if distance is greater than
11379 scroll_max. */
11380 SET_TEXT_POS (pos, PT, PT_BYTE);
11381 start_display (&it, w, pos);
11382 y0 = it.current_y;
11383 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11384 it.last_visible_y, -1,
11385 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11386 dy = it.current_y - y0;
11387 if (dy > scroll_max)
11388 return SCROLLING_FAILED;
11389
11390 /* Compute new window start. */
11391 start_display (&it, w, startp);
11392
11393 if (scroll_conservatively)
11394 amount_to_scroll
11395 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11396 else if (scroll_step || temp_scroll_step)
11397 amount_to_scroll = scroll_max;
11398 else
11399 {
11400 aggressive = current_buffer->scroll_down_aggressively;
11401 height = WINDOW_BOX_TEXT_HEIGHT (w);
11402 if (NUMBERP (aggressive))
11403 {
11404 double float_amount = XFLOATINT (aggressive) * height;
11405 amount_to_scroll = float_amount;
11406 if (amount_to_scroll == 0 && float_amount > 0)
11407 amount_to_scroll = 1;
11408 }
11409 }
11410
11411 if (amount_to_scroll <= 0)
11412 return SCROLLING_FAILED;
11413
11414 move_it_vertically_backward (&it, amount_to_scroll);
11415 startp = it.current.pos;
11416 }
11417 }
11418
11419 /* Run window scroll functions. */
11420 startp = run_window_scroll_functions (window, startp);
11421
11422 /* Display the window. Give up if new fonts are loaded, or if point
11423 doesn't appear. */
11424 if (!try_window (window, startp))
11425 rc = SCROLLING_NEED_LARGER_MATRICES;
11426 else if (w->cursor.vpos < 0)
11427 {
11428 clear_glyph_matrix (w->desired_matrix);
11429 rc = SCROLLING_FAILED;
11430 }
11431 else
11432 {
11433 /* Maybe forget recorded base line for line number display. */
11434 if (!just_this_one_p
11435 || current_buffer->clip_changed
11436 || BEG_UNCHANGED < CHARPOS (startp))
11437 w->base_line_number = Qnil;
11438
11439 /* If cursor ends up on a partially visible line,
11440 treat that as being off the bottom of the screen. */
11441 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
11442 {
11443 clear_glyph_matrix (w->desired_matrix);
11444 ++extra_scroll_margin_lines;
11445 goto too_near_end;
11446 }
11447 rc = SCROLLING_SUCCESS;
11448 }
11449
11450 return rc;
11451 }
11452
11453
11454 /* Compute a suitable window start for window W if display of W starts
11455 on a continuation line. Value is non-zero if a new window start
11456 was computed.
11457
11458 The new window start will be computed, based on W's width, starting
11459 from the start of the continued line. It is the start of the
11460 screen line with the minimum distance from the old start W->start. */
11461
11462 static int
11463 compute_window_start_on_continuation_line (w)
11464 struct window *w;
11465 {
11466 struct text_pos pos, start_pos;
11467 int window_start_changed_p = 0;
11468
11469 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11470
11471 /* If window start is on a continuation line... Window start may be
11472 < BEGV in case there's invisible text at the start of the
11473 buffer (M-x rmail, for example). */
11474 if (CHARPOS (start_pos) > BEGV
11475 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11476 {
11477 struct it it;
11478 struct glyph_row *row;
11479
11480 /* Handle the case that the window start is out of range. */
11481 if (CHARPOS (start_pos) < BEGV)
11482 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11483 else if (CHARPOS (start_pos) > ZV)
11484 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11485
11486 /* Find the start of the continued line. This should be fast
11487 because scan_buffer is fast (newline cache). */
11488 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11489 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11490 row, DEFAULT_FACE_ID);
11491 reseat_at_previous_visible_line_start (&it);
11492
11493 /* If the line start is "too far" away from the window start,
11494 say it takes too much time to compute a new window start. */
11495 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11496 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11497 {
11498 int min_distance, distance;
11499
11500 /* Move forward by display lines to find the new window
11501 start. If window width was enlarged, the new start can
11502 be expected to be > the old start. If window width was
11503 decreased, the new window start will be < the old start.
11504 So, we're looking for the display line start with the
11505 minimum distance from the old window start. */
11506 pos = it.current.pos;
11507 min_distance = INFINITY;
11508 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11509 distance < min_distance)
11510 {
11511 min_distance = distance;
11512 pos = it.current.pos;
11513 move_it_by_lines (&it, 1, 0);
11514 }
11515
11516 /* Set the window start there. */
11517 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11518 window_start_changed_p = 1;
11519 }
11520 }
11521
11522 return window_start_changed_p;
11523 }
11524
11525
11526 /* Try cursor movement in case text has not changed in window WINDOW,
11527 with window start STARTP. Value is
11528
11529 CURSOR_MOVEMENT_SUCCESS if successful
11530
11531 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11532
11533 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11534 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11535 we want to scroll as if scroll-step were set to 1. See the code.
11536
11537 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11538 which case we have to abort this redisplay, and adjust matrices
11539 first. */
11540
11541 enum
11542 {
11543 CURSOR_MOVEMENT_SUCCESS,
11544 CURSOR_MOVEMENT_CANNOT_BE_USED,
11545 CURSOR_MOVEMENT_MUST_SCROLL,
11546 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11547 };
11548
11549 static int
11550 try_cursor_movement (window, startp, scroll_step)
11551 Lisp_Object window;
11552 struct text_pos startp;
11553 int *scroll_step;
11554 {
11555 struct window *w = XWINDOW (window);
11556 struct frame *f = XFRAME (w->frame);
11557 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11558
11559 #if GLYPH_DEBUG
11560 if (inhibit_try_cursor_movement)
11561 return rc;
11562 #endif
11563
11564 /* Handle case where text has not changed, only point, and it has
11565 not moved off the frame. */
11566 if (/* Point may be in this window. */
11567 PT >= CHARPOS (startp)
11568 /* Selective display hasn't changed. */
11569 && !current_buffer->clip_changed
11570 /* Function force-mode-line-update is used to force a thorough
11571 redisplay. It sets either windows_or_buffers_changed or
11572 update_mode_lines. So don't take a shortcut here for these
11573 cases. */
11574 && !update_mode_lines
11575 && !windows_or_buffers_changed
11576 && !cursor_type_changed
11577 /* Can't use this case if highlighting a region. When a
11578 region exists, cursor movement has to do more than just
11579 set the cursor. */
11580 && !(!NILP (Vtransient_mark_mode)
11581 && !NILP (current_buffer->mark_active))
11582 && NILP (w->region_showing)
11583 && NILP (Vshow_trailing_whitespace)
11584 /* Right after splitting windows, last_point may be nil. */
11585 && INTEGERP (w->last_point)
11586 /* This code is not used for mini-buffer for the sake of the case
11587 of redisplaying to replace an echo area message; since in
11588 that case the mini-buffer contents per se are usually
11589 unchanged. This code is of no real use in the mini-buffer
11590 since the handling of this_line_start_pos, etc., in redisplay
11591 handles the same cases. */
11592 && !EQ (window, minibuf_window)
11593 /* When splitting windows or for new windows, it happens that
11594 redisplay is called with a nil window_end_vpos or one being
11595 larger than the window. This should really be fixed in
11596 window.c. I don't have this on my list, now, so we do
11597 approximately the same as the old redisplay code. --gerd. */
11598 && INTEGERP (w->window_end_vpos)
11599 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11600 && (FRAME_WINDOW_P (f)
11601 || !overlay_arrow_in_current_buffer_p ()))
11602 {
11603 int this_scroll_margin, top_scroll_margin;
11604 struct glyph_row *row = NULL;
11605
11606 #if GLYPH_DEBUG
11607 debug_method_add (w, "cursor movement");
11608 #endif
11609
11610 /* Scroll if point within this distance from the top or bottom
11611 of the window. This is a pixel value. */
11612 this_scroll_margin = max (0, scroll_margin);
11613 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11614 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11615
11616 top_scroll_margin = this_scroll_margin;
11617 if (WINDOW_WANTS_HEADER_LINE_P (w))
11618 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11619
11620 /* Start with the row the cursor was displayed during the last
11621 not paused redisplay. Give up if that row is not valid. */
11622 if (w->last_cursor.vpos < 0
11623 || w->last_cursor.vpos >= w->current_matrix->nrows)
11624 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11625 else
11626 {
11627 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11628 if (row->mode_line_p)
11629 ++row;
11630 if (!row->enabled_p)
11631 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11632 }
11633
11634 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11635 {
11636 int scroll_p = 0;
11637 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11638
11639 if (PT > XFASTINT (w->last_point))
11640 {
11641 /* Point has moved forward. */
11642 while (MATRIX_ROW_END_CHARPOS (row) < PT
11643 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11644 {
11645 xassert (row->enabled_p);
11646 ++row;
11647 }
11648
11649 /* The end position of a row equals the start position
11650 of the next row. If PT is there, we would rather
11651 display it in the next line. */
11652 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11653 && MATRIX_ROW_END_CHARPOS (row) == PT
11654 && !cursor_row_p (w, row))
11655 ++row;
11656
11657 /* If within the scroll margin, scroll. Note that
11658 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11659 the next line would be drawn, and that
11660 this_scroll_margin can be zero. */
11661 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11662 || PT > MATRIX_ROW_END_CHARPOS (row)
11663 /* Line is completely visible last line in window
11664 and PT is to be set in the next line. */
11665 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11666 && PT == MATRIX_ROW_END_CHARPOS (row)
11667 && !row->ends_at_zv_p
11668 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11669 scroll_p = 1;
11670 }
11671 else if (PT < XFASTINT (w->last_point))
11672 {
11673 /* Cursor has to be moved backward. Note that PT >=
11674 CHARPOS (startp) because of the outer if-statement. */
11675 while (!row->mode_line_p
11676 && (MATRIX_ROW_START_CHARPOS (row) > PT
11677 || (MATRIX_ROW_START_CHARPOS (row) == PT
11678 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11679 && (row->y > top_scroll_margin
11680 || CHARPOS (startp) == BEGV))
11681 {
11682 xassert (row->enabled_p);
11683 --row;
11684 }
11685
11686 /* Consider the following case: Window starts at BEGV,
11687 there is invisible, intangible text at BEGV, so that
11688 display starts at some point START > BEGV. It can
11689 happen that we are called with PT somewhere between
11690 BEGV and START. Try to handle that case. */
11691 if (row < w->current_matrix->rows
11692 || row->mode_line_p)
11693 {
11694 row = w->current_matrix->rows;
11695 if (row->mode_line_p)
11696 ++row;
11697 }
11698
11699 /* Due to newlines in overlay strings, we may have to
11700 skip forward over overlay strings. */
11701 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11702 && MATRIX_ROW_END_CHARPOS (row) == PT
11703 && !cursor_row_p (w, row))
11704 ++row;
11705
11706 /* If within the scroll margin, scroll. */
11707 if (row->y < top_scroll_margin
11708 && CHARPOS (startp) != BEGV)
11709 scroll_p = 1;
11710 }
11711 else
11712 {
11713 /* Cursor did not move. So don't scroll even if cursor line
11714 is partially visible, as it was so before. */
11715 rc = CURSOR_MOVEMENT_SUCCESS;
11716 }
11717
11718 if (PT < MATRIX_ROW_START_CHARPOS (row)
11719 || PT > MATRIX_ROW_END_CHARPOS (row))
11720 {
11721 /* if PT is not in the glyph row, give up. */
11722 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11723 }
11724 else if (rc != CURSOR_MOVEMENT_SUCCESS
11725 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11726 && make_cursor_line_fully_visible_p)
11727 {
11728 if (PT == MATRIX_ROW_END_CHARPOS (row)
11729 && !row->ends_at_zv_p
11730 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11731 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11732 else if (row->height > window_box_height (w))
11733 {
11734 /* If we end up in a partially visible line, let's
11735 make it fully visible, except when it's taller
11736 than the window, in which case we can't do much
11737 about it. */
11738 *scroll_step = 1;
11739 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11740 }
11741 else
11742 {
11743 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11744 if (!cursor_row_fully_visible_p (w, 0, 1))
11745 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11746 else
11747 rc = CURSOR_MOVEMENT_SUCCESS;
11748 }
11749 }
11750 else if (scroll_p)
11751 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11752 else
11753 {
11754 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11755 rc = CURSOR_MOVEMENT_SUCCESS;
11756 }
11757 }
11758 }
11759
11760 return rc;
11761 }
11762
11763 void
11764 set_vertical_scroll_bar (w)
11765 struct window *w;
11766 {
11767 int start, end, whole;
11768
11769 /* Calculate the start and end positions for the current window.
11770 At some point, it would be nice to choose between scrollbars
11771 which reflect the whole buffer size, with special markers
11772 indicating narrowing, and scrollbars which reflect only the
11773 visible region.
11774
11775 Note that mini-buffers sometimes aren't displaying any text. */
11776 if (!MINI_WINDOW_P (w)
11777 || (w == XWINDOW (minibuf_window)
11778 && NILP (echo_area_buffer[0])))
11779 {
11780 struct buffer *buf = XBUFFER (w->buffer);
11781 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11782 start = marker_position (w->start) - BUF_BEGV (buf);
11783 /* I don't think this is guaranteed to be right. For the
11784 moment, we'll pretend it is. */
11785 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11786
11787 if (end < start)
11788 end = start;
11789 if (whole < (end - start))
11790 whole = end - start;
11791 }
11792 else
11793 start = end = whole = 0;
11794
11795 /* Indicate what this scroll bar ought to be displaying now. */
11796 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11797 }
11798
11799
11800 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11801 selected_window is redisplayed.
11802
11803 We can return without actually redisplaying the window if
11804 fonts_changed_p is nonzero. In that case, redisplay_internal will
11805 retry. */
11806
11807 static void
11808 redisplay_window (window, just_this_one_p)
11809 Lisp_Object window;
11810 int just_this_one_p;
11811 {
11812 struct window *w = XWINDOW (window);
11813 struct frame *f = XFRAME (w->frame);
11814 struct buffer *buffer = XBUFFER (w->buffer);
11815 struct buffer *old = current_buffer;
11816 struct text_pos lpoint, opoint, startp;
11817 int update_mode_line;
11818 int tem;
11819 struct it it;
11820 /* Record it now because it's overwritten. */
11821 int current_matrix_up_to_date_p = 0;
11822 int used_current_matrix_p = 0;
11823 /* This is less strict than current_matrix_up_to_date_p.
11824 It indictes that the buffer contents and narrowing are unchanged. */
11825 int buffer_unchanged_p = 0;
11826 int temp_scroll_step = 0;
11827 int count = SPECPDL_INDEX ();
11828 int rc;
11829 int centering_position = -1;
11830 int last_line_misfit = 0;
11831
11832 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11833 opoint = lpoint;
11834
11835 /* W must be a leaf window here. */
11836 xassert (!NILP (w->buffer));
11837 #if GLYPH_DEBUG
11838 *w->desired_matrix->method = 0;
11839 #endif
11840
11841 specbind (Qinhibit_point_motion_hooks, Qt);
11842
11843 reconsider_clip_changes (w, buffer);
11844
11845 /* Has the mode line to be updated? */
11846 update_mode_line = (!NILP (w->update_mode_line)
11847 || update_mode_lines
11848 || buffer->clip_changed
11849 || buffer->prevent_redisplay_optimizations_p);
11850
11851 if (MINI_WINDOW_P (w))
11852 {
11853 if (w == XWINDOW (echo_area_window)
11854 && !NILP (echo_area_buffer[0]))
11855 {
11856 if (update_mode_line)
11857 /* We may have to update a tty frame's menu bar or a
11858 tool-bar. Example `M-x C-h C-h C-g'. */
11859 goto finish_menu_bars;
11860 else
11861 /* We've already displayed the echo area glyphs in this window. */
11862 goto finish_scroll_bars;
11863 }
11864 else if ((w != XWINDOW (minibuf_window)
11865 || minibuf_level == 0)
11866 /* When buffer is nonempty, redisplay window normally. */
11867 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11868 /* Quail displays non-mini buffers in minibuffer window.
11869 In that case, redisplay the window normally. */
11870 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11871 {
11872 /* W is a mini-buffer window, but it's not active, so clear
11873 it. */
11874 int yb = window_text_bottom_y (w);
11875 struct glyph_row *row;
11876 int y;
11877
11878 for (y = 0, row = w->desired_matrix->rows;
11879 y < yb;
11880 y += row->height, ++row)
11881 blank_row (w, row, y);
11882 goto finish_scroll_bars;
11883 }
11884
11885 clear_glyph_matrix (w->desired_matrix);
11886 }
11887
11888 /* Otherwise set up data on this window; select its buffer and point
11889 value. */
11890 /* Really select the buffer, for the sake of buffer-local
11891 variables. */
11892 set_buffer_internal_1 (XBUFFER (w->buffer));
11893 SET_TEXT_POS (opoint, PT, PT_BYTE);
11894
11895 current_matrix_up_to_date_p
11896 = (!NILP (w->window_end_valid)
11897 && !current_buffer->clip_changed
11898 && !current_buffer->prevent_redisplay_optimizations_p
11899 && XFASTINT (w->last_modified) >= MODIFF
11900 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11901
11902 buffer_unchanged_p
11903 = (!NILP (w->window_end_valid)
11904 && !current_buffer->clip_changed
11905 && XFASTINT (w->last_modified) >= MODIFF
11906 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11907
11908 /* When windows_or_buffers_changed is non-zero, we can't rely on
11909 the window end being valid, so set it to nil there. */
11910 if (windows_or_buffers_changed)
11911 {
11912 /* If window starts on a continuation line, maybe adjust the
11913 window start in case the window's width changed. */
11914 if (XMARKER (w->start)->buffer == current_buffer)
11915 compute_window_start_on_continuation_line (w);
11916
11917 w->window_end_valid = Qnil;
11918 }
11919
11920 /* Some sanity checks. */
11921 CHECK_WINDOW_END (w);
11922 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11923 abort ();
11924 if (BYTEPOS (opoint) < CHARPOS (opoint))
11925 abort ();
11926
11927 /* If %c is in mode line, update it if needed. */
11928 if (!NILP (w->column_number_displayed)
11929 /* This alternative quickly identifies a common case
11930 where no change is needed. */
11931 && !(PT == XFASTINT (w->last_point)
11932 && XFASTINT (w->last_modified) >= MODIFF
11933 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11934 && (XFASTINT (w->column_number_displayed)
11935 != (int) current_column ())) /* iftc */
11936 update_mode_line = 1;
11937
11938 /* Count number of windows showing the selected buffer. An indirect
11939 buffer counts as its base buffer. */
11940 if (!just_this_one_p)
11941 {
11942 struct buffer *current_base, *window_base;
11943 current_base = current_buffer;
11944 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11945 if (current_base->base_buffer)
11946 current_base = current_base->base_buffer;
11947 if (window_base->base_buffer)
11948 window_base = window_base->base_buffer;
11949 if (current_base == window_base)
11950 buffer_shared++;
11951 }
11952
11953 /* Point refers normally to the selected window. For any other
11954 window, set up appropriate value. */
11955 if (!EQ (window, selected_window))
11956 {
11957 int new_pt = XMARKER (w->pointm)->charpos;
11958 int new_pt_byte = marker_byte_position (w->pointm);
11959 if (new_pt < BEGV)
11960 {
11961 new_pt = BEGV;
11962 new_pt_byte = BEGV_BYTE;
11963 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11964 }
11965 else if (new_pt > (ZV - 1))
11966 {
11967 new_pt = ZV;
11968 new_pt_byte = ZV_BYTE;
11969 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11970 }
11971
11972 /* We don't use SET_PT so that the point-motion hooks don't run. */
11973 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11974 }
11975
11976 /* If any of the character widths specified in the display table
11977 have changed, invalidate the width run cache. It's true that
11978 this may be a bit late to catch such changes, but the rest of
11979 redisplay goes (non-fatally) haywire when the display table is
11980 changed, so why should we worry about doing any better? */
11981 if (current_buffer->width_run_cache)
11982 {
11983 struct Lisp_Char_Table *disptab = buffer_display_table ();
11984
11985 if (! disptab_matches_widthtab (disptab,
11986 XVECTOR (current_buffer->width_table)))
11987 {
11988 invalidate_region_cache (current_buffer,
11989 current_buffer->width_run_cache,
11990 BEG, Z);
11991 recompute_width_table (current_buffer, disptab);
11992 }
11993 }
11994
11995 /* If window-start is screwed up, choose a new one. */
11996 if (XMARKER (w->start)->buffer != current_buffer)
11997 goto recenter;
11998
11999 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12000
12001 /* If someone specified a new starting point but did not insist,
12002 check whether it can be used. */
12003 if (!NILP (w->optional_new_start)
12004 && CHARPOS (startp) >= BEGV
12005 && CHARPOS (startp) <= ZV)
12006 {
12007 w->optional_new_start = Qnil;
12008 start_display (&it, w, startp);
12009 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12010 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12011 if (IT_CHARPOS (it) == PT)
12012 w->force_start = Qt;
12013 /* IT may overshoot PT if text at PT is invisible. */
12014 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
12015 w->force_start = Qt;
12016
12017
12018 }
12019
12020 /* Handle case where place to start displaying has been specified,
12021 unless the specified location is outside the accessible range. */
12022 if (!NILP (w->force_start)
12023 || w->frozen_window_start_p)
12024 {
12025 /* We set this later on if we have to adjust point. */
12026 int new_vpos = -1;
12027
12028 w->force_start = Qnil;
12029 w->vscroll = 0;
12030 w->window_end_valid = Qnil;
12031
12032 /* Forget any recorded base line for line number display. */
12033 if (!buffer_unchanged_p)
12034 w->base_line_number = Qnil;
12035
12036 /* Redisplay the mode line. Select the buffer properly for that.
12037 Also, run the hook window-scroll-functions
12038 because we have scrolled. */
12039 /* Note, we do this after clearing force_start because
12040 if there's an error, it is better to forget about force_start
12041 than to get into an infinite loop calling the hook functions
12042 and having them get more errors. */
12043 if (!update_mode_line
12044 || ! NILP (Vwindow_scroll_functions))
12045 {
12046 update_mode_line = 1;
12047 w->update_mode_line = Qt;
12048 startp = run_window_scroll_functions (window, startp);
12049 }
12050
12051 w->last_modified = make_number (0);
12052 w->last_overlay_modified = make_number (0);
12053 if (CHARPOS (startp) < BEGV)
12054 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
12055 else if (CHARPOS (startp) > ZV)
12056 SET_TEXT_POS (startp, ZV, ZV_BYTE);
12057
12058 /* Redisplay, then check if cursor has been set during the
12059 redisplay. Give up if new fonts were loaded. */
12060 if (!try_window (window, startp))
12061 {
12062 w->force_start = Qt;
12063 clear_glyph_matrix (w->desired_matrix);
12064 goto need_larger_matrices;
12065 }
12066
12067 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
12068 {
12069 /* If point does not appear, try to move point so it does
12070 appear. The desired matrix has been built above, so we
12071 can use it here. */
12072 new_vpos = window_box_height (w) / 2;
12073 }
12074
12075 if (!cursor_row_fully_visible_p (w, 0, 0))
12076 {
12077 /* Point does appear, but on a line partly visible at end of window.
12078 Move it back to a fully-visible line. */
12079 new_vpos = window_box_height (w);
12080 }
12081
12082 /* If we need to move point for either of the above reasons,
12083 now actually do it. */
12084 if (new_vpos >= 0)
12085 {
12086 struct glyph_row *row;
12087
12088 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
12089 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
12090 ++row;
12091
12092 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
12093 MATRIX_ROW_START_BYTEPOS (row));
12094
12095 if (w != XWINDOW (selected_window))
12096 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
12097 else if (current_buffer == old)
12098 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12099
12100 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
12101
12102 /* If we are highlighting the region, then we just changed
12103 the region, so redisplay to show it. */
12104 if (!NILP (Vtransient_mark_mode)
12105 && !NILP (current_buffer->mark_active))
12106 {
12107 clear_glyph_matrix (w->desired_matrix);
12108 if (!try_window (window, startp))
12109 goto need_larger_matrices;
12110 }
12111 }
12112
12113 #if GLYPH_DEBUG
12114 debug_method_add (w, "forced window start");
12115 #endif
12116 goto done;
12117 }
12118
12119 /* Handle case where text has not changed, only point, and it has
12120 not moved off the frame, and we are not retrying after hscroll.
12121 (current_matrix_up_to_date_p is nonzero when retrying.) */
12122 if (current_matrix_up_to_date_p
12123 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
12124 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
12125 {
12126 switch (rc)
12127 {
12128 case CURSOR_MOVEMENT_SUCCESS:
12129 used_current_matrix_p = 1;
12130 goto done;
12131
12132 #if 0 /* try_cursor_movement never returns this value. */
12133 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
12134 goto need_larger_matrices;
12135 #endif
12136
12137 case CURSOR_MOVEMENT_MUST_SCROLL:
12138 goto try_to_scroll;
12139
12140 default:
12141 abort ();
12142 }
12143 }
12144 /* If current starting point was originally the beginning of a line
12145 but no longer is, find a new starting point. */
12146 else if (!NILP (w->start_at_line_beg)
12147 && !(CHARPOS (startp) <= BEGV
12148 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
12149 {
12150 #if GLYPH_DEBUG
12151 debug_method_add (w, "recenter 1");
12152 #endif
12153 goto recenter;
12154 }
12155
12156 /* Try scrolling with try_window_id. Value is > 0 if update has
12157 been done, it is -1 if we know that the same window start will
12158 not work. It is 0 if unsuccessful for some other reason. */
12159 else if ((tem = try_window_id (w)) != 0)
12160 {
12161 #if GLYPH_DEBUG
12162 debug_method_add (w, "try_window_id %d", tem);
12163 #endif
12164
12165 if (fonts_changed_p)
12166 goto need_larger_matrices;
12167 if (tem > 0)
12168 goto done;
12169
12170 /* Otherwise try_window_id has returned -1 which means that we
12171 don't want the alternative below this comment to execute. */
12172 }
12173 else if (CHARPOS (startp) >= BEGV
12174 && CHARPOS (startp) <= ZV
12175 && PT >= CHARPOS (startp)
12176 && (CHARPOS (startp) < ZV
12177 /* Avoid starting at end of buffer. */
12178 || CHARPOS (startp) == BEGV
12179 || (XFASTINT (w->last_modified) >= MODIFF
12180 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
12181 {
12182 #if GLYPH_DEBUG
12183 debug_method_add (w, "same window start");
12184 #endif
12185
12186 /* Try to redisplay starting at same place as before.
12187 If point has not moved off frame, accept the results. */
12188 if (!current_matrix_up_to_date_p
12189 /* Don't use try_window_reusing_current_matrix in this case
12190 because a window scroll function can have changed the
12191 buffer. */
12192 || !NILP (Vwindow_scroll_functions)
12193 || MINI_WINDOW_P (w)
12194 || !(used_current_matrix_p
12195 = try_window_reusing_current_matrix (w)))
12196 {
12197 IF_DEBUG (debug_method_add (w, "1"));
12198 try_window (window, startp);
12199 }
12200
12201 if (fonts_changed_p)
12202 goto need_larger_matrices;
12203
12204 if (w->cursor.vpos >= 0)
12205 {
12206 if (!just_this_one_p
12207 || current_buffer->clip_changed
12208 || BEG_UNCHANGED < CHARPOS (startp))
12209 /* Forget any recorded base line for line number display. */
12210 w->base_line_number = Qnil;
12211
12212 if (!cursor_row_fully_visible_p (w, 1, 0))
12213 {
12214 clear_glyph_matrix (w->desired_matrix);
12215 last_line_misfit = 1;
12216 }
12217 /* Drop through and scroll. */
12218 else
12219 goto done;
12220 }
12221 else
12222 clear_glyph_matrix (w->desired_matrix);
12223 }
12224
12225 try_to_scroll:
12226
12227 w->last_modified = make_number (0);
12228 w->last_overlay_modified = make_number (0);
12229
12230 /* Redisplay the mode line. Select the buffer properly for that. */
12231 if (!update_mode_line)
12232 {
12233 update_mode_line = 1;
12234 w->update_mode_line = Qt;
12235 }
12236
12237 /* Try to scroll by specified few lines. */
12238 if ((scroll_conservatively
12239 || scroll_step
12240 || temp_scroll_step
12241 || NUMBERP (current_buffer->scroll_up_aggressively)
12242 || NUMBERP (current_buffer->scroll_down_aggressively))
12243 && !current_buffer->clip_changed
12244 && CHARPOS (startp) >= BEGV
12245 && CHARPOS (startp) <= ZV)
12246 {
12247 /* The function returns -1 if new fonts were loaded, 1 if
12248 successful, 0 if not successful. */
12249 int rc = try_scrolling (window, just_this_one_p,
12250 scroll_conservatively,
12251 scroll_step,
12252 temp_scroll_step, last_line_misfit);
12253 switch (rc)
12254 {
12255 case SCROLLING_SUCCESS:
12256 goto done;
12257
12258 case SCROLLING_NEED_LARGER_MATRICES:
12259 goto need_larger_matrices;
12260
12261 case SCROLLING_FAILED:
12262 break;
12263
12264 default:
12265 abort ();
12266 }
12267 }
12268
12269 /* Finally, just choose place to start which centers point */
12270
12271 recenter:
12272 if (centering_position < 0)
12273 centering_position = window_box_height (w) / 2;
12274
12275 #if GLYPH_DEBUG
12276 debug_method_add (w, "recenter");
12277 #endif
12278
12279 /* w->vscroll = 0; */
12280
12281 /* Forget any previously recorded base line for line number display. */
12282 if (!buffer_unchanged_p)
12283 w->base_line_number = Qnil;
12284
12285 /* Move backward half the height of the window. */
12286 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12287 it.current_y = it.last_visible_y;
12288 move_it_vertically_backward (&it, centering_position);
12289 xassert (IT_CHARPOS (it) >= BEGV);
12290
12291 /* The function move_it_vertically_backward may move over more
12292 than the specified y-distance. If it->w is small, e.g. a
12293 mini-buffer window, we may end up in front of the window's
12294 display area. Start displaying at the start of the line
12295 containing PT in this case. */
12296 if (it.current_y <= 0)
12297 {
12298 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12299 move_it_vertically_backward (&it, 0);
12300 #if 0
12301 /* I think this assert is bogus if buffer contains
12302 invisible text or images. KFS. */
12303 xassert (IT_CHARPOS (it) <= PT);
12304 #endif
12305 it.current_y = 0;
12306 }
12307
12308 it.current_x = it.hpos = 0;
12309
12310 /* Set startp here explicitly in case that helps avoid an infinite loop
12311 in case the window-scroll-functions functions get errors. */
12312 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12313
12314 /* Run scroll hooks. */
12315 startp = run_window_scroll_functions (window, it.current.pos);
12316
12317 /* Redisplay the window. */
12318 if (!current_matrix_up_to_date_p
12319 || windows_or_buffers_changed
12320 || cursor_type_changed
12321 /* Don't use try_window_reusing_current_matrix in this case
12322 because it can have changed the buffer. */
12323 || !NILP (Vwindow_scroll_functions)
12324 || !just_this_one_p
12325 || MINI_WINDOW_P (w)
12326 || !(used_current_matrix_p
12327 = try_window_reusing_current_matrix (w)))
12328 try_window (window, startp);
12329
12330 /* If new fonts have been loaded (due to fontsets), give up. We
12331 have to start a new redisplay since we need to re-adjust glyph
12332 matrices. */
12333 if (fonts_changed_p)
12334 goto need_larger_matrices;
12335
12336 /* If cursor did not appear assume that the middle of the window is
12337 in the first line of the window. Do it again with the next line.
12338 (Imagine a window of height 100, displaying two lines of height
12339 60. Moving back 50 from it->last_visible_y will end in the first
12340 line.) */
12341 if (w->cursor.vpos < 0)
12342 {
12343 if (!NILP (w->window_end_valid)
12344 && PT >= Z - XFASTINT (w->window_end_pos))
12345 {
12346 clear_glyph_matrix (w->desired_matrix);
12347 move_it_by_lines (&it, 1, 0);
12348 try_window (window, it.current.pos);
12349 }
12350 else if (PT < IT_CHARPOS (it))
12351 {
12352 clear_glyph_matrix (w->desired_matrix);
12353 move_it_by_lines (&it, -1, 0);
12354 try_window (window, it.current.pos);
12355 }
12356 else
12357 {
12358 /* Not much we can do about it. */
12359 }
12360 }
12361
12362 /* Consider the following case: Window starts at BEGV, there is
12363 invisible, intangible text at BEGV, so that display starts at
12364 some point START > BEGV. It can happen that we are called with
12365 PT somewhere between BEGV and START. Try to handle that case. */
12366 if (w->cursor.vpos < 0)
12367 {
12368 struct glyph_row *row = w->current_matrix->rows;
12369 if (row->mode_line_p)
12370 ++row;
12371 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12372 }
12373
12374 if (!cursor_row_fully_visible_p (w, 0, 0))
12375 {
12376 /* If vscroll is enabled, disable it and try again. */
12377 if (w->vscroll)
12378 {
12379 w->vscroll = 0;
12380 clear_glyph_matrix (w->desired_matrix);
12381 goto recenter;
12382 }
12383
12384 /* If centering point failed to make the whole line visible,
12385 put point at the top instead. That has to make the whole line
12386 visible, if it can be done. */
12387 if (centering_position == 0)
12388 goto done;
12389
12390 clear_glyph_matrix (w->desired_matrix);
12391 centering_position = 0;
12392 goto recenter;
12393 }
12394
12395 done:
12396
12397 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12398 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12399 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12400 ? Qt : Qnil);
12401
12402 /* Display the mode line, if we must. */
12403 if ((update_mode_line
12404 /* If window not full width, must redo its mode line
12405 if (a) the window to its side is being redone and
12406 (b) we do a frame-based redisplay. This is a consequence
12407 of how inverted lines are drawn in frame-based redisplay. */
12408 || (!just_this_one_p
12409 && !FRAME_WINDOW_P (f)
12410 && !WINDOW_FULL_WIDTH_P (w))
12411 /* Line number to display. */
12412 || INTEGERP (w->base_line_pos)
12413 /* Column number is displayed and different from the one displayed. */
12414 || (!NILP (w->column_number_displayed)
12415 && (XFASTINT (w->column_number_displayed)
12416 != (int) current_column ()))) /* iftc */
12417 /* This means that the window has a mode line. */
12418 && (WINDOW_WANTS_MODELINE_P (w)
12419 || WINDOW_WANTS_HEADER_LINE_P (w)))
12420 {
12421 display_mode_lines (w);
12422
12423 /* If mode line height has changed, arrange for a thorough
12424 immediate redisplay using the correct mode line height. */
12425 if (WINDOW_WANTS_MODELINE_P (w)
12426 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12427 {
12428 fonts_changed_p = 1;
12429 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12430 = DESIRED_MODE_LINE_HEIGHT (w);
12431 }
12432
12433 /* If top line height has changed, arrange for a thorough
12434 immediate redisplay using the correct mode line height. */
12435 if (WINDOW_WANTS_HEADER_LINE_P (w)
12436 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12437 {
12438 fonts_changed_p = 1;
12439 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12440 = DESIRED_HEADER_LINE_HEIGHT (w);
12441 }
12442
12443 if (fonts_changed_p)
12444 goto need_larger_matrices;
12445 }
12446
12447 if (!line_number_displayed
12448 && !BUFFERP (w->base_line_pos))
12449 {
12450 w->base_line_pos = Qnil;
12451 w->base_line_number = Qnil;
12452 }
12453
12454 finish_menu_bars:
12455
12456 /* When we reach a frame's selected window, redo the frame's menu bar. */
12457 if (update_mode_line
12458 && EQ (FRAME_SELECTED_WINDOW (f), window))
12459 {
12460 int redisplay_menu_p = 0;
12461 int redisplay_tool_bar_p = 0;
12462
12463 if (FRAME_WINDOW_P (f))
12464 {
12465 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12466 || defined (USE_GTK)
12467 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12468 #else
12469 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12470 #endif
12471 }
12472 else
12473 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12474
12475 if (redisplay_menu_p)
12476 display_menu_bar (w);
12477
12478 #ifdef HAVE_WINDOW_SYSTEM
12479 #ifdef USE_GTK
12480 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12481 #else
12482 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12483 && (FRAME_TOOL_BAR_LINES (f) > 0
12484 || auto_resize_tool_bars_p);
12485
12486 #endif
12487
12488 if (redisplay_tool_bar_p)
12489 redisplay_tool_bar (f);
12490 #endif
12491 }
12492
12493 #ifdef HAVE_WINDOW_SYSTEM
12494 if (FRAME_WINDOW_P (f)
12495 && update_window_fringes (w, 0)
12496 && !just_this_one_p
12497 && (used_current_matrix_p || overlay_arrow_seen)
12498 && !w->pseudo_window_p)
12499 {
12500 update_begin (f);
12501 BLOCK_INPUT;
12502 if (draw_window_fringes (w, 1))
12503 x_draw_vertical_border (w);
12504 UNBLOCK_INPUT;
12505 update_end (f);
12506 }
12507 #endif /* HAVE_WINDOW_SYSTEM */
12508
12509 /* We go to this label, with fonts_changed_p nonzero,
12510 if it is necessary to try again using larger glyph matrices.
12511 We have to redeem the scroll bar even in this case,
12512 because the loop in redisplay_internal expects that. */
12513 need_larger_matrices:
12514 ;
12515 finish_scroll_bars:
12516
12517 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12518 {
12519 /* Set the thumb's position and size. */
12520 set_vertical_scroll_bar (w);
12521
12522 /* Note that we actually used the scroll bar attached to this
12523 window, so it shouldn't be deleted at the end of redisplay. */
12524 redeem_scroll_bar_hook (w);
12525 }
12526
12527 /* Restore current_buffer and value of point in it. */
12528 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12529 set_buffer_internal_1 (old);
12530 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12531
12532 unbind_to (count, Qnil);
12533 }
12534
12535
12536 /* Build the complete desired matrix of WINDOW with a window start
12537 buffer position POS. Value is non-zero if successful. It is zero
12538 if fonts were loaded during redisplay which makes re-adjusting
12539 glyph matrices necessary. */
12540
12541 int
12542 try_window (window, pos)
12543 Lisp_Object window;
12544 struct text_pos pos;
12545 {
12546 struct window *w = XWINDOW (window);
12547 struct it it;
12548 struct glyph_row *last_text_row = NULL;
12549
12550 /* Make POS the new window start. */
12551 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12552
12553 /* Mark cursor position as unknown. No overlay arrow seen. */
12554 w->cursor.vpos = -1;
12555 overlay_arrow_seen = 0;
12556
12557 /* Initialize iterator and info to start at POS. */
12558 start_display (&it, w, pos);
12559
12560 /* Display all lines of W. */
12561 while (it.current_y < it.last_visible_y)
12562 {
12563 if (display_line (&it))
12564 last_text_row = it.glyph_row - 1;
12565 if (fonts_changed_p)
12566 return 0;
12567 }
12568
12569 /* If bottom moved off end of frame, change mode line percentage. */
12570 if (XFASTINT (w->window_end_pos) <= 0
12571 && Z != IT_CHARPOS (it))
12572 w->update_mode_line = Qt;
12573
12574 /* Set window_end_pos to the offset of the last character displayed
12575 on the window from the end of current_buffer. Set
12576 window_end_vpos to its row number. */
12577 if (last_text_row)
12578 {
12579 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12580 w->window_end_bytepos
12581 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12582 w->window_end_pos
12583 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12584 w->window_end_vpos
12585 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12586 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12587 ->displays_text_p);
12588 }
12589 else
12590 {
12591 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12592 w->window_end_pos = make_number (Z - ZV);
12593 w->window_end_vpos = make_number (0);
12594 }
12595
12596 /* But that is not valid info until redisplay finishes. */
12597 w->window_end_valid = Qnil;
12598 return 1;
12599 }
12600
12601
12602 \f
12603 /************************************************************************
12604 Window redisplay reusing current matrix when buffer has not changed
12605 ************************************************************************/
12606
12607 /* Try redisplay of window W showing an unchanged buffer with a
12608 different window start than the last time it was displayed by
12609 reusing its current matrix. Value is non-zero if successful.
12610 W->start is the new window start. */
12611
12612 static int
12613 try_window_reusing_current_matrix (w)
12614 struct window *w;
12615 {
12616 struct frame *f = XFRAME (w->frame);
12617 struct glyph_row *row, *bottom_row;
12618 struct it it;
12619 struct run run;
12620 struct text_pos start, new_start;
12621 int nrows_scrolled, i;
12622 struct glyph_row *last_text_row;
12623 struct glyph_row *last_reused_text_row;
12624 struct glyph_row *start_row;
12625 int start_vpos, min_y, max_y;
12626
12627 #if GLYPH_DEBUG
12628 if (inhibit_try_window_reusing)
12629 return 0;
12630 #endif
12631
12632 if (/* This function doesn't handle terminal frames. */
12633 !FRAME_WINDOW_P (f)
12634 /* Don't try to reuse the display if windows have been split
12635 or such. */
12636 || windows_or_buffers_changed
12637 || cursor_type_changed)
12638 return 0;
12639
12640 /* Can't do this if region may have changed. */
12641 if ((!NILP (Vtransient_mark_mode)
12642 && !NILP (current_buffer->mark_active))
12643 || !NILP (w->region_showing)
12644 || !NILP (Vshow_trailing_whitespace))
12645 return 0;
12646
12647 /* If top-line visibility has changed, give up. */
12648 if (WINDOW_WANTS_HEADER_LINE_P (w)
12649 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12650 return 0;
12651
12652 /* Give up if old or new display is scrolled vertically. We could
12653 make this function handle this, but right now it doesn't. */
12654 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12655 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
12656 return 0;
12657
12658 /* The variable new_start now holds the new window start. The old
12659 start `start' can be determined from the current matrix. */
12660 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12661 start = start_row->start.pos;
12662 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12663
12664 /* Clear the desired matrix for the display below. */
12665 clear_glyph_matrix (w->desired_matrix);
12666
12667 if (CHARPOS (new_start) <= CHARPOS (start))
12668 {
12669 int first_row_y;
12670
12671 /* Don't use this method if the display starts with an ellipsis
12672 displayed for invisible text. It's not easy to handle that case
12673 below, and it's certainly not worth the effort since this is
12674 not a frequent case. */
12675 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12676 return 0;
12677
12678 IF_DEBUG (debug_method_add (w, "twu1"));
12679
12680 /* Display up to a row that can be reused. The variable
12681 last_text_row is set to the last row displayed that displays
12682 text. Note that it.vpos == 0 if or if not there is a
12683 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12684 start_display (&it, w, new_start);
12685 first_row_y = it.current_y;
12686 w->cursor.vpos = -1;
12687 last_text_row = last_reused_text_row = NULL;
12688
12689 while (it.current_y < it.last_visible_y
12690 && !fonts_changed_p)
12691 {
12692 /* If we have reached into the characters in the START row,
12693 that means the line boundaries have changed. So we
12694 can't start copying with the row START. Maybe it will
12695 work to start copying with the following row. */
12696 while (IT_CHARPOS (it) > CHARPOS (start))
12697 {
12698 /* Advance to the next row as the "start". */
12699 start_row++;
12700 start = start_row->start.pos;
12701 /* If there are no more rows to try, or just one, give up. */
12702 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12703 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
12704 || CHARPOS (start) == ZV)
12705 {
12706 clear_glyph_matrix (w->desired_matrix);
12707 return 0;
12708 }
12709
12710 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12711 }
12712 /* If we have reached alignment,
12713 we can copy the rest of the rows. */
12714 if (IT_CHARPOS (it) == CHARPOS (start))
12715 break;
12716
12717 if (display_line (&it))
12718 last_text_row = it.glyph_row - 1;
12719 }
12720
12721 /* A value of current_y < last_visible_y means that we stopped
12722 at the previous window start, which in turn means that we
12723 have at least one reusable row. */
12724 if (it.current_y < it.last_visible_y)
12725 {
12726 /* IT.vpos always starts from 0; it counts text lines. */
12727 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12728
12729 /* Find PT if not already found in the lines displayed. */
12730 if (w->cursor.vpos < 0)
12731 {
12732 int dy = it.current_y - start_row->y;
12733
12734 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12735 row = row_containing_pos (w, PT, row, NULL, dy);
12736 if (row)
12737 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12738 dy, nrows_scrolled);
12739 else
12740 {
12741 clear_glyph_matrix (w->desired_matrix);
12742 return 0;
12743 }
12744 }
12745
12746 /* Scroll the display. Do it before the current matrix is
12747 changed. The problem here is that update has not yet
12748 run, i.e. part of the current matrix is not up to date.
12749 scroll_run_hook will clear the cursor, and use the
12750 current matrix to get the height of the row the cursor is
12751 in. */
12752 run.current_y = start_row->y;
12753 run.desired_y = it.current_y;
12754 run.height = it.last_visible_y - it.current_y;
12755
12756 if (run.height > 0 && run.current_y != run.desired_y)
12757 {
12758 update_begin (f);
12759 rif->update_window_begin_hook (w);
12760 rif->clear_window_mouse_face (w);
12761 rif->scroll_run_hook (w, &run);
12762 rif->update_window_end_hook (w, 0, 0);
12763 update_end (f);
12764 }
12765
12766 /* Shift current matrix down by nrows_scrolled lines. */
12767 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12768 rotate_matrix (w->current_matrix,
12769 start_vpos,
12770 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12771 nrows_scrolled);
12772
12773 /* Disable lines that must be updated. */
12774 for (i = 0; i < it.vpos; ++i)
12775 (start_row + i)->enabled_p = 0;
12776
12777 /* Re-compute Y positions. */
12778 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12779 max_y = it.last_visible_y;
12780 for (row = start_row + nrows_scrolled;
12781 row < bottom_row;
12782 ++row)
12783 {
12784 row->y = it.current_y;
12785 row->visible_height = row->height;
12786
12787 if (row->y < min_y)
12788 row->visible_height -= min_y - row->y;
12789 if (row->y + row->height > max_y)
12790 row->visible_height -= row->y + row->height - max_y;
12791 row->redraw_fringe_bitmaps_p = 1;
12792
12793 it.current_y += row->height;
12794
12795 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12796 last_reused_text_row = row;
12797 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12798 break;
12799 }
12800
12801 /* Disable lines in the current matrix which are now
12802 below the window. */
12803 for (++row; row < bottom_row; ++row)
12804 row->enabled_p = 0;
12805 }
12806
12807 /* Update window_end_pos etc.; last_reused_text_row is the last
12808 reused row from the current matrix containing text, if any.
12809 The value of last_text_row is the last displayed line
12810 containing text. */
12811 if (last_reused_text_row)
12812 {
12813 w->window_end_bytepos
12814 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12815 w->window_end_pos
12816 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12817 w->window_end_vpos
12818 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12819 w->current_matrix));
12820 }
12821 else if (last_text_row)
12822 {
12823 w->window_end_bytepos
12824 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12825 w->window_end_pos
12826 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12827 w->window_end_vpos
12828 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12829 }
12830 else
12831 {
12832 /* This window must be completely empty. */
12833 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12834 w->window_end_pos = make_number (Z - ZV);
12835 w->window_end_vpos = make_number (0);
12836 }
12837 w->window_end_valid = Qnil;
12838
12839 /* Update hint: don't try scrolling again in update_window. */
12840 w->desired_matrix->no_scrolling_p = 1;
12841
12842 #if GLYPH_DEBUG
12843 debug_method_add (w, "try_window_reusing_current_matrix 1");
12844 #endif
12845 return 1;
12846 }
12847 else if (CHARPOS (new_start) > CHARPOS (start))
12848 {
12849 struct glyph_row *pt_row, *row;
12850 struct glyph_row *first_reusable_row;
12851 struct glyph_row *first_row_to_display;
12852 int dy;
12853 int yb = window_text_bottom_y (w);
12854
12855 /* Find the row starting at new_start, if there is one. Don't
12856 reuse a partially visible line at the end. */
12857 first_reusable_row = start_row;
12858 while (first_reusable_row->enabled_p
12859 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12860 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12861 < CHARPOS (new_start)))
12862 ++first_reusable_row;
12863
12864 /* Give up if there is no row to reuse. */
12865 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12866 || !first_reusable_row->enabled_p
12867 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12868 != CHARPOS (new_start)))
12869 return 0;
12870
12871 /* We can reuse fully visible rows beginning with
12872 first_reusable_row to the end of the window. Set
12873 first_row_to_display to the first row that cannot be reused.
12874 Set pt_row to the row containing point, if there is any. */
12875 pt_row = NULL;
12876 for (first_row_to_display = first_reusable_row;
12877 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12878 ++first_row_to_display)
12879 {
12880 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12881 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12882 pt_row = first_row_to_display;
12883 }
12884
12885 /* Start displaying at the start of first_row_to_display. */
12886 xassert (first_row_to_display->y < yb);
12887 init_to_row_start (&it, w, first_row_to_display);
12888
12889 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12890 - start_vpos);
12891 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12892 - nrows_scrolled);
12893 it.current_y = (first_row_to_display->y - first_reusable_row->y
12894 + WINDOW_HEADER_LINE_HEIGHT (w));
12895
12896 /* Display lines beginning with first_row_to_display in the
12897 desired matrix. Set last_text_row to the last row displayed
12898 that displays text. */
12899 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12900 if (pt_row == NULL)
12901 w->cursor.vpos = -1;
12902 last_text_row = NULL;
12903 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12904 if (display_line (&it))
12905 last_text_row = it.glyph_row - 1;
12906
12907 /* Give up If point isn't in a row displayed or reused. */
12908 if (w->cursor.vpos < 0)
12909 {
12910 clear_glyph_matrix (w->desired_matrix);
12911 return 0;
12912 }
12913
12914 /* If point is in a reused row, adjust y and vpos of the cursor
12915 position. */
12916 if (pt_row)
12917 {
12918 w->cursor.vpos -= nrows_scrolled;
12919 w->cursor.y -= first_reusable_row->y - start_row->y;
12920 }
12921
12922 /* Scroll the display. */
12923 run.current_y = first_reusable_row->y;
12924 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12925 run.height = it.last_visible_y - run.current_y;
12926 dy = run.current_y - run.desired_y;
12927
12928 if (run.height)
12929 {
12930 update_begin (f);
12931 rif->update_window_begin_hook (w);
12932 rif->clear_window_mouse_face (w);
12933 rif->scroll_run_hook (w, &run);
12934 rif->update_window_end_hook (w, 0, 0);
12935 update_end (f);
12936 }
12937
12938 /* Adjust Y positions of reused rows. */
12939 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12940 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12941 max_y = it.last_visible_y;
12942 for (row = first_reusable_row; row < first_row_to_display; ++row)
12943 {
12944 row->y -= dy;
12945 row->visible_height = row->height;
12946 if (row->y < min_y)
12947 row->visible_height -= min_y - row->y;
12948 if (row->y + row->height > max_y)
12949 row->visible_height -= row->y + row->height - max_y;
12950 row->redraw_fringe_bitmaps_p = 1;
12951 }
12952
12953 /* Scroll the current matrix. */
12954 xassert (nrows_scrolled > 0);
12955 rotate_matrix (w->current_matrix,
12956 start_vpos,
12957 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12958 -nrows_scrolled);
12959
12960 /* Disable rows not reused. */
12961 for (row -= nrows_scrolled; row < bottom_row; ++row)
12962 row->enabled_p = 0;
12963
12964 /* Point may have moved to a different line, so we cannot assume that
12965 the previous cursor position is valid; locate the correct row. */
12966 if (pt_row)
12967 {
12968 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12969 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12970 row++)
12971 {
12972 w->cursor.vpos++;
12973 w->cursor.y = row->y;
12974 }
12975 if (row < bottom_row)
12976 {
12977 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12978 while (glyph->charpos < PT)
12979 {
12980 w->cursor.hpos++;
12981 w->cursor.x += glyph->pixel_width;
12982 glyph++;
12983 }
12984 }
12985 }
12986
12987 /* Adjust window end. A null value of last_text_row means that
12988 the window end is in reused rows which in turn means that
12989 only its vpos can have changed. */
12990 if (last_text_row)
12991 {
12992 w->window_end_bytepos
12993 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12994 w->window_end_pos
12995 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12996 w->window_end_vpos
12997 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12998 }
12999 else
13000 {
13001 w->window_end_vpos
13002 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
13003 }
13004
13005 w->window_end_valid = Qnil;
13006 w->desired_matrix->no_scrolling_p = 1;
13007
13008 #if GLYPH_DEBUG
13009 debug_method_add (w, "try_window_reusing_current_matrix 2");
13010 #endif
13011 return 1;
13012 }
13013
13014 return 0;
13015 }
13016
13017
13018 \f
13019 /************************************************************************
13020 Window redisplay reusing current matrix when buffer has changed
13021 ************************************************************************/
13022
13023 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
13024 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
13025 int *, int *));
13026 static struct glyph_row *
13027 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
13028 struct glyph_row *));
13029
13030
13031 /* Return the last row in MATRIX displaying text. If row START is
13032 non-null, start searching with that row. IT gives the dimensions
13033 of the display. Value is null if matrix is empty; otherwise it is
13034 a pointer to the row found. */
13035
13036 static struct glyph_row *
13037 find_last_row_displaying_text (matrix, it, start)
13038 struct glyph_matrix *matrix;
13039 struct it *it;
13040 struct glyph_row *start;
13041 {
13042 struct glyph_row *row, *row_found;
13043
13044 /* Set row_found to the last row in IT->w's current matrix
13045 displaying text. The loop looks funny but think of partially
13046 visible lines. */
13047 row_found = NULL;
13048 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
13049 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13050 {
13051 xassert (row->enabled_p);
13052 row_found = row;
13053 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
13054 break;
13055 ++row;
13056 }
13057
13058 return row_found;
13059 }
13060
13061
13062 /* Return the last row in the current matrix of W that is not affected
13063 by changes at the start of current_buffer that occurred since W's
13064 current matrix was built. Value is null if no such row exists.
13065
13066 BEG_UNCHANGED us the number of characters unchanged at the start of
13067 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
13068 first changed character in current_buffer. Characters at positions <
13069 BEG + BEG_UNCHANGED are at the same buffer positions as they were
13070 when the current matrix was built. */
13071
13072 static struct glyph_row *
13073 find_last_unchanged_at_beg_row (w)
13074 struct window *w;
13075 {
13076 int first_changed_pos = BEG + BEG_UNCHANGED;
13077 struct glyph_row *row;
13078 struct glyph_row *row_found = NULL;
13079 int yb = window_text_bottom_y (w);
13080
13081 /* Find the last row displaying unchanged text. */
13082 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13083 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13084 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
13085 {
13086 if (/* If row ends before first_changed_pos, it is unchanged,
13087 except in some case. */
13088 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
13089 /* When row ends in ZV and we write at ZV it is not
13090 unchanged. */
13091 && !row->ends_at_zv_p
13092 /* When first_changed_pos is the end of a continued line,
13093 row is not unchanged because it may be no longer
13094 continued. */
13095 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
13096 && (row->continued_p
13097 || row->exact_window_width_line_p)))
13098 row_found = row;
13099
13100 /* Stop if last visible row. */
13101 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
13102 break;
13103
13104 ++row;
13105 }
13106
13107 return row_found;
13108 }
13109
13110
13111 /* Find the first glyph row in the current matrix of W that is not
13112 affected by changes at the end of current_buffer since the
13113 time W's current matrix was built.
13114
13115 Return in *DELTA the number of chars by which buffer positions in
13116 unchanged text at the end of current_buffer must be adjusted.
13117
13118 Return in *DELTA_BYTES the corresponding number of bytes.
13119
13120 Value is null if no such row exists, i.e. all rows are affected by
13121 changes. */
13122
13123 static struct glyph_row *
13124 find_first_unchanged_at_end_row (w, delta, delta_bytes)
13125 struct window *w;
13126 int *delta, *delta_bytes;
13127 {
13128 struct glyph_row *row;
13129 struct glyph_row *row_found = NULL;
13130
13131 *delta = *delta_bytes = 0;
13132
13133 /* Display must not have been paused, otherwise the current matrix
13134 is not up to date. */
13135 if (NILP (w->window_end_valid))
13136 abort ();
13137
13138 /* A value of window_end_pos >= END_UNCHANGED means that the window
13139 end is in the range of changed text. If so, there is no
13140 unchanged row at the end of W's current matrix. */
13141 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
13142 return NULL;
13143
13144 /* Set row to the last row in W's current matrix displaying text. */
13145 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13146
13147 /* If matrix is entirely empty, no unchanged row exists. */
13148 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13149 {
13150 /* The value of row is the last glyph row in the matrix having a
13151 meaningful buffer position in it. The end position of row
13152 corresponds to window_end_pos. This allows us to translate
13153 buffer positions in the current matrix to current buffer
13154 positions for characters not in changed text. */
13155 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13156 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13157 int last_unchanged_pos, last_unchanged_pos_old;
13158 struct glyph_row *first_text_row
13159 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13160
13161 *delta = Z - Z_old;
13162 *delta_bytes = Z_BYTE - Z_BYTE_old;
13163
13164 /* Set last_unchanged_pos to the buffer position of the last
13165 character in the buffer that has not been changed. Z is the
13166 index + 1 of the last character in current_buffer, i.e. by
13167 subtracting END_UNCHANGED we get the index of the last
13168 unchanged character, and we have to add BEG to get its buffer
13169 position. */
13170 last_unchanged_pos = Z - END_UNCHANGED + BEG;
13171 last_unchanged_pos_old = last_unchanged_pos - *delta;
13172
13173 /* Search backward from ROW for a row displaying a line that
13174 starts at a minimum position >= last_unchanged_pos_old. */
13175 for (; row > first_text_row; --row)
13176 {
13177 /* This used to abort, but it can happen.
13178 It is ok to just stop the search instead here. KFS. */
13179 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13180 break;
13181
13182 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13183 row_found = row;
13184 }
13185 }
13186
13187 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
13188 abort ();
13189
13190 return row_found;
13191 }
13192
13193
13194 /* Make sure that glyph rows in the current matrix of window W
13195 reference the same glyph memory as corresponding rows in the
13196 frame's frame matrix. This function is called after scrolling W's
13197 current matrix on a terminal frame in try_window_id and
13198 try_window_reusing_current_matrix. */
13199
13200 static void
13201 sync_frame_with_window_matrix_rows (w)
13202 struct window *w;
13203 {
13204 struct frame *f = XFRAME (w->frame);
13205 struct glyph_row *window_row, *window_row_end, *frame_row;
13206
13207 /* Preconditions: W must be a leaf window and full-width. Its frame
13208 must have a frame matrix. */
13209 xassert (NILP (w->hchild) && NILP (w->vchild));
13210 xassert (WINDOW_FULL_WIDTH_P (w));
13211 xassert (!FRAME_WINDOW_P (f));
13212
13213 /* If W is a full-width window, glyph pointers in W's current matrix
13214 have, by definition, to be the same as glyph pointers in the
13215 corresponding frame matrix. Note that frame matrices have no
13216 marginal areas (see build_frame_matrix). */
13217 window_row = w->current_matrix->rows;
13218 window_row_end = window_row + w->current_matrix->nrows;
13219 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
13220 while (window_row < window_row_end)
13221 {
13222 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
13223 struct glyph *end = window_row->glyphs[LAST_AREA];
13224
13225 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
13226 frame_row->glyphs[TEXT_AREA] = start;
13227 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
13228 frame_row->glyphs[LAST_AREA] = end;
13229
13230 /* Disable frame rows whose corresponding window rows have
13231 been disabled in try_window_id. */
13232 if (!window_row->enabled_p)
13233 frame_row->enabled_p = 0;
13234
13235 ++window_row, ++frame_row;
13236 }
13237 }
13238
13239
13240 /* Find the glyph row in window W containing CHARPOS. Consider all
13241 rows between START and END (not inclusive). END null means search
13242 all rows to the end of the display area of W. Value is the row
13243 containing CHARPOS or null. */
13244
13245 struct glyph_row *
13246 row_containing_pos (w, charpos, start, end, dy)
13247 struct window *w;
13248 int charpos;
13249 struct glyph_row *start, *end;
13250 int dy;
13251 {
13252 struct glyph_row *row = start;
13253 int last_y;
13254
13255 /* If we happen to start on a header-line, skip that. */
13256 if (row->mode_line_p)
13257 ++row;
13258
13259 if ((end && row >= end) || !row->enabled_p)
13260 return NULL;
13261
13262 last_y = window_text_bottom_y (w) - dy;
13263
13264 while (1)
13265 {
13266 /* Give up if we have gone too far. */
13267 if (end && row >= end)
13268 return NULL;
13269 /* This formerly returned if they were equal.
13270 I think that both quantities are of a "last plus one" type;
13271 if so, when they are equal, the row is within the screen. -- rms. */
13272 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13273 return NULL;
13274
13275 /* If it is in this row, return this row. */
13276 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13277 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13278 /* The end position of a row equals the start
13279 position of the next row. If CHARPOS is there, we
13280 would rather display it in the next line, except
13281 when this line ends in ZV. */
13282 && !row->ends_at_zv_p
13283 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13284 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13285 return row;
13286 ++row;
13287 }
13288 }
13289
13290
13291 /* Try to redisplay window W by reusing its existing display. W's
13292 current matrix must be up to date when this function is called,
13293 i.e. window_end_valid must not be nil.
13294
13295 Value is
13296
13297 1 if display has been updated
13298 0 if otherwise unsuccessful
13299 -1 if redisplay with same window start is known not to succeed
13300
13301 The following steps are performed:
13302
13303 1. Find the last row in the current matrix of W that is not
13304 affected by changes at the start of current_buffer. If no such row
13305 is found, give up.
13306
13307 2. Find the first row in W's current matrix that is not affected by
13308 changes at the end of current_buffer. Maybe there is no such row.
13309
13310 3. Display lines beginning with the row + 1 found in step 1 to the
13311 row found in step 2 or, if step 2 didn't find a row, to the end of
13312 the window.
13313
13314 4. If cursor is not known to appear on the window, give up.
13315
13316 5. If display stopped at the row found in step 2, scroll the
13317 display and current matrix as needed.
13318
13319 6. Maybe display some lines at the end of W, if we must. This can
13320 happen under various circumstances, like a partially visible line
13321 becoming fully visible, or because newly displayed lines are displayed
13322 in smaller font sizes.
13323
13324 7. Update W's window end information. */
13325
13326 static int
13327 try_window_id (w)
13328 struct window *w;
13329 {
13330 struct frame *f = XFRAME (w->frame);
13331 struct glyph_matrix *current_matrix = w->current_matrix;
13332 struct glyph_matrix *desired_matrix = w->desired_matrix;
13333 struct glyph_row *last_unchanged_at_beg_row;
13334 struct glyph_row *first_unchanged_at_end_row;
13335 struct glyph_row *row;
13336 struct glyph_row *bottom_row;
13337 int bottom_vpos;
13338 struct it it;
13339 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13340 struct text_pos start_pos;
13341 struct run run;
13342 int first_unchanged_at_end_vpos = 0;
13343 struct glyph_row *last_text_row, *last_text_row_at_end;
13344 struct text_pos start;
13345 int first_changed_charpos, last_changed_charpos;
13346
13347 #if GLYPH_DEBUG
13348 if (inhibit_try_window_id)
13349 return 0;
13350 #endif
13351
13352 /* This is handy for debugging. */
13353 #if 0
13354 #define GIVE_UP(X) \
13355 do { \
13356 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13357 return 0; \
13358 } while (0)
13359 #else
13360 #define GIVE_UP(X) return 0
13361 #endif
13362
13363 SET_TEXT_POS_FROM_MARKER (start, w->start);
13364
13365 /* Don't use this for mini-windows because these can show
13366 messages and mini-buffers, and we don't handle that here. */
13367 if (MINI_WINDOW_P (w))
13368 GIVE_UP (1);
13369
13370 /* This flag is used to prevent redisplay optimizations. */
13371 if (windows_or_buffers_changed || cursor_type_changed)
13372 GIVE_UP (2);
13373
13374 /* Verify that narrowing has not changed.
13375 Also verify that we were not told to prevent redisplay optimizations.
13376 It would be nice to further
13377 reduce the number of cases where this prevents try_window_id. */
13378 if (current_buffer->clip_changed
13379 || current_buffer->prevent_redisplay_optimizations_p)
13380 GIVE_UP (3);
13381
13382 /* Window must either use window-based redisplay or be full width. */
13383 if (!FRAME_WINDOW_P (f)
13384 && (!line_ins_del_ok
13385 || !WINDOW_FULL_WIDTH_P (w)))
13386 GIVE_UP (4);
13387
13388 /* Give up if point is not known NOT to appear in W. */
13389 if (PT < CHARPOS (start))
13390 GIVE_UP (5);
13391
13392 /* Another way to prevent redisplay optimizations. */
13393 if (XFASTINT (w->last_modified) == 0)
13394 GIVE_UP (6);
13395
13396 /* Verify that window is not hscrolled. */
13397 if (XFASTINT (w->hscroll) != 0)
13398 GIVE_UP (7);
13399
13400 /* Verify that display wasn't paused. */
13401 if (NILP (w->window_end_valid))
13402 GIVE_UP (8);
13403
13404 /* Can't use this if highlighting a region because a cursor movement
13405 will do more than just set the cursor. */
13406 if (!NILP (Vtransient_mark_mode)
13407 && !NILP (current_buffer->mark_active))
13408 GIVE_UP (9);
13409
13410 /* Likewise if highlighting trailing whitespace. */
13411 if (!NILP (Vshow_trailing_whitespace))
13412 GIVE_UP (11);
13413
13414 /* Likewise if showing a region. */
13415 if (!NILP (w->region_showing))
13416 GIVE_UP (10);
13417
13418 /* Can use this if overlay arrow position and or string have changed. */
13419 if (overlay_arrows_changed_p ())
13420 GIVE_UP (12);
13421
13422
13423 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13424 only if buffer has really changed. The reason is that the gap is
13425 initially at Z for freshly visited files. The code below would
13426 set end_unchanged to 0 in that case. */
13427 if (MODIFF > SAVE_MODIFF
13428 /* This seems to happen sometimes after saving a buffer. */
13429 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13430 {
13431 if (GPT - BEG < BEG_UNCHANGED)
13432 BEG_UNCHANGED = GPT - BEG;
13433 if (Z - GPT < END_UNCHANGED)
13434 END_UNCHANGED = Z - GPT;
13435 }
13436
13437 /* The position of the first and last character that has been changed. */
13438 first_changed_charpos = BEG + BEG_UNCHANGED;
13439 last_changed_charpos = Z - END_UNCHANGED;
13440
13441 /* If window starts after a line end, and the last change is in
13442 front of that newline, then changes don't affect the display.
13443 This case happens with stealth-fontification. Note that although
13444 the display is unchanged, glyph positions in the matrix have to
13445 be adjusted, of course. */
13446 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13447 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13448 && ((last_changed_charpos < CHARPOS (start)
13449 && CHARPOS (start) == BEGV)
13450 || (last_changed_charpos < CHARPOS (start) - 1
13451 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13452 {
13453 int Z_old, delta, Z_BYTE_old, delta_bytes;
13454 struct glyph_row *r0;
13455
13456 /* Compute how many chars/bytes have been added to or removed
13457 from the buffer. */
13458 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13459 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13460 delta = Z - Z_old;
13461 delta_bytes = Z_BYTE - Z_BYTE_old;
13462
13463 /* Give up if PT is not in the window. Note that it already has
13464 been checked at the start of try_window_id that PT is not in
13465 front of the window start. */
13466 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13467 GIVE_UP (13);
13468
13469 /* If window start is unchanged, we can reuse the whole matrix
13470 as is, after adjusting glyph positions. No need to compute
13471 the window end again, since its offset from Z hasn't changed. */
13472 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13473 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13474 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13475 /* PT must not be in a partially visible line. */
13476 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13477 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13478 {
13479 /* Adjust positions in the glyph matrix. */
13480 if (delta || delta_bytes)
13481 {
13482 struct glyph_row *r1
13483 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13484 increment_matrix_positions (w->current_matrix,
13485 MATRIX_ROW_VPOS (r0, current_matrix),
13486 MATRIX_ROW_VPOS (r1, current_matrix),
13487 delta, delta_bytes);
13488 }
13489
13490 /* Set the cursor. */
13491 row = row_containing_pos (w, PT, r0, NULL, 0);
13492 if (row)
13493 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13494 else
13495 abort ();
13496 return 1;
13497 }
13498 }
13499
13500 /* Handle the case that changes are all below what is displayed in
13501 the window, and that PT is in the window. This shortcut cannot
13502 be taken if ZV is visible in the window, and text has been added
13503 there that is visible in the window. */
13504 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13505 /* ZV is not visible in the window, or there are no
13506 changes at ZV, actually. */
13507 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13508 || first_changed_charpos == last_changed_charpos))
13509 {
13510 struct glyph_row *r0;
13511
13512 /* Give up if PT is not in the window. Note that it already has
13513 been checked at the start of try_window_id that PT is not in
13514 front of the window start. */
13515 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13516 GIVE_UP (14);
13517
13518 /* If window start is unchanged, we can reuse the whole matrix
13519 as is, without changing glyph positions since no text has
13520 been added/removed in front of the window end. */
13521 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13522 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13523 /* PT must not be in a partially visible line. */
13524 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13525 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13526 {
13527 /* We have to compute the window end anew since text
13528 can have been added/removed after it. */
13529 w->window_end_pos
13530 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13531 w->window_end_bytepos
13532 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13533
13534 /* Set the cursor. */
13535 row = row_containing_pos (w, PT, r0, NULL, 0);
13536 if (row)
13537 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13538 else
13539 abort ();
13540 return 2;
13541 }
13542 }
13543
13544 /* Give up if window start is in the changed area.
13545
13546 The condition used to read
13547
13548 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13549
13550 but why that was tested escapes me at the moment. */
13551 if (CHARPOS (start) >= first_changed_charpos
13552 && CHARPOS (start) <= last_changed_charpos)
13553 GIVE_UP (15);
13554
13555 /* Check that window start agrees with the start of the first glyph
13556 row in its current matrix. Check this after we know the window
13557 start is not in changed text, otherwise positions would not be
13558 comparable. */
13559 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13560 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13561 GIVE_UP (16);
13562
13563 /* Give up if the window ends in strings. Overlay strings
13564 at the end are difficult to handle, so don't try. */
13565 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13566 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13567 GIVE_UP (20);
13568
13569 /* Compute the position at which we have to start displaying new
13570 lines. Some of the lines at the top of the window might be
13571 reusable because they are not displaying changed text. Find the
13572 last row in W's current matrix not affected by changes at the
13573 start of current_buffer. Value is null if changes start in the
13574 first line of window. */
13575 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13576 if (last_unchanged_at_beg_row)
13577 {
13578 /* Avoid starting to display in the moddle of a character, a TAB
13579 for instance. This is easier than to set up the iterator
13580 exactly, and it's not a frequent case, so the additional
13581 effort wouldn't really pay off. */
13582 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13583 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13584 && last_unchanged_at_beg_row > w->current_matrix->rows)
13585 --last_unchanged_at_beg_row;
13586
13587 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13588 GIVE_UP (17);
13589
13590 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13591 GIVE_UP (18);
13592 start_pos = it.current.pos;
13593
13594 /* Start displaying new lines in the desired matrix at the same
13595 vpos we would use in the current matrix, i.e. below
13596 last_unchanged_at_beg_row. */
13597 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13598 current_matrix);
13599 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13600 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13601
13602 xassert (it.hpos == 0 && it.current_x == 0);
13603 }
13604 else
13605 {
13606 /* There are no reusable lines at the start of the window.
13607 Start displaying in the first text line. */
13608 start_display (&it, w, start);
13609 it.vpos = it.first_vpos;
13610 start_pos = it.current.pos;
13611 }
13612
13613 /* Find the first row that is not affected by changes at the end of
13614 the buffer. Value will be null if there is no unchanged row, in
13615 which case we must redisplay to the end of the window. delta
13616 will be set to the value by which buffer positions beginning with
13617 first_unchanged_at_end_row have to be adjusted due to text
13618 changes. */
13619 first_unchanged_at_end_row
13620 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13621 IF_DEBUG (debug_delta = delta);
13622 IF_DEBUG (debug_delta_bytes = delta_bytes);
13623
13624 /* Set stop_pos to the buffer position up to which we will have to
13625 display new lines. If first_unchanged_at_end_row != NULL, this
13626 is the buffer position of the start of the line displayed in that
13627 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13628 that we don't stop at a buffer position. */
13629 stop_pos = 0;
13630 if (first_unchanged_at_end_row)
13631 {
13632 xassert (last_unchanged_at_beg_row == NULL
13633 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13634
13635 /* If this is a continuation line, move forward to the next one
13636 that isn't. Changes in lines above affect this line.
13637 Caution: this may move first_unchanged_at_end_row to a row
13638 not displaying text. */
13639 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13640 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13641 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13642 < it.last_visible_y))
13643 ++first_unchanged_at_end_row;
13644
13645 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13646 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13647 >= it.last_visible_y))
13648 first_unchanged_at_end_row = NULL;
13649 else
13650 {
13651 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13652 + delta);
13653 first_unchanged_at_end_vpos
13654 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13655 xassert (stop_pos >= Z - END_UNCHANGED);
13656 }
13657 }
13658 else if (last_unchanged_at_beg_row == NULL)
13659 GIVE_UP (19);
13660
13661
13662 #if GLYPH_DEBUG
13663
13664 /* Either there is no unchanged row at the end, or the one we have
13665 now displays text. This is a necessary condition for the window
13666 end pos calculation at the end of this function. */
13667 xassert (first_unchanged_at_end_row == NULL
13668 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13669
13670 debug_last_unchanged_at_beg_vpos
13671 = (last_unchanged_at_beg_row
13672 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13673 : -1);
13674 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13675
13676 #endif /* GLYPH_DEBUG != 0 */
13677
13678
13679 /* Display new lines. Set last_text_row to the last new line
13680 displayed which has text on it, i.e. might end up as being the
13681 line where the window_end_vpos is. */
13682 w->cursor.vpos = -1;
13683 last_text_row = NULL;
13684 overlay_arrow_seen = 0;
13685 while (it.current_y < it.last_visible_y
13686 && !fonts_changed_p
13687 && (first_unchanged_at_end_row == NULL
13688 || IT_CHARPOS (it) < stop_pos))
13689 {
13690 if (display_line (&it))
13691 last_text_row = it.glyph_row - 1;
13692 }
13693
13694 if (fonts_changed_p)
13695 return -1;
13696
13697
13698 /* Compute differences in buffer positions, y-positions etc. for
13699 lines reused at the bottom of the window. Compute what we can
13700 scroll. */
13701 if (first_unchanged_at_end_row
13702 /* No lines reused because we displayed everything up to the
13703 bottom of the window. */
13704 && it.current_y < it.last_visible_y)
13705 {
13706 dvpos = (it.vpos
13707 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13708 current_matrix));
13709 dy = it.current_y - first_unchanged_at_end_row->y;
13710 run.current_y = first_unchanged_at_end_row->y;
13711 run.desired_y = run.current_y + dy;
13712 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13713 }
13714 else
13715 {
13716 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13717 first_unchanged_at_end_row = NULL;
13718 }
13719 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13720
13721
13722 /* Find the cursor if not already found. We have to decide whether
13723 PT will appear on this window (it sometimes doesn't, but this is
13724 not a very frequent case.) This decision has to be made before
13725 the current matrix is altered. A value of cursor.vpos < 0 means
13726 that PT is either in one of the lines beginning at
13727 first_unchanged_at_end_row or below the window. Don't care for
13728 lines that might be displayed later at the window end; as
13729 mentioned, this is not a frequent case. */
13730 if (w->cursor.vpos < 0)
13731 {
13732 /* Cursor in unchanged rows at the top? */
13733 if (PT < CHARPOS (start_pos)
13734 && last_unchanged_at_beg_row)
13735 {
13736 row = row_containing_pos (w, PT,
13737 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13738 last_unchanged_at_beg_row + 1, 0);
13739 if (row)
13740 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13741 }
13742
13743 /* Start from first_unchanged_at_end_row looking for PT. */
13744 else if (first_unchanged_at_end_row)
13745 {
13746 row = row_containing_pos (w, PT - delta,
13747 first_unchanged_at_end_row, NULL, 0);
13748 if (row)
13749 set_cursor_from_row (w, row, w->current_matrix, delta,
13750 delta_bytes, dy, dvpos);
13751 }
13752
13753 /* Give up if cursor was not found. */
13754 if (w->cursor.vpos < 0)
13755 {
13756 clear_glyph_matrix (w->desired_matrix);
13757 return -1;
13758 }
13759 }
13760
13761 /* Don't let the cursor end in the scroll margins. */
13762 {
13763 int this_scroll_margin, cursor_height;
13764
13765 this_scroll_margin = max (0, scroll_margin);
13766 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13767 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13768 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13769
13770 if ((w->cursor.y < this_scroll_margin
13771 && CHARPOS (start) > BEGV)
13772 /* Old redisplay didn't take scroll margin into account at the bottom,
13773 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13774 || (w->cursor.y + (make_cursor_line_fully_visible_p
13775 ? cursor_height + this_scroll_margin
13776 : 1)) > it.last_visible_y)
13777 {
13778 w->cursor.vpos = -1;
13779 clear_glyph_matrix (w->desired_matrix);
13780 return -1;
13781 }
13782 }
13783
13784 /* Scroll the display. Do it before changing the current matrix so
13785 that xterm.c doesn't get confused about where the cursor glyph is
13786 found. */
13787 if (dy && run.height)
13788 {
13789 update_begin (f);
13790
13791 if (FRAME_WINDOW_P (f))
13792 {
13793 rif->update_window_begin_hook (w);
13794 rif->clear_window_mouse_face (w);
13795 rif->scroll_run_hook (w, &run);
13796 rif->update_window_end_hook (w, 0, 0);
13797 }
13798 else
13799 {
13800 /* Terminal frame. In this case, dvpos gives the number of
13801 lines to scroll by; dvpos < 0 means scroll up. */
13802 int first_unchanged_at_end_vpos
13803 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13804 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13805 int end = (WINDOW_TOP_EDGE_LINE (w)
13806 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13807 + window_internal_height (w));
13808
13809 /* Perform the operation on the screen. */
13810 if (dvpos > 0)
13811 {
13812 /* Scroll last_unchanged_at_beg_row to the end of the
13813 window down dvpos lines. */
13814 set_terminal_window (end);
13815
13816 /* On dumb terminals delete dvpos lines at the end
13817 before inserting dvpos empty lines. */
13818 if (!scroll_region_ok)
13819 ins_del_lines (end - dvpos, -dvpos);
13820
13821 /* Insert dvpos empty lines in front of
13822 last_unchanged_at_beg_row. */
13823 ins_del_lines (from, dvpos);
13824 }
13825 else if (dvpos < 0)
13826 {
13827 /* Scroll up last_unchanged_at_beg_vpos to the end of
13828 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13829 set_terminal_window (end);
13830
13831 /* Delete dvpos lines in front of
13832 last_unchanged_at_beg_vpos. ins_del_lines will set
13833 the cursor to the given vpos and emit |dvpos| delete
13834 line sequences. */
13835 ins_del_lines (from + dvpos, dvpos);
13836
13837 /* On a dumb terminal insert dvpos empty lines at the
13838 end. */
13839 if (!scroll_region_ok)
13840 ins_del_lines (end + dvpos, -dvpos);
13841 }
13842
13843 set_terminal_window (0);
13844 }
13845
13846 update_end (f);
13847 }
13848
13849 /* Shift reused rows of the current matrix to the right position.
13850 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13851 text. */
13852 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13853 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13854 if (dvpos < 0)
13855 {
13856 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13857 bottom_vpos, dvpos);
13858 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13859 bottom_vpos, 0);
13860 }
13861 else if (dvpos > 0)
13862 {
13863 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13864 bottom_vpos, dvpos);
13865 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13866 first_unchanged_at_end_vpos + dvpos, 0);
13867 }
13868
13869 /* For frame-based redisplay, make sure that current frame and window
13870 matrix are in sync with respect to glyph memory. */
13871 if (!FRAME_WINDOW_P (f))
13872 sync_frame_with_window_matrix_rows (w);
13873
13874 /* Adjust buffer positions in reused rows. */
13875 if (delta)
13876 increment_matrix_positions (current_matrix,
13877 first_unchanged_at_end_vpos + dvpos,
13878 bottom_vpos, delta, delta_bytes);
13879
13880 /* Adjust Y positions. */
13881 if (dy)
13882 shift_glyph_matrix (w, current_matrix,
13883 first_unchanged_at_end_vpos + dvpos,
13884 bottom_vpos, dy);
13885
13886 if (first_unchanged_at_end_row)
13887 {
13888 first_unchanged_at_end_row += dvpos;
13889 if (first_unchanged_at_end_row->y >= it.last_visible_y
13890 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
13891 first_unchanged_at_end_row = NULL;
13892 }
13893
13894 /* If scrolling up, there may be some lines to display at the end of
13895 the window. */
13896 last_text_row_at_end = NULL;
13897 if (dy < 0)
13898 {
13899 /* Scrolling up can leave for example a partially visible line
13900 at the end of the window to be redisplayed. */
13901 /* Set last_row to the glyph row in the current matrix where the
13902 window end line is found. It has been moved up or down in
13903 the matrix by dvpos. */
13904 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13905 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13906
13907 /* If last_row is the window end line, it should display text. */
13908 xassert (last_row->displays_text_p);
13909
13910 /* If window end line was partially visible before, begin
13911 displaying at that line. Otherwise begin displaying with the
13912 line following it. */
13913 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13914 {
13915 init_to_row_start (&it, w, last_row);
13916 it.vpos = last_vpos;
13917 it.current_y = last_row->y;
13918 }
13919 else
13920 {
13921 init_to_row_end (&it, w, last_row);
13922 it.vpos = 1 + last_vpos;
13923 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13924 ++last_row;
13925 }
13926
13927 /* We may start in a continuation line. If so, we have to
13928 get the right continuation_lines_width and current_x. */
13929 it.continuation_lines_width = last_row->continuation_lines_width;
13930 it.hpos = it.current_x = 0;
13931
13932 /* Display the rest of the lines at the window end. */
13933 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13934 while (it.current_y < it.last_visible_y
13935 && !fonts_changed_p)
13936 {
13937 /* Is it always sure that the display agrees with lines in
13938 the current matrix? I don't think so, so we mark rows
13939 displayed invalid in the current matrix by setting their
13940 enabled_p flag to zero. */
13941 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13942 if (display_line (&it))
13943 last_text_row_at_end = it.glyph_row - 1;
13944 }
13945 }
13946
13947 /* Update window_end_pos and window_end_vpos. */
13948 if (first_unchanged_at_end_row
13949 && !last_text_row_at_end)
13950 {
13951 /* Window end line if one of the preserved rows from the current
13952 matrix. Set row to the last row displaying text in current
13953 matrix starting at first_unchanged_at_end_row, after
13954 scrolling. */
13955 xassert (first_unchanged_at_end_row->displays_text_p);
13956 row = find_last_row_displaying_text (w->current_matrix, &it,
13957 first_unchanged_at_end_row);
13958 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13959
13960 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13961 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13962 w->window_end_vpos
13963 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13964 xassert (w->window_end_bytepos >= 0);
13965 IF_DEBUG (debug_method_add (w, "A"));
13966 }
13967 else if (last_text_row_at_end)
13968 {
13969 w->window_end_pos
13970 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13971 w->window_end_bytepos
13972 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13973 w->window_end_vpos
13974 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13975 xassert (w->window_end_bytepos >= 0);
13976 IF_DEBUG (debug_method_add (w, "B"));
13977 }
13978 else if (last_text_row)
13979 {
13980 /* We have displayed either to the end of the window or at the
13981 end of the window, i.e. the last row with text is to be found
13982 in the desired matrix. */
13983 w->window_end_pos
13984 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13985 w->window_end_bytepos
13986 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13987 w->window_end_vpos
13988 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13989 xassert (w->window_end_bytepos >= 0);
13990 }
13991 else if (first_unchanged_at_end_row == NULL
13992 && last_text_row == NULL
13993 && last_text_row_at_end == NULL)
13994 {
13995 /* Displayed to end of window, but no line containing text was
13996 displayed. Lines were deleted at the end of the window. */
13997 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13998 int vpos = XFASTINT (w->window_end_vpos);
13999 struct glyph_row *current_row = current_matrix->rows + vpos;
14000 struct glyph_row *desired_row = desired_matrix->rows + vpos;
14001
14002 for (row = NULL;
14003 row == NULL && vpos >= first_vpos;
14004 --vpos, --current_row, --desired_row)
14005 {
14006 if (desired_row->enabled_p)
14007 {
14008 if (desired_row->displays_text_p)
14009 row = desired_row;
14010 }
14011 else if (current_row->displays_text_p)
14012 row = current_row;
14013 }
14014
14015 xassert (row != NULL);
14016 w->window_end_vpos = make_number (vpos + 1);
14017 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14018 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14019 xassert (w->window_end_bytepos >= 0);
14020 IF_DEBUG (debug_method_add (w, "C"));
14021 }
14022 else
14023 abort ();
14024
14025 #if 0 /* This leads to problems, for instance when the cursor is
14026 at ZV, and the cursor line displays no text. */
14027 /* Disable rows below what's displayed in the window. This makes
14028 debugging easier. */
14029 enable_glyph_matrix_rows (current_matrix,
14030 XFASTINT (w->window_end_vpos) + 1,
14031 bottom_vpos, 0);
14032 #endif
14033
14034 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
14035 debug_end_vpos = XFASTINT (w->window_end_vpos));
14036
14037 /* Record that display has not been completed. */
14038 w->window_end_valid = Qnil;
14039 w->desired_matrix->no_scrolling_p = 1;
14040 return 3;
14041
14042 #undef GIVE_UP
14043 }
14044
14045
14046 \f
14047 /***********************************************************************
14048 More debugging support
14049 ***********************************************************************/
14050
14051 #if GLYPH_DEBUG
14052
14053 void dump_glyph_row P_ ((struct glyph_row *, int, int));
14054 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
14055 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
14056
14057
14058 /* Dump the contents of glyph matrix MATRIX on stderr.
14059
14060 GLYPHS 0 means don't show glyph contents.
14061 GLYPHS 1 means show glyphs in short form
14062 GLYPHS > 1 means show glyphs in long form. */
14063
14064 void
14065 dump_glyph_matrix (matrix, glyphs)
14066 struct glyph_matrix *matrix;
14067 int glyphs;
14068 {
14069 int i;
14070 for (i = 0; i < matrix->nrows; ++i)
14071 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
14072 }
14073
14074
14075 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
14076 the glyph row and area where the glyph comes from. */
14077
14078 void
14079 dump_glyph (row, glyph, area)
14080 struct glyph_row *row;
14081 struct glyph *glyph;
14082 int area;
14083 {
14084 if (glyph->type == CHAR_GLYPH)
14085 {
14086 fprintf (stderr,
14087 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14088 glyph - row->glyphs[TEXT_AREA],
14089 'C',
14090 glyph->charpos,
14091 (BUFFERP (glyph->object)
14092 ? 'B'
14093 : (STRINGP (glyph->object)
14094 ? 'S'
14095 : '-')),
14096 glyph->pixel_width,
14097 glyph->u.ch,
14098 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
14099 ? glyph->u.ch
14100 : '.'),
14101 glyph->face_id,
14102 glyph->left_box_line_p,
14103 glyph->right_box_line_p);
14104 }
14105 else if (glyph->type == STRETCH_GLYPH)
14106 {
14107 fprintf (stderr,
14108 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14109 glyph - row->glyphs[TEXT_AREA],
14110 'S',
14111 glyph->charpos,
14112 (BUFFERP (glyph->object)
14113 ? 'B'
14114 : (STRINGP (glyph->object)
14115 ? 'S'
14116 : '-')),
14117 glyph->pixel_width,
14118 0,
14119 '.',
14120 glyph->face_id,
14121 glyph->left_box_line_p,
14122 glyph->right_box_line_p);
14123 }
14124 else if (glyph->type == IMAGE_GLYPH)
14125 {
14126 fprintf (stderr,
14127 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14128 glyph - row->glyphs[TEXT_AREA],
14129 'I',
14130 glyph->charpos,
14131 (BUFFERP (glyph->object)
14132 ? 'B'
14133 : (STRINGP (glyph->object)
14134 ? 'S'
14135 : '-')),
14136 glyph->pixel_width,
14137 glyph->u.img_id,
14138 '.',
14139 glyph->face_id,
14140 glyph->left_box_line_p,
14141 glyph->right_box_line_p);
14142 }
14143 }
14144
14145
14146 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
14147 GLYPHS 0 means don't show glyph contents.
14148 GLYPHS 1 means show glyphs in short form
14149 GLYPHS > 1 means show glyphs in long form. */
14150
14151 void
14152 dump_glyph_row (row, vpos, glyphs)
14153 struct glyph_row *row;
14154 int vpos, glyphs;
14155 {
14156 if (glyphs != 1)
14157 {
14158 fprintf (stderr, "Row Start End Used oEI><\\CTZFesm X Y W H V A P\n");
14159 fprintf (stderr, "======================================================================\n");
14160
14161 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
14162 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
14163 vpos,
14164 MATRIX_ROW_START_CHARPOS (row),
14165 MATRIX_ROW_END_CHARPOS (row),
14166 row->used[TEXT_AREA],
14167 row->contains_overlapping_glyphs_p,
14168 row->enabled_p,
14169 row->truncated_on_left_p,
14170 row->truncated_on_right_p,
14171 row->continued_p,
14172 MATRIX_ROW_CONTINUATION_LINE_P (row),
14173 row->displays_text_p,
14174 row->ends_at_zv_p,
14175 row->fill_line_p,
14176 row->ends_in_middle_of_char_p,
14177 row->starts_in_middle_of_char_p,
14178 row->mouse_face_p,
14179 row->x,
14180 row->y,
14181 row->pixel_width,
14182 row->height,
14183 row->visible_height,
14184 row->ascent,
14185 row->phys_ascent);
14186 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
14187 row->end.overlay_string_index,
14188 row->continuation_lines_width);
14189 fprintf (stderr, "%9d %5d\n",
14190 CHARPOS (row->start.string_pos),
14191 CHARPOS (row->end.string_pos));
14192 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
14193 row->end.dpvec_index);
14194 }
14195
14196 if (glyphs > 1)
14197 {
14198 int area;
14199
14200 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14201 {
14202 struct glyph *glyph = row->glyphs[area];
14203 struct glyph *glyph_end = glyph + row->used[area];
14204
14205 /* Glyph for a line end in text. */
14206 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
14207 ++glyph_end;
14208
14209 if (glyph < glyph_end)
14210 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
14211
14212 for (; glyph < glyph_end; ++glyph)
14213 dump_glyph (row, glyph, area);
14214 }
14215 }
14216 else if (glyphs == 1)
14217 {
14218 int area;
14219
14220 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14221 {
14222 char *s = (char *) alloca (row->used[area] + 1);
14223 int i;
14224
14225 for (i = 0; i < row->used[area]; ++i)
14226 {
14227 struct glyph *glyph = row->glyphs[area] + i;
14228 if (glyph->type == CHAR_GLYPH
14229 && glyph->u.ch < 0x80
14230 && glyph->u.ch >= ' ')
14231 s[i] = glyph->u.ch;
14232 else
14233 s[i] = '.';
14234 }
14235
14236 s[i] = '\0';
14237 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14238 }
14239 }
14240 }
14241
14242
14243 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14244 Sdump_glyph_matrix, 0, 1, "p",
14245 doc: /* Dump the current matrix of the selected window to stderr.
14246 Shows contents of glyph row structures. With non-nil
14247 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14248 glyphs in short form, otherwise show glyphs in long form. */)
14249 (glyphs)
14250 Lisp_Object glyphs;
14251 {
14252 struct window *w = XWINDOW (selected_window);
14253 struct buffer *buffer = XBUFFER (w->buffer);
14254
14255 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14256 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14257 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14258 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14259 fprintf (stderr, "=============================================\n");
14260 dump_glyph_matrix (w->current_matrix,
14261 NILP (glyphs) ? 0 : XINT (glyphs));
14262 return Qnil;
14263 }
14264
14265
14266 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14267 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14268 ()
14269 {
14270 struct frame *f = XFRAME (selected_frame);
14271 dump_glyph_matrix (f->current_matrix, 1);
14272 return Qnil;
14273 }
14274
14275
14276 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14277 doc: /* Dump glyph row ROW to stderr.
14278 GLYPH 0 means don't dump glyphs.
14279 GLYPH 1 means dump glyphs in short form.
14280 GLYPH > 1 or omitted means dump glyphs in long form. */)
14281 (row, glyphs)
14282 Lisp_Object row, glyphs;
14283 {
14284 struct glyph_matrix *matrix;
14285 int vpos;
14286
14287 CHECK_NUMBER (row);
14288 matrix = XWINDOW (selected_window)->current_matrix;
14289 vpos = XINT (row);
14290 if (vpos >= 0 && vpos < matrix->nrows)
14291 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14292 vpos,
14293 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14294 return Qnil;
14295 }
14296
14297
14298 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14299 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14300 GLYPH 0 means don't dump glyphs.
14301 GLYPH 1 means dump glyphs in short form.
14302 GLYPH > 1 or omitted means dump glyphs in long form. */)
14303 (row, glyphs)
14304 Lisp_Object row, glyphs;
14305 {
14306 struct frame *sf = SELECTED_FRAME ();
14307 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14308 int vpos;
14309
14310 CHECK_NUMBER (row);
14311 vpos = XINT (row);
14312 if (vpos >= 0 && vpos < m->nrows)
14313 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14314 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14315 return Qnil;
14316 }
14317
14318
14319 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14320 doc: /* Toggle tracing of redisplay.
14321 With ARG, turn tracing on if and only if ARG is positive. */)
14322 (arg)
14323 Lisp_Object arg;
14324 {
14325 if (NILP (arg))
14326 trace_redisplay_p = !trace_redisplay_p;
14327 else
14328 {
14329 arg = Fprefix_numeric_value (arg);
14330 trace_redisplay_p = XINT (arg) > 0;
14331 }
14332
14333 return Qnil;
14334 }
14335
14336
14337 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14338 doc: /* Like `format', but print result to stderr.
14339 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14340 (nargs, args)
14341 int nargs;
14342 Lisp_Object *args;
14343 {
14344 Lisp_Object s = Fformat (nargs, args);
14345 fprintf (stderr, "%s", SDATA (s));
14346 return Qnil;
14347 }
14348
14349 #endif /* GLYPH_DEBUG */
14350
14351
14352 \f
14353 /***********************************************************************
14354 Building Desired Matrix Rows
14355 ***********************************************************************/
14356
14357 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14358 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14359
14360 static struct glyph_row *
14361 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14362 struct window *w;
14363 Lisp_Object overlay_arrow_string;
14364 {
14365 struct frame *f = XFRAME (WINDOW_FRAME (w));
14366 struct buffer *buffer = XBUFFER (w->buffer);
14367 struct buffer *old = current_buffer;
14368 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14369 int arrow_len = SCHARS (overlay_arrow_string);
14370 const unsigned char *arrow_end = arrow_string + arrow_len;
14371 const unsigned char *p;
14372 struct it it;
14373 int multibyte_p;
14374 int n_glyphs_before;
14375
14376 set_buffer_temp (buffer);
14377 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14378 it.glyph_row->used[TEXT_AREA] = 0;
14379 SET_TEXT_POS (it.position, 0, 0);
14380
14381 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14382 p = arrow_string;
14383 while (p < arrow_end)
14384 {
14385 Lisp_Object face, ilisp;
14386
14387 /* Get the next character. */
14388 if (multibyte_p)
14389 it.c = string_char_and_length (p, arrow_len, &it.len);
14390 else
14391 it.c = *p, it.len = 1;
14392 p += it.len;
14393
14394 /* Get its face. */
14395 ilisp = make_number (p - arrow_string);
14396 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14397 it.face_id = compute_char_face (f, it.c, face);
14398
14399 /* Compute its width, get its glyphs. */
14400 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14401 SET_TEXT_POS (it.position, -1, -1);
14402 PRODUCE_GLYPHS (&it);
14403
14404 /* If this character doesn't fit any more in the line, we have
14405 to remove some glyphs. */
14406 if (it.current_x > it.last_visible_x)
14407 {
14408 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14409 break;
14410 }
14411 }
14412
14413 set_buffer_temp (old);
14414 return it.glyph_row;
14415 }
14416
14417
14418 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14419 glyphs are only inserted for terminal frames since we can't really
14420 win with truncation glyphs when partially visible glyphs are
14421 involved. Which glyphs to insert is determined by
14422 produce_special_glyphs. */
14423
14424 static void
14425 insert_left_trunc_glyphs (it)
14426 struct it *it;
14427 {
14428 struct it truncate_it;
14429 struct glyph *from, *end, *to, *toend;
14430
14431 xassert (!FRAME_WINDOW_P (it->f));
14432
14433 /* Get the truncation glyphs. */
14434 truncate_it = *it;
14435 truncate_it.current_x = 0;
14436 truncate_it.face_id = DEFAULT_FACE_ID;
14437 truncate_it.glyph_row = &scratch_glyph_row;
14438 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14439 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14440 truncate_it.object = make_number (0);
14441 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14442
14443 /* Overwrite glyphs from IT with truncation glyphs. */
14444 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14445 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14446 to = it->glyph_row->glyphs[TEXT_AREA];
14447 toend = to + it->glyph_row->used[TEXT_AREA];
14448
14449 while (from < end)
14450 *to++ = *from++;
14451
14452 /* There may be padding glyphs left over. Overwrite them too. */
14453 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14454 {
14455 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14456 while (from < end)
14457 *to++ = *from++;
14458 }
14459
14460 if (to > toend)
14461 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14462 }
14463
14464
14465 /* Compute the pixel height and width of IT->glyph_row.
14466
14467 Most of the time, ascent and height of a display line will be equal
14468 to the max_ascent and max_height values of the display iterator
14469 structure. This is not the case if
14470
14471 1. We hit ZV without displaying anything. In this case, max_ascent
14472 and max_height will be zero.
14473
14474 2. We have some glyphs that don't contribute to the line height.
14475 (The glyph row flag contributes_to_line_height_p is for future
14476 pixmap extensions).
14477
14478 The first case is easily covered by using default values because in
14479 these cases, the line height does not really matter, except that it
14480 must not be zero. */
14481
14482 static void
14483 compute_line_metrics (it)
14484 struct it *it;
14485 {
14486 struct glyph_row *row = it->glyph_row;
14487 int area, i;
14488
14489 if (FRAME_WINDOW_P (it->f))
14490 {
14491 int i, min_y, max_y;
14492
14493 /* The line may consist of one space only, that was added to
14494 place the cursor on it. If so, the row's height hasn't been
14495 computed yet. */
14496 if (row->height == 0)
14497 {
14498 if (it->max_ascent + it->max_descent == 0)
14499 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14500 row->ascent = it->max_ascent;
14501 row->height = it->max_ascent + it->max_descent;
14502 row->phys_ascent = it->max_phys_ascent;
14503 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14504 row->extra_line_spacing = it->max_extra_line_spacing;
14505 }
14506
14507 /* Compute the width of this line. */
14508 row->pixel_width = row->x;
14509 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14510 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14511
14512 xassert (row->pixel_width >= 0);
14513 xassert (row->ascent >= 0 && row->height > 0);
14514
14515 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14516 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14517
14518 /* If first line's physical ascent is larger than its logical
14519 ascent, use the physical ascent, and make the row taller.
14520 This makes accented characters fully visible. */
14521 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14522 && row->phys_ascent > row->ascent)
14523 {
14524 row->height += row->phys_ascent - row->ascent;
14525 row->ascent = row->phys_ascent;
14526 }
14527
14528 /* Compute how much of the line is visible. */
14529 row->visible_height = row->height;
14530
14531 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14532 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14533
14534 if (row->y < min_y)
14535 row->visible_height -= min_y - row->y;
14536 if (row->y + row->height > max_y)
14537 row->visible_height -= row->y + row->height - max_y;
14538 }
14539 else
14540 {
14541 row->pixel_width = row->used[TEXT_AREA];
14542 if (row->continued_p)
14543 row->pixel_width -= it->continuation_pixel_width;
14544 else if (row->truncated_on_right_p)
14545 row->pixel_width -= it->truncation_pixel_width;
14546 row->ascent = row->phys_ascent = 0;
14547 row->height = row->phys_height = row->visible_height = 1;
14548 row->extra_line_spacing = 0;
14549 }
14550
14551 /* Compute a hash code for this row. */
14552 row->hash = 0;
14553 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14554 for (i = 0; i < row->used[area]; ++i)
14555 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14556 + row->glyphs[area][i].u.val
14557 + row->glyphs[area][i].face_id
14558 + row->glyphs[area][i].padding_p
14559 + (row->glyphs[area][i].type << 2));
14560
14561 it->max_ascent = it->max_descent = 0;
14562 it->max_phys_ascent = it->max_phys_descent = 0;
14563 }
14564
14565
14566 /* Append one space to the glyph row of iterator IT if doing a
14567 window-based redisplay. The space has the same face as
14568 IT->face_id. Value is non-zero if a space was added.
14569
14570 This function is called to make sure that there is always one glyph
14571 at the end of a glyph row that the cursor can be set on under
14572 window-systems. (If there weren't such a glyph we would not know
14573 how wide and tall a box cursor should be displayed).
14574
14575 At the same time this space let's a nicely handle clearing to the
14576 end of the line if the row ends in italic text. */
14577
14578 static int
14579 append_space_for_newline (it, default_face_p)
14580 struct it *it;
14581 int default_face_p;
14582 {
14583 if (FRAME_WINDOW_P (it->f))
14584 {
14585 int n = it->glyph_row->used[TEXT_AREA];
14586
14587 if (it->glyph_row->glyphs[TEXT_AREA] + n
14588 < it->glyph_row->glyphs[1 + TEXT_AREA])
14589 {
14590 /* Save some values that must not be changed.
14591 Must save IT->c and IT->len because otherwise
14592 ITERATOR_AT_END_P wouldn't work anymore after
14593 append_space_for_newline has been called. */
14594 enum display_element_type saved_what = it->what;
14595 int saved_c = it->c, saved_len = it->len;
14596 int saved_x = it->current_x;
14597 int saved_face_id = it->face_id;
14598 struct text_pos saved_pos;
14599 Lisp_Object saved_object;
14600 struct face *face;
14601
14602 saved_object = it->object;
14603 saved_pos = it->position;
14604
14605 it->what = IT_CHARACTER;
14606 bzero (&it->position, sizeof it->position);
14607 it->object = make_number (0);
14608 it->c = ' ';
14609 it->len = 1;
14610
14611 if (default_face_p)
14612 it->face_id = DEFAULT_FACE_ID;
14613 else if (it->face_before_selective_p)
14614 it->face_id = it->saved_face_id;
14615 face = FACE_FROM_ID (it->f, it->face_id);
14616 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14617
14618 PRODUCE_GLYPHS (it);
14619
14620 it->override_ascent = -1;
14621 it->constrain_row_ascent_descent_p = 0;
14622 it->current_x = saved_x;
14623 it->object = saved_object;
14624 it->position = saved_pos;
14625 it->what = saved_what;
14626 it->face_id = saved_face_id;
14627 it->len = saved_len;
14628 it->c = saved_c;
14629 return 1;
14630 }
14631 }
14632
14633 return 0;
14634 }
14635
14636
14637 /* Extend the face of the last glyph in the text area of IT->glyph_row
14638 to the end of the display line. Called from display_line.
14639 If the glyph row is empty, add a space glyph to it so that we
14640 know the face to draw. Set the glyph row flag fill_line_p. */
14641
14642 static void
14643 extend_face_to_end_of_line (it)
14644 struct it *it;
14645 {
14646 struct face *face;
14647 struct frame *f = it->f;
14648
14649 /* If line is already filled, do nothing. */
14650 if (it->current_x >= it->last_visible_x)
14651 return;
14652
14653 /* Face extension extends the background and box of IT->face_id
14654 to the end of the line. If the background equals the background
14655 of the frame, we don't have to do anything. */
14656 if (it->face_before_selective_p)
14657 face = FACE_FROM_ID (it->f, it->saved_face_id);
14658 else
14659 face = FACE_FROM_ID (f, it->face_id);
14660
14661 if (FRAME_WINDOW_P (f)
14662 && face->box == FACE_NO_BOX
14663 && face->background == FRAME_BACKGROUND_PIXEL (f)
14664 && !face->stipple)
14665 return;
14666
14667 /* Set the glyph row flag indicating that the face of the last glyph
14668 in the text area has to be drawn to the end of the text area. */
14669 it->glyph_row->fill_line_p = 1;
14670
14671 /* If current character of IT is not ASCII, make sure we have the
14672 ASCII face. This will be automatically undone the next time
14673 get_next_display_element returns a multibyte character. Note
14674 that the character will always be single byte in unibyte text. */
14675 if (!SINGLE_BYTE_CHAR_P (it->c))
14676 {
14677 it->face_id = FACE_FOR_CHAR (f, face, 0);
14678 }
14679
14680 if (FRAME_WINDOW_P (f))
14681 {
14682 /* If the row is empty, add a space with the current face of IT,
14683 so that we know which face to draw. */
14684 if (it->glyph_row->used[TEXT_AREA] == 0)
14685 {
14686 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14687 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14688 it->glyph_row->used[TEXT_AREA] = 1;
14689 }
14690 }
14691 else
14692 {
14693 /* Save some values that must not be changed. */
14694 int saved_x = it->current_x;
14695 struct text_pos saved_pos;
14696 Lisp_Object saved_object;
14697 enum display_element_type saved_what = it->what;
14698 int saved_face_id = it->face_id;
14699
14700 saved_object = it->object;
14701 saved_pos = it->position;
14702
14703 it->what = IT_CHARACTER;
14704 bzero (&it->position, sizeof it->position);
14705 it->object = make_number (0);
14706 it->c = ' ';
14707 it->len = 1;
14708 it->face_id = face->id;
14709
14710 PRODUCE_GLYPHS (it);
14711
14712 while (it->current_x <= it->last_visible_x)
14713 PRODUCE_GLYPHS (it);
14714
14715 /* Don't count these blanks really. It would let us insert a left
14716 truncation glyph below and make us set the cursor on them, maybe. */
14717 it->current_x = saved_x;
14718 it->object = saved_object;
14719 it->position = saved_pos;
14720 it->what = saved_what;
14721 it->face_id = saved_face_id;
14722 }
14723 }
14724
14725
14726 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14727 trailing whitespace. */
14728
14729 static int
14730 trailing_whitespace_p (charpos)
14731 int charpos;
14732 {
14733 int bytepos = CHAR_TO_BYTE (charpos);
14734 int c = 0;
14735
14736 while (bytepos < ZV_BYTE
14737 && (c = FETCH_CHAR (bytepos),
14738 c == ' ' || c == '\t'))
14739 ++bytepos;
14740
14741 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14742 {
14743 if (bytepos != PT_BYTE)
14744 return 1;
14745 }
14746 return 0;
14747 }
14748
14749
14750 /* Highlight trailing whitespace, if any, in ROW. */
14751
14752 void
14753 highlight_trailing_whitespace (f, row)
14754 struct frame *f;
14755 struct glyph_row *row;
14756 {
14757 int used = row->used[TEXT_AREA];
14758
14759 if (used)
14760 {
14761 struct glyph *start = row->glyphs[TEXT_AREA];
14762 struct glyph *glyph = start + used - 1;
14763
14764 /* Skip over glyphs inserted to display the cursor at the
14765 end of a line, for extending the face of the last glyph
14766 to the end of the line on terminals, and for truncation
14767 and continuation glyphs. */
14768 while (glyph >= start
14769 && glyph->type == CHAR_GLYPH
14770 && INTEGERP (glyph->object))
14771 --glyph;
14772
14773 /* If last glyph is a space or stretch, and it's trailing
14774 whitespace, set the face of all trailing whitespace glyphs in
14775 IT->glyph_row to `trailing-whitespace'. */
14776 if (glyph >= start
14777 && BUFFERP (glyph->object)
14778 && (glyph->type == STRETCH_GLYPH
14779 || (glyph->type == CHAR_GLYPH
14780 && glyph->u.ch == ' '))
14781 && trailing_whitespace_p (glyph->charpos))
14782 {
14783 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
14784 if (face_id < 0)
14785 return;
14786
14787 while (glyph >= start
14788 && BUFFERP (glyph->object)
14789 && (glyph->type == STRETCH_GLYPH
14790 || (glyph->type == CHAR_GLYPH
14791 && glyph->u.ch == ' ')))
14792 (glyph--)->face_id = face_id;
14793 }
14794 }
14795 }
14796
14797
14798 /* Value is non-zero if glyph row ROW in window W should be
14799 used to hold the cursor. */
14800
14801 static int
14802 cursor_row_p (w, row)
14803 struct window *w;
14804 struct glyph_row *row;
14805 {
14806 int cursor_row_p = 1;
14807
14808 if (PT == MATRIX_ROW_END_CHARPOS (row))
14809 {
14810 /* If the row ends with a newline from a string, we don't want
14811 the cursor there (if the row is continued it doesn't end in a
14812 newline). */
14813 if (CHARPOS (row->end.string_pos) >= 0)
14814 cursor_row_p = row->continued_p;
14815 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14816 {
14817 /* If the row ends in middle of a real character,
14818 and the line is continued, we want the cursor here.
14819 That's because MATRIX_ROW_END_CHARPOS would equal
14820 PT if PT is before the character. */
14821 if (!row->ends_in_ellipsis_p)
14822 cursor_row_p = row->continued_p;
14823 else
14824 /* If the row ends in an ellipsis, then
14825 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
14826 We want that position to be displayed after the ellipsis. */
14827 cursor_row_p = 0;
14828 }
14829 /* If the row ends at ZV, display the cursor at the end of that
14830 row instead of at the start of the row below. */
14831 else if (row->ends_at_zv_p)
14832 cursor_row_p = 1;
14833 else
14834 cursor_row_p = 0;
14835 }
14836
14837 return cursor_row_p;
14838 }
14839
14840
14841 /* Construct the glyph row IT->glyph_row in the desired matrix of
14842 IT->w from text at the current position of IT. See dispextern.h
14843 for an overview of struct it. Value is non-zero if
14844 IT->glyph_row displays text, as opposed to a line displaying ZV
14845 only. */
14846
14847 static int
14848 display_line (it)
14849 struct it *it;
14850 {
14851 struct glyph_row *row = it->glyph_row;
14852 Lisp_Object overlay_arrow_string;
14853
14854 /* We always start displaying at hpos zero even if hscrolled. */
14855 xassert (it->hpos == 0 && it->current_x == 0);
14856
14857 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14858 >= it->w->desired_matrix->nrows)
14859 {
14860 it->w->nrows_scale_factor++;
14861 fonts_changed_p = 1;
14862 return 0;
14863 }
14864
14865 /* Is IT->w showing the region? */
14866 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14867
14868 /* Clear the result glyph row and enable it. */
14869 prepare_desired_row (row);
14870
14871 row->y = it->current_y;
14872 row->start = it->start;
14873 row->continuation_lines_width = it->continuation_lines_width;
14874 row->displays_text_p = 1;
14875 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14876 it->starts_in_middle_of_char_p = 0;
14877
14878 /* Arrange the overlays nicely for our purposes. Usually, we call
14879 display_line on only one line at a time, in which case this
14880 can't really hurt too much, or we call it on lines which appear
14881 one after another in the buffer, in which case all calls to
14882 recenter_overlay_lists but the first will be pretty cheap. */
14883 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14884
14885 /* Move over display elements that are not visible because we are
14886 hscrolled. This may stop at an x-position < IT->first_visible_x
14887 if the first glyph is partially visible or if we hit a line end. */
14888 if (it->current_x < it->first_visible_x)
14889 {
14890 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14891 MOVE_TO_POS | MOVE_TO_X);
14892 }
14893
14894 /* Get the initial row height. This is either the height of the
14895 text hscrolled, if there is any, or zero. */
14896 row->ascent = it->max_ascent;
14897 row->height = it->max_ascent + it->max_descent;
14898 row->phys_ascent = it->max_phys_ascent;
14899 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14900 row->extra_line_spacing = it->max_extra_line_spacing;
14901
14902 /* Loop generating characters. The loop is left with IT on the next
14903 character to display. */
14904 while (1)
14905 {
14906 int n_glyphs_before, hpos_before, x_before;
14907 int x, i, nglyphs;
14908 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14909
14910 /* Retrieve the next thing to display. Value is zero if end of
14911 buffer reached. */
14912 if (!get_next_display_element (it))
14913 {
14914 /* Maybe add a space at the end of this line that is used to
14915 display the cursor there under X. Set the charpos of the
14916 first glyph of blank lines not corresponding to any text
14917 to -1. */
14918 #ifdef HAVE_WINDOW_SYSTEM
14919 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14920 row->exact_window_width_line_p = 1;
14921 else
14922 #endif /* HAVE_WINDOW_SYSTEM */
14923 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14924 || row->used[TEXT_AREA] == 0)
14925 {
14926 row->glyphs[TEXT_AREA]->charpos = -1;
14927 row->displays_text_p = 0;
14928
14929 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14930 && (!MINI_WINDOW_P (it->w)
14931 || (minibuf_level && EQ (it->window, minibuf_window))))
14932 row->indicate_empty_line_p = 1;
14933 }
14934
14935 it->continuation_lines_width = 0;
14936 row->ends_at_zv_p = 1;
14937 break;
14938 }
14939
14940 /* Now, get the metrics of what we want to display. This also
14941 generates glyphs in `row' (which is IT->glyph_row). */
14942 n_glyphs_before = row->used[TEXT_AREA];
14943 x = it->current_x;
14944
14945 /* Remember the line height so far in case the next element doesn't
14946 fit on the line. */
14947 if (!it->truncate_lines_p)
14948 {
14949 ascent = it->max_ascent;
14950 descent = it->max_descent;
14951 phys_ascent = it->max_phys_ascent;
14952 phys_descent = it->max_phys_descent;
14953 }
14954
14955 PRODUCE_GLYPHS (it);
14956
14957 /* If this display element was in marginal areas, continue with
14958 the next one. */
14959 if (it->area != TEXT_AREA)
14960 {
14961 row->ascent = max (row->ascent, it->max_ascent);
14962 row->height = max (row->height, it->max_ascent + it->max_descent);
14963 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14964 row->phys_height = max (row->phys_height,
14965 it->max_phys_ascent + it->max_phys_descent);
14966 row->extra_line_spacing = max (row->extra_line_spacing,
14967 it->max_extra_line_spacing);
14968 set_iterator_to_next (it, 1);
14969 continue;
14970 }
14971
14972 /* Does the display element fit on the line? If we truncate
14973 lines, we should draw past the right edge of the window. If
14974 we don't truncate, we want to stop so that we can display the
14975 continuation glyph before the right margin. If lines are
14976 continued, there are two possible strategies for characters
14977 resulting in more than 1 glyph (e.g. tabs): Display as many
14978 glyphs as possible in this line and leave the rest for the
14979 continuation line, or display the whole element in the next
14980 line. Original redisplay did the former, so we do it also. */
14981 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14982 hpos_before = it->hpos;
14983 x_before = x;
14984
14985 if (/* Not a newline. */
14986 nglyphs > 0
14987 /* Glyphs produced fit entirely in the line. */
14988 && it->current_x < it->last_visible_x)
14989 {
14990 it->hpos += nglyphs;
14991 row->ascent = max (row->ascent, it->max_ascent);
14992 row->height = max (row->height, it->max_ascent + it->max_descent);
14993 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14994 row->phys_height = max (row->phys_height,
14995 it->max_phys_ascent + it->max_phys_descent);
14996 row->extra_line_spacing = max (row->extra_line_spacing,
14997 it->max_extra_line_spacing);
14998 if (it->current_x - it->pixel_width < it->first_visible_x)
14999 row->x = x - it->first_visible_x;
15000 }
15001 else
15002 {
15003 int new_x;
15004 struct glyph *glyph;
15005
15006 for (i = 0; i < nglyphs; ++i, x = new_x)
15007 {
15008 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
15009 new_x = x + glyph->pixel_width;
15010
15011 if (/* Lines are continued. */
15012 !it->truncate_lines_p
15013 && (/* Glyph doesn't fit on the line. */
15014 new_x > it->last_visible_x
15015 /* Or it fits exactly on a window system frame. */
15016 || (new_x == it->last_visible_x
15017 && FRAME_WINDOW_P (it->f))))
15018 {
15019 /* End of a continued line. */
15020
15021 if (it->hpos == 0
15022 || (new_x == it->last_visible_x
15023 && FRAME_WINDOW_P (it->f)))
15024 {
15025 /* Current glyph is the only one on the line or
15026 fits exactly on the line. We must continue
15027 the line because we can't draw the cursor
15028 after the glyph. */
15029 row->continued_p = 1;
15030 it->current_x = new_x;
15031 it->continuation_lines_width += new_x;
15032 ++it->hpos;
15033 if (i == nglyphs - 1)
15034 {
15035 set_iterator_to_next (it, 1);
15036 #ifdef HAVE_WINDOW_SYSTEM
15037 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15038 {
15039 if (!get_next_display_element (it))
15040 {
15041 row->exact_window_width_line_p = 1;
15042 it->continuation_lines_width = 0;
15043 row->continued_p = 0;
15044 row->ends_at_zv_p = 1;
15045 }
15046 else if (ITERATOR_AT_END_OF_LINE_P (it))
15047 {
15048 row->continued_p = 0;
15049 row->exact_window_width_line_p = 1;
15050 }
15051 }
15052 #endif /* HAVE_WINDOW_SYSTEM */
15053 }
15054 }
15055 else if (CHAR_GLYPH_PADDING_P (*glyph)
15056 && !FRAME_WINDOW_P (it->f))
15057 {
15058 /* A padding glyph that doesn't fit on this line.
15059 This means the whole character doesn't fit
15060 on the line. */
15061 row->used[TEXT_AREA] = n_glyphs_before;
15062
15063 /* Fill the rest of the row with continuation
15064 glyphs like in 20.x. */
15065 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
15066 < row->glyphs[1 + TEXT_AREA])
15067 produce_special_glyphs (it, IT_CONTINUATION);
15068
15069 row->continued_p = 1;
15070 it->current_x = x_before;
15071 it->continuation_lines_width += x_before;
15072
15073 /* Restore the height to what it was before the
15074 element not fitting on the line. */
15075 it->max_ascent = ascent;
15076 it->max_descent = descent;
15077 it->max_phys_ascent = phys_ascent;
15078 it->max_phys_descent = phys_descent;
15079 }
15080 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
15081 {
15082 /* A TAB that extends past the right edge of the
15083 window. This produces a single glyph on
15084 window system frames. We leave the glyph in
15085 this row and let it fill the row, but don't
15086 consume the TAB. */
15087 it->continuation_lines_width += it->last_visible_x;
15088 row->ends_in_middle_of_char_p = 1;
15089 row->continued_p = 1;
15090 glyph->pixel_width = it->last_visible_x - x;
15091 it->starts_in_middle_of_char_p = 1;
15092 }
15093 else
15094 {
15095 /* Something other than a TAB that draws past
15096 the right edge of the window. Restore
15097 positions to values before the element. */
15098 row->used[TEXT_AREA] = n_glyphs_before + i;
15099
15100 /* Display continuation glyphs. */
15101 if (!FRAME_WINDOW_P (it->f))
15102 produce_special_glyphs (it, IT_CONTINUATION);
15103 row->continued_p = 1;
15104
15105 it->continuation_lines_width += x;
15106
15107 if (nglyphs > 1 && i > 0)
15108 {
15109 row->ends_in_middle_of_char_p = 1;
15110 it->starts_in_middle_of_char_p = 1;
15111 }
15112
15113 /* Restore the height to what it was before the
15114 element not fitting on the line. */
15115 it->max_ascent = ascent;
15116 it->max_descent = descent;
15117 it->max_phys_ascent = phys_ascent;
15118 it->max_phys_descent = phys_descent;
15119 }
15120
15121 break;
15122 }
15123 else if (new_x > it->first_visible_x)
15124 {
15125 /* Increment number of glyphs actually displayed. */
15126 ++it->hpos;
15127
15128 if (x < it->first_visible_x)
15129 /* Glyph is partially visible, i.e. row starts at
15130 negative X position. */
15131 row->x = x - it->first_visible_x;
15132 }
15133 else
15134 {
15135 /* Glyph is completely off the left margin of the
15136 window. This should not happen because of the
15137 move_it_in_display_line at the start of this
15138 function, unless the text display area of the
15139 window is empty. */
15140 xassert (it->first_visible_x <= it->last_visible_x);
15141 }
15142 }
15143
15144 row->ascent = max (row->ascent, it->max_ascent);
15145 row->height = max (row->height, it->max_ascent + it->max_descent);
15146 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15147 row->phys_height = max (row->phys_height,
15148 it->max_phys_ascent + it->max_phys_descent);
15149 row->extra_line_spacing = max (row->extra_line_spacing,
15150 it->max_extra_line_spacing);
15151
15152 /* End of this display line if row is continued. */
15153 if (row->continued_p || row->ends_at_zv_p)
15154 break;
15155 }
15156
15157 at_end_of_line:
15158 /* Is this a line end? If yes, we're also done, after making
15159 sure that a non-default face is extended up to the right
15160 margin of the window. */
15161 if (ITERATOR_AT_END_OF_LINE_P (it))
15162 {
15163 int used_before = row->used[TEXT_AREA];
15164
15165 row->ends_in_newline_from_string_p = STRINGP (it->object);
15166
15167 #ifdef HAVE_WINDOW_SYSTEM
15168 /* Add a space at the end of the line that is used to
15169 display the cursor there. */
15170 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15171 append_space_for_newline (it, 0);
15172 #endif /* HAVE_WINDOW_SYSTEM */
15173
15174 /* Extend the face to the end of the line. */
15175 extend_face_to_end_of_line (it);
15176
15177 /* Make sure we have the position. */
15178 if (used_before == 0)
15179 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
15180
15181 /* Consume the line end. This skips over invisible lines. */
15182 set_iterator_to_next (it, 1);
15183 it->continuation_lines_width = 0;
15184 break;
15185 }
15186
15187 /* Proceed with next display element. Note that this skips
15188 over lines invisible because of selective display. */
15189 set_iterator_to_next (it, 1);
15190
15191 /* If we truncate lines, we are done when the last displayed
15192 glyphs reach past the right margin of the window. */
15193 if (it->truncate_lines_p
15194 && (FRAME_WINDOW_P (it->f)
15195 ? (it->current_x >= it->last_visible_x)
15196 : (it->current_x > it->last_visible_x)))
15197 {
15198 /* Maybe add truncation glyphs. */
15199 if (!FRAME_WINDOW_P (it->f))
15200 {
15201 int i, n;
15202
15203 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
15204 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
15205 break;
15206
15207 for (n = row->used[TEXT_AREA]; i < n; ++i)
15208 {
15209 row->used[TEXT_AREA] = i;
15210 produce_special_glyphs (it, IT_TRUNCATION);
15211 }
15212 }
15213 #ifdef HAVE_WINDOW_SYSTEM
15214 else
15215 {
15216 /* Don't truncate if we can overflow newline into fringe. */
15217 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15218 {
15219 if (!get_next_display_element (it))
15220 {
15221 it->continuation_lines_width = 0;
15222 row->ends_at_zv_p = 1;
15223 row->exact_window_width_line_p = 1;
15224 break;
15225 }
15226 if (ITERATOR_AT_END_OF_LINE_P (it))
15227 {
15228 row->exact_window_width_line_p = 1;
15229 goto at_end_of_line;
15230 }
15231 }
15232 }
15233 #endif /* HAVE_WINDOW_SYSTEM */
15234
15235 row->truncated_on_right_p = 1;
15236 it->continuation_lines_width = 0;
15237 reseat_at_next_visible_line_start (it, 0);
15238 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
15239 it->hpos = hpos_before;
15240 it->current_x = x_before;
15241 break;
15242 }
15243 }
15244
15245 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15246 at the left window margin. */
15247 if (it->first_visible_x
15248 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
15249 {
15250 if (!FRAME_WINDOW_P (it->f))
15251 insert_left_trunc_glyphs (it);
15252 row->truncated_on_left_p = 1;
15253 }
15254
15255 /* If the start of this line is the overlay arrow-position, then
15256 mark this glyph row as the one containing the overlay arrow.
15257 This is clearly a mess with variable size fonts. It would be
15258 better to let it be displayed like cursors under X. */
15259 if ((row->displays_text_p || !overlay_arrow_seen)
15260 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
15261 !NILP (overlay_arrow_string)))
15262 {
15263 /* Overlay arrow in window redisplay is a fringe bitmap. */
15264 if (STRINGP (overlay_arrow_string))
15265 {
15266 struct glyph_row *arrow_row
15267 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
15268 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15269 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15270 struct glyph *p = row->glyphs[TEXT_AREA];
15271 struct glyph *p2, *end;
15272
15273 /* Copy the arrow glyphs. */
15274 while (glyph < arrow_end)
15275 *p++ = *glyph++;
15276
15277 /* Throw away padding glyphs. */
15278 p2 = p;
15279 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15280 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15281 ++p2;
15282 if (p2 > p)
15283 {
15284 while (p2 < end)
15285 *p++ = *p2++;
15286 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15287 }
15288 }
15289 else
15290 {
15291 xassert (INTEGERP (overlay_arrow_string));
15292 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
15293 }
15294 overlay_arrow_seen = 1;
15295 }
15296
15297 /* Compute pixel dimensions of this line. */
15298 compute_line_metrics (it);
15299
15300 /* Remember the position at which this line ends. */
15301 row->end = it->current;
15302
15303 /* Record whether this row ends inside an ellipsis. */
15304 row->ends_in_ellipsis_p
15305 = (it->method == GET_FROM_DISPLAY_VECTOR
15306 && it->ellipsis_p);
15307
15308 /* Save fringe bitmaps in this row. */
15309 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15310 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15311 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15312 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15313
15314 it->left_user_fringe_bitmap = 0;
15315 it->left_user_fringe_face_id = 0;
15316 it->right_user_fringe_bitmap = 0;
15317 it->right_user_fringe_face_id = 0;
15318
15319 /* Maybe set the cursor. */
15320 if (it->w->cursor.vpos < 0
15321 && PT >= MATRIX_ROW_START_CHARPOS (row)
15322 && PT <= MATRIX_ROW_END_CHARPOS (row)
15323 && cursor_row_p (it->w, row))
15324 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15325
15326 /* Highlight trailing whitespace. */
15327 if (!NILP (Vshow_trailing_whitespace))
15328 highlight_trailing_whitespace (it->f, it->glyph_row);
15329
15330 /* Prepare for the next line. This line starts horizontally at (X
15331 HPOS) = (0 0). Vertical positions are incremented. As a
15332 convenience for the caller, IT->glyph_row is set to the next
15333 row to be used. */
15334 it->current_x = it->hpos = 0;
15335 it->current_y += row->height;
15336 ++it->vpos;
15337 ++it->glyph_row;
15338 it->start = it->current;
15339 return row->displays_text_p;
15340 }
15341
15342
15343 \f
15344 /***********************************************************************
15345 Menu Bar
15346 ***********************************************************************/
15347
15348 /* Redisplay the menu bar in the frame for window W.
15349
15350 The menu bar of X frames that don't have X toolkit support is
15351 displayed in a special window W->frame->menu_bar_window.
15352
15353 The menu bar of terminal frames is treated specially as far as
15354 glyph matrices are concerned. Menu bar lines are not part of
15355 windows, so the update is done directly on the frame matrix rows
15356 for the menu bar. */
15357
15358 static void
15359 display_menu_bar (w)
15360 struct window *w;
15361 {
15362 struct frame *f = XFRAME (WINDOW_FRAME (w));
15363 struct it it;
15364 Lisp_Object items;
15365 int i;
15366
15367 /* Don't do all this for graphical frames. */
15368 #ifdef HAVE_NTGUI
15369 if (!NILP (Vwindow_system))
15370 return;
15371 #endif
15372 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15373 if (FRAME_X_P (f))
15374 return;
15375 #endif
15376 #ifdef MAC_OS
15377 if (FRAME_MAC_P (f))
15378 return;
15379 #endif
15380
15381 #ifdef USE_X_TOOLKIT
15382 xassert (!FRAME_WINDOW_P (f));
15383 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15384 it.first_visible_x = 0;
15385 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15386 #else /* not USE_X_TOOLKIT */
15387 if (FRAME_WINDOW_P (f))
15388 {
15389 /* Menu bar lines are displayed in the desired matrix of the
15390 dummy window menu_bar_window. */
15391 struct window *menu_w;
15392 xassert (WINDOWP (f->menu_bar_window));
15393 menu_w = XWINDOW (f->menu_bar_window);
15394 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15395 MENU_FACE_ID);
15396 it.first_visible_x = 0;
15397 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15398 }
15399 else
15400 {
15401 /* This is a TTY frame, i.e. character hpos/vpos are used as
15402 pixel x/y. */
15403 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15404 MENU_FACE_ID);
15405 it.first_visible_x = 0;
15406 it.last_visible_x = FRAME_COLS (f);
15407 }
15408 #endif /* not USE_X_TOOLKIT */
15409
15410 if (! mode_line_inverse_video)
15411 /* Force the menu-bar to be displayed in the default face. */
15412 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15413
15414 /* Clear all rows of the menu bar. */
15415 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15416 {
15417 struct glyph_row *row = it.glyph_row + i;
15418 clear_glyph_row (row);
15419 row->enabled_p = 1;
15420 row->full_width_p = 1;
15421 }
15422
15423 /* Display all items of the menu bar. */
15424 items = FRAME_MENU_BAR_ITEMS (it.f);
15425 for (i = 0; i < XVECTOR (items)->size; i += 4)
15426 {
15427 Lisp_Object string;
15428
15429 /* Stop at nil string. */
15430 string = AREF (items, i + 1);
15431 if (NILP (string))
15432 break;
15433
15434 /* Remember where item was displayed. */
15435 AREF (items, i + 3) = make_number (it.hpos);
15436
15437 /* Display the item, pad with one space. */
15438 if (it.current_x < it.last_visible_x)
15439 display_string (NULL, string, Qnil, 0, 0, &it,
15440 SCHARS (string) + 1, 0, 0, -1);
15441 }
15442
15443 /* Fill out the line with spaces. */
15444 if (it.current_x < it.last_visible_x)
15445 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15446
15447 /* Compute the total height of the lines. */
15448 compute_line_metrics (&it);
15449 }
15450
15451
15452 \f
15453 /***********************************************************************
15454 Mode Line
15455 ***********************************************************************/
15456
15457 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15458 FORCE is non-zero, redisplay mode lines unconditionally.
15459 Otherwise, redisplay only mode lines that are garbaged. Value is
15460 the number of windows whose mode lines were redisplayed. */
15461
15462 static int
15463 redisplay_mode_lines (window, force)
15464 Lisp_Object window;
15465 int force;
15466 {
15467 int nwindows = 0;
15468
15469 while (!NILP (window))
15470 {
15471 struct window *w = XWINDOW (window);
15472
15473 if (WINDOWP (w->hchild))
15474 nwindows += redisplay_mode_lines (w->hchild, force);
15475 else if (WINDOWP (w->vchild))
15476 nwindows += redisplay_mode_lines (w->vchild, force);
15477 else if (force
15478 || FRAME_GARBAGED_P (XFRAME (w->frame))
15479 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15480 {
15481 struct text_pos lpoint;
15482 struct buffer *old = current_buffer;
15483
15484 /* Set the window's buffer for the mode line display. */
15485 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15486 set_buffer_internal_1 (XBUFFER (w->buffer));
15487
15488 /* Point refers normally to the selected window. For any
15489 other window, set up appropriate value. */
15490 if (!EQ (window, selected_window))
15491 {
15492 struct text_pos pt;
15493
15494 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15495 if (CHARPOS (pt) < BEGV)
15496 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15497 else if (CHARPOS (pt) > (ZV - 1))
15498 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15499 else
15500 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15501 }
15502
15503 /* Display mode lines. */
15504 clear_glyph_matrix (w->desired_matrix);
15505 if (display_mode_lines (w))
15506 {
15507 ++nwindows;
15508 w->must_be_updated_p = 1;
15509 }
15510
15511 /* Restore old settings. */
15512 set_buffer_internal_1 (old);
15513 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15514 }
15515
15516 window = w->next;
15517 }
15518
15519 return nwindows;
15520 }
15521
15522
15523 /* Display the mode and/or top line of window W. Value is the number
15524 of mode lines displayed. */
15525
15526 static int
15527 display_mode_lines (w)
15528 struct window *w;
15529 {
15530 Lisp_Object old_selected_window, old_selected_frame;
15531 int n = 0;
15532
15533 old_selected_frame = selected_frame;
15534 selected_frame = w->frame;
15535 old_selected_window = selected_window;
15536 XSETWINDOW (selected_window, w);
15537
15538 /* These will be set while the mode line specs are processed. */
15539 line_number_displayed = 0;
15540 w->column_number_displayed = Qnil;
15541
15542 if (WINDOW_WANTS_MODELINE_P (w))
15543 {
15544 struct window *sel_w = XWINDOW (old_selected_window);
15545
15546 /* Select mode line face based on the real selected window. */
15547 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15548 current_buffer->mode_line_format);
15549 ++n;
15550 }
15551
15552 if (WINDOW_WANTS_HEADER_LINE_P (w))
15553 {
15554 display_mode_line (w, HEADER_LINE_FACE_ID,
15555 current_buffer->header_line_format);
15556 ++n;
15557 }
15558
15559 selected_frame = old_selected_frame;
15560 selected_window = old_selected_window;
15561 return n;
15562 }
15563
15564
15565 /* Display mode or top line of window W. FACE_ID specifies which line
15566 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15567 FORMAT is the mode line format to display. Value is the pixel
15568 height of the mode line displayed. */
15569
15570 static int
15571 display_mode_line (w, face_id, format)
15572 struct window *w;
15573 enum face_id face_id;
15574 Lisp_Object format;
15575 {
15576 struct it it;
15577 struct face *face;
15578
15579 init_iterator (&it, w, -1, -1, NULL, face_id);
15580 prepare_desired_row (it.glyph_row);
15581
15582 it.glyph_row->mode_line_p = 1;
15583
15584 if (! mode_line_inverse_video)
15585 /* Force the mode-line to be displayed in the default face. */
15586 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15587
15588 /* Temporarily make frame's keyboard the current kboard so that
15589 kboard-local variables in the mode_line_format will get the right
15590 values. */
15591 push_frame_kboard (it.f);
15592 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15593 pop_frame_kboard ();
15594
15595 /* Fill up with spaces. */
15596 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15597
15598 compute_line_metrics (&it);
15599 it.glyph_row->full_width_p = 1;
15600 it.glyph_row->continued_p = 0;
15601 it.glyph_row->truncated_on_left_p = 0;
15602 it.glyph_row->truncated_on_right_p = 0;
15603
15604 /* Make a 3D mode-line have a shadow at its right end. */
15605 face = FACE_FROM_ID (it.f, face_id);
15606 extend_face_to_end_of_line (&it);
15607 if (face->box != FACE_NO_BOX)
15608 {
15609 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15610 + it.glyph_row->used[TEXT_AREA] - 1);
15611 last->right_box_line_p = 1;
15612 }
15613
15614 return it.glyph_row->height;
15615 }
15616
15617 /* Alist that caches the results of :propertize.
15618 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15619 Lisp_Object mode_line_proptrans_alist;
15620
15621 /* List of strings making up the mode-line. */
15622 Lisp_Object mode_line_string_list;
15623
15624 /* Base face property when building propertized mode line string. */
15625 static Lisp_Object mode_line_string_face;
15626 static Lisp_Object mode_line_string_face_prop;
15627
15628
15629 /* Contribute ELT to the mode line for window IT->w. How it
15630 translates into text depends on its data type.
15631
15632 IT describes the display environment in which we display, as usual.
15633
15634 DEPTH is the depth in recursion. It is used to prevent
15635 infinite recursion here.
15636
15637 FIELD_WIDTH is the number of characters the display of ELT should
15638 occupy in the mode line, and PRECISION is the maximum number of
15639 characters to display from ELT's representation. See
15640 display_string for details.
15641
15642 Returns the hpos of the end of the text generated by ELT.
15643
15644 PROPS is a property list to add to any string we encounter.
15645
15646 If RISKY is nonzero, remove (disregard) any properties in any string
15647 we encounter, and ignore :eval and :propertize.
15648
15649 If the global variable `frame_title_ptr' is non-NULL, then the output
15650 is passed to `store_frame_title' instead of `display_string'. */
15651
15652 static int
15653 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15654 struct it *it;
15655 int depth;
15656 int field_width, precision;
15657 Lisp_Object elt, props;
15658 int risky;
15659 {
15660 int n = 0, field, prec;
15661 int literal = 0;
15662
15663 tail_recurse:
15664 if (depth > 100)
15665 elt = build_string ("*too-deep*");
15666
15667 depth++;
15668
15669 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15670 {
15671 case Lisp_String:
15672 {
15673 /* A string: output it and check for %-constructs within it. */
15674 unsigned char c;
15675 const unsigned char *this, *lisp_string;
15676
15677 if (!NILP (props) || risky)
15678 {
15679 Lisp_Object oprops, aelt;
15680 oprops = Ftext_properties_at (make_number (0), elt);
15681
15682 /* If the starting string's properties are not what
15683 we want, translate the string. Also, if the string
15684 is risky, do that anyway. */
15685
15686 if (NILP (Fequal (props, oprops)) || risky)
15687 {
15688 /* If the starting string has properties,
15689 merge the specified ones onto the existing ones. */
15690 if (! NILP (oprops) && !risky)
15691 {
15692 Lisp_Object tem;
15693
15694 oprops = Fcopy_sequence (oprops);
15695 tem = props;
15696 while (CONSP (tem))
15697 {
15698 oprops = Fplist_put (oprops, XCAR (tem),
15699 XCAR (XCDR (tem)));
15700 tem = XCDR (XCDR (tem));
15701 }
15702 props = oprops;
15703 }
15704
15705 aelt = Fassoc (elt, mode_line_proptrans_alist);
15706 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15707 {
15708 mode_line_proptrans_alist
15709 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15710 elt = XCAR (aelt);
15711 }
15712 else
15713 {
15714 Lisp_Object tem;
15715
15716 elt = Fcopy_sequence (elt);
15717 Fset_text_properties (make_number (0), Flength (elt),
15718 props, elt);
15719 /* Add this item to mode_line_proptrans_alist. */
15720 mode_line_proptrans_alist
15721 = Fcons (Fcons (elt, props),
15722 mode_line_proptrans_alist);
15723 /* Truncate mode_line_proptrans_alist
15724 to at most 50 elements. */
15725 tem = Fnthcdr (make_number (50),
15726 mode_line_proptrans_alist);
15727 if (! NILP (tem))
15728 XSETCDR (tem, Qnil);
15729 }
15730 }
15731 }
15732
15733 this = SDATA (elt);
15734 lisp_string = this;
15735
15736 if (literal)
15737 {
15738 prec = precision - n;
15739 if (frame_title_ptr)
15740 n += store_frame_title (SDATA (elt), -1, prec);
15741 else if (!NILP (mode_line_string_list))
15742 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15743 else
15744 n += display_string (NULL, elt, Qnil, 0, 0, it,
15745 0, prec, 0, STRING_MULTIBYTE (elt));
15746
15747 break;
15748 }
15749
15750 while ((precision <= 0 || n < precision)
15751 && *this
15752 && (frame_title_ptr
15753 || !NILP (mode_line_string_list)
15754 || it->current_x < it->last_visible_x))
15755 {
15756 const unsigned char *last = this;
15757
15758 /* Advance to end of string or next format specifier. */
15759 while ((c = *this++) != '\0' && c != '%')
15760 ;
15761
15762 if (this - 1 != last)
15763 {
15764 int nchars, nbytes;
15765
15766 /* Output to end of string or up to '%'. Field width
15767 is length of string. Don't output more than
15768 PRECISION allows us. */
15769 --this;
15770
15771 prec = c_string_width (last, this - last, precision - n,
15772 &nchars, &nbytes);
15773
15774 if (frame_title_ptr)
15775 n += store_frame_title (last, 0, prec);
15776 else if (!NILP (mode_line_string_list))
15777 {
15778 int bytepos = last - lisp_string;
15779 int charpos = string_byte_to_char (elt, bytepos);
15780 int endpos = (precision <= 0
15781 ? string_byte_to_char (elt,
15782 this - lisp_string)
15783 : charpos + nchars);
15784
15785 n += store_mode_line_string (NULL,
15786 Fsubstring (elt, make_number (charpos),
15787 make_number (endpos)),
15788 0, 0, 0, Qnil);
15789 }
15790 else
15791 {
15792 int bytepos = last - lisp_string;
15793 int charpos = string_byte_to_char (elt, bytepos);
15794 n += display_string (NULL, elt, Qnil, 0, charpos,
15795 it, 0, prec, 0,
15796 STRING_MULTIBYTE (elt));
15797 }
15798 }
15799 else /* c == '%' */
15800 {
15801 const unsigned char *percent_position = this;
15802
15803 /* Get the specified minimum width. Zero means
15804 don't pad. */
15805 field = 0;
15806 while ((c = *this++) >= '0' && c <= '9')
15807 field = field * 10 + c - '0';
15808
15809 /* Don't pad beyond the total padding allowed. */
15810 if (field_width - n > 0 && field > field_width - n)
15811 field = field_width - n;
15812
15813 /* Note that either PRECISION <= 0 or N < PRECISION. */
15814 prec = precision - n;
15815
15816 if (c == 'M')
15817 n += display_mode_element (it, depth, field, prec,
15818 Vglobal_mode_string, props,
15819 risky);
15820 else if (c != 0)
15821 {
15822 int multibyte;
15823 int bytepos, charpos;
15824 unsigned char *spec;
15825
15826 bytepos = percent_position - lisp_string;
15827 charpos = (STRING_MULTIBYTE (elt)
15828 ? string_byte_to_char (elt, bytepos)
15829 : bytepos);
15830
15831 spec
15832 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15833
15834 if (frame_title_ptr)
15835 n += store_frame_title (spec, field, prec);
15836 else if (!NILP (mode_line_string_list))
15837 {
15838 int len = strlen (spec);
15839 Lisp_Object tem = make_string (spec, len);
15840 props = Ftext_properties_at (make_number (charpos), elt);
15841 /* Should only keep face property in props */
15842 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15843 }
15844 else
15845 {
15846 int nglyphs_before, nwritten;
15847
15848 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15849 nwritten = display_string (spec, Qnil, elt,
15850 charpos, 0, it,
15851 field, prec, 0,
15852 multibyte);
15853
15854 /* Assign to the glyphs written above the
15855 string where the `%x' came from, position
15856 of the `%'. */
15857 if (nwritten > 0)
15858 {
15859 struct glyph *glyph
15860 = (it->glyph_row->glyphs[TEXT_AREA]
15861 + nglyphs_before);
15862 int i;
15863
15864 for (i = 0; i < nwritten; ++i)
15865 {
15866 glyph[i].object = elt;
15867 glyph[i].charpos = charpos;
15868 }
15869
15870 n += nwritten;
15871 }
15872 }
15873 }
15874 else /* c == 0 */
15875 break;
15876 }
15877 }
15878 }
15879 break;
15880
15881 case Lisp_Symbol:
15882 /* A symbol: process the value of the symbol recursively
15883 as if it appeared here directly. Avoid error if symbol void.
15884 Special case: if value of symbol is a string, output the string
15885 literally. */
15886 {
15887 register Lisp_Object tem;
15888
15889 /* If the variable is not marked as risky to set
15890 then its contents are risky to use. */
15891 if (NILP (Fget (elt, Qrisky_local_variable)))
15892 risky = 1;
15893
15894 tem = Fboundp (elt);
15895 if (!NILP (tem))
15896 {
15897 tem = Fsymbol_value (elt);
15898 /* If value is a string, output that string literally:
15899 don't check for % within it. */
15900 if (STRINGP (tem))
15901 literal = 1;
15902
15903 if (!EQ (tem, elt))
15904 {
15905 /* Give up right away for nil or t. */
15906 elt = tem;
15907 goto tail_recurse;
15908 }
15909 }
15910 }
15911 break;
15912
15913 case Lisp_Cons:
15914 {
15915 register Lisp_Object car, tem;
15916
15917 /* A cons cell: five distinct cases.
15918 If first element is :eval or :propertize, do something special.
15919 If first element is a string or a cons, process all the elements
15920 and effectively concatenate them.
15921 If first element is a negative number, truncate displaying cdr to
15922 at most that many characters. If positive, pad (with spaces)
15923 to at least that many characters.
15924 If first element is a symbol, process the cadr or caddr recursively
15925 according to whether the symbol's value is non-nil or nil. */
15926 car = XCAR (elt);
15927 if (EQ (car, QCeval))
15928 {
15929 /* An element of the form (:eval FORM) means evaluate FORM
15930 and use the result as mode line elements. */
15931
15932 if (risky)
15933 break;
15934
15935 if (CONSP (XCDR (elt)))
15936 {
15937 Lisp_Object spec;
15938 spec = safe_eval (XCAR (XCDR (elt)));
15939 n += display_mode_element (it, depth, field_width - n,
15940 precision - n, spec, props,
15941 risky);
15942 }
15943 }
15944 else if (EQ (car, QCpropertize))
15945 {
15946 /* An element of the form (:propertize ELT PROPS...)
15947 means display ELT but applying properties PROPS. */
15948
15949 if (risky)
15950 break;
15951
15952 if (CONSP (XCDR (elt)))
15953 n += display_mode_element (it, depth, field_width - n,
15954 precision - n, XCAR (XCDR (elt)),
15955 XCDR (XCDR (elt)), risky);
15956 }
15957 else if (SYMBOLP (car))
15958 {
15959 tem = Fboundp (car);
15960 elt = XCDR (elt);
15961 if (!CONSP (elt))
15962 goto invalid;
15963 /* elt is now the cdr, and we know it is a cons cell.
15964 Use its car if CAR has a non-nil value. */
15965 if (!NILP (tem))
15966 {
15967 tem = Fsymbol_value (car);
15968 if (!NILP (tem))
15969 {
15970 elt = XCAR (elt);
15971 goto tail_recurse;
15972 }
15973 }
15974 /* Symbol's value is nil (or symbol is unbound)
15975 Get the cddr of the original list
15976 and if possible find the caddr and use that. */
15977 elt = XCDR (elt);
15978 if (NILP (elt))
15979 break;
15980 else if (!CONSP (elt))
15981 goto invalid;
15982 elt = XCAR (elt);
15983 goto tail_recurse;
15984 }
15985 else if (INTEGERP (car))
15986 {
15987 register int lim = XINT (car);
15988 elt = XCDR (elt);
15989 if (lim < 0)
15990 {
15991 /* Negative int means reduce maximum width. */
15992 if (precision <= 0)
15993 precision = -lim;
15994 else
15995 precision = min (precision, -lim);
15996 }
15997 else if (lim > 0)
15998 {
15999 /* Padding specified. Don't let it be more than
16000 current maximum. */
16001 if (precision > 0)
16002 lim = min (precision, lim);
16003
16004 /* If that's more padding than already wanted, queue it.
16005 But don't reduce padding already specified even if
16006 that is beyond the current truncation point. */
16007 field_width = max (lim, field_width);
16008 }
16009 goto tail_recurse;
16010 }
16011 else if (STRINGP (car) || CONSP (car))
16012 {
16013 register int limit = 50;
16014 /* Limit is to protect against circular lists. */
16015 while (CONSP (elt)
16016 && --limit > 0
16017 && (precision <= 0 || n < precision))
16018 {
16019 n += display_mode_element (it, depth, field_width - n,
16020 precision - n, XCAR (elt),
16021 props, risky);
16022 elt = XCDR (elt);
16023 }
16024 }
16025 }
16026 break;
16027
16028 default:
16029 invalid:
16030 elt = build_string ("*invalid*");
16031 goto tail_recurse;
16032 }
16033
16034 /* Pad to FIELD_WIDTH. */
16035 if (field_width > 0 && n < field_width)
16036 {
16037 if (frame_title_ptr)
16038 n += store_frame_title ("", field_width - n, 0);
16039 else if (!NILP (mode_line_string_list))
16040 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
16041 else
16042 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
16043 0, 0, 0);
16044 }
16045
16046 return n;
16047 }
16048
16049 /* Store a mode-line string element in mode_line_string_list.
16050
16051 If STRING is non-null, display that C string. Otherwise, the Lisp
16052 string LISP_STRING is displayed.
16053
16054 FIELD_WIDTH is the minimum number of output glyphs to produce.
16055 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16056 with spaces. FIELD_WIDTH <= 0 means don't pad.
16057
16058 PRECISION is the maximum number of characters to output from
16059 STRING. PRECISION <= 0 means don't truncate the string.
16060
16061 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
16062 properties to the string.
16063
16064 PROPS are the properties to add to the string.
16065 The mode_line_string_face face property is always added to the string.
16066 */
16067
16068 static int
16069 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
16070 char *string;
16071 Lisp_Object lisp_string;
16072 int copy_string;
16073 int field_width;
16074 int precision;
16075 Lisp_Object props;
16076 {
16077 int len;
16078 int n = 0;
16079
16080 if (string != NULL)
16081 {
16082 len = strlen (string);
16083 if (precision > 0 && len > precision)
16084 len = precision;
16085 lisp_string = make_string (string, len);
16086 if (NILP (props))
16087 props = mode_line_string_face_prop;
16088 else if (!NILP (mode_line_string_face))
16089 {
16090 Lisp_Object face = Fplist_get (props, Qface);
16091 props = Fcopy_sequence (props);
16092 if (NILP (face))
16093 face = mode_line_string_face;
16094 else
16095 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16096 props = Fplist_put (props, Qface, face);
16097 }
16098 Fadd_text_properties (make_number (0), make_number (len),
16099 props, lisp_string);
16100 }
16101 else
16102 {
16103 len = XFASTINT (Flength (lisp_string));
16104 if (precision > 0 && len > precision)
16105 {
16106 len = precision;
16107 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
16108 precision = -1;
16109 }
16110 if (!NILP (mode_line_string_face))
16111 {
16112 Lisp_Object face;
16113 if (NILP (props))
16114 props = Ftext_properties_at (make_number (0), lisp_string);
16115 face = Fplist_get (props, Qface);
16116 if (NILP (face))
16117 face = mode_line_string_face;
16118 else
16119 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16120 props = Fcons (Qface, Fcons (face, Qnil));
16121 if (copy_string)
16122 lisp_string = Fcopy_sequence (lisp_string);
16123 }
16124 if (!NILP (props))
16125 Fadd_text_properties (make_number (0), make_number (len),
16126 props, lisp_string);
16127 }
16128
16129 if (len > 0)
16130 {
16131 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16132 n += len;
16133 }
16134
16135 if (field_width > len)
16136 {
16137 field_width -= len;
16138 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
16139 if (!NILP (props))
16140 Fadd_text_properties (make_number (0), make_number (field_width),
16141 props, lisp_string);
16142 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16143 n += field_width;
16144 }
16145
16146 return n;
16147 }
16148
16149
16150 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
16151 1, 4, 0,
16152 doc: /* Format a string out of a mode line format specification.
16153 First arg FORMAT specifies the mode line format (see `mode-line-format'
16154 for details) to use.
16155
16156 Optional second arg FACE specifies the face property to put
16157 on all characters for which no face is specified.
16158 t means whatever face the window's mode line currently uses
16159 \(either `mode-line' or `mode-line-inactive', depending).
16160 nil means the default is no face property.
16161 If FACE is an integer, the value string has no text properties.
16162
16163 Optional third and fourth args WINDOW and BUFFER specify the window
16164 and buffer to use as the context for the formatting (defaults
16165 are the selected window and the window's buffer). */)
16166 (format, face, window, buffer)
16167 Lisp_Object format, face, window, buffer;
16168 {
16169 struct it it;
16170 int len;
16171 struct window *w;
16172 struct buffer *old_buffer = NULL;
16173 int face_id = -1;
16174 int no_props = INTEGERP (face);
16175
16176 if (NILP (window))
16177 window = selected_window;
16178 CHECK_WINDOW (window);
16179 w = XWINDOW (window);
16180
16181 if (NILP (buffer))
16182 buffer = w->buffer;
16183 CHECK_BUFFER (buffer);
16184
16185 if (NILP (format))
16186 return build_string ("");
16187
16188 if (no_props)
16189 face = Qnil;
16190
16191 if (!NILP (face))
16192 {
16193 if (EQ (face, Qt))
16194 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
16195 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
16196 }
16197
16198 if (face_id < 0)
16199 face_id = DEFAULT_FACE_ID;
16200
16201 if (XBUFFER (buffer) != current_buffer)
16202 {
16203 old_buffer = current_buffer;
16204 set_buffer_internal_1 (XBUFFER (buffer));
16205 }
16206
16207 init_iterator (&it, w, -1, -1, NULL, face_id);
16208
16209 if (!no_props)
16210 {
16211 mode_line_string_face = face;
16212 mode_line_string_face_prop
16213 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
16214
16215 /* We need a dummy last element in mode_line_string_list to
16216 indicate we are building the propertized mode-line string.
16217 Using mode_line_string_face_prop here GC protects it. */
16218 mode_line_string_list
16219 = Fcons (mode_line_string_face_prop, Qnil);
16220 frame_title_ptr = NULL;
16221 }
16222 else
16223 {
16224 mode_line_string_face_prop = Qnil;
16225 mode_line_string_list = Qnil;
16226 frame_title_ptr = frame_title_buf;
16227 }
16228
16229 push_frame_kboard (it.f);
16230 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16231 pop_frame_kboard ();
16232
16233 if (old_buffer)
16234 set_buffer_internal_1 (old_buffer);
16235
16236 if (!no_props)
16237 {
16238 Lisp_Object str;
16239 mode_line_string_list = Fnreverse (mode_line_string_list);
16240 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
16241 make_string ("", 0));
16242 mode_line_string_face_prop = Qnil;
16243 mode_line_string_list = Qnil;
16244 return str;
16245 }
16246
16247 len = frame_title_ptr - frame_title_buf;
16248 if (len > 0 && frame_title_ptr[-1] == '-')
16249 {
16250 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
16251 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
16252 ;
16253 frame_title_ptr += 3; /* restore last non-dash + two dashes */
16254 if (len > frame_title_ptr - frame_title_buf)
16255 len = frame_title_ptr - frame_title_buf;
16256 }
16257
16258 frame_title_ptr = NULL;
16259 return make_string (frame_title_buf, len);
16260 }
16261
16262 /* Write a null-terminated, right justified decimal representation of
16263 the positive integer D to BUF using a minimal field width WIDTH. */
16264
16265 static void
16266 pint2str (buf, width, d)
16267 register char *buf;
16268 register int width;
16269 register int d;
16270 {
16271 register char *p = buf;
16272
16273 if (d <= 0)
16274 *p++ = '0';
16275 else
16276 {
16277 while (d > 0)
16278 {
16279 *p++ = d % 10 + '0';
16280 d /= 10;
16281 }
16282 }
16283
16284 for (width -= (int) (p - buf); width > 0; --width)
16285 *p++ = ' ';
16286 *p-- = '\0';
16287 while (p > buf)
16288 {
16289 d = *buf;
16290 *buf++ = *p;
16291 *p-- = d;
16292 }
16293 }
16294
16295 /* Write a null-terminated, right justified decimal and "human
16296 readable" representation of the nonnegative integer D to BUF using
16297 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16298
16299 static const char power_letter[] =
16300 {
16301 0, /* not used */
16302 'k', /* kilo */
16303 'M', /* mega */
16304 'G', /* giga */
16305 'T', /* tera */
16306 'P', /* peta */
16307 'E', /* exa */
16308 'Z', /* zetta */
16309 'Y' /* yotta */
16310 };
16311
16312 static void
16313 pint2hrstr (buf, width, d)
16314 char *buf;
16315 int width;
16316 int d;
16317 {
16318 /* We aim to represent the nonnegative integer D as
16319 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16320 int quotient = d;
16321 int remainder = 0;
16322 /* -1 means: do not use TENTHS. */
16323 int tenths = -1;
16324 int exponent = 0;
16325
16326 /* Length of QUOTIENT.TENTHS as a string. */
16327 int length;
16328
16329 char * psuffix;
16330 char * p;
16331
16332 if (1000 <= quotient)
16333 {
16334 /* Scale to the appropriate EXPONENT. */
16335 do
16336 {
16337 remainder = quotient % 1000;
16338 quotient /= 1000;
16339 exponent++;
16340 }
16341 while (1000 <= quotient);
16342
16343 /* Round to nearest and decide whether to use TENTHS or not. */
16344 if (quotient <= 9)
16345 {
16346 tenths = remainder / 100;
16347 if (50 <= remainder % 100)
16348 {
16349 if (tenths < 9)
16350 tenths++;
16351 else
16352 {
16353 quotient++;
16354 if (quotient == 10)
16355 tenths = -1;
16356 else
16357 tenths = 0;
16358 }
16359 }
16360 }
16361 else
16362 if (500 <= remainder)
16363 {
16364 if (quotient < 999)
16365 quotient++;
16366 else
16367 {
16368 quotient = 1;
16369 exponent++;
16370 tenths = 0;
16371 }
16372 }
16373 }
16374
16375 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16376 if (tenths == -1 && quotient <= 99)
16377 if (quotient <= 9)
16378 length = 1;
16379 else
16380 length = 2;
16381 else
16382 length = 3;
16383 p = psuffix = buf + max (width, length);
16384
16385 /* Print EXPONENT. */
16386 if (exponent)
16387 *psuffix++ = power_letter[exponent];
16388 *psuffix = '\0';
16389
16390 /* Print TENTHS. */
16391 if (tenths >= 0)
16392 {
16393 *--p = '0' + tenths;
16394 *--p = '.';
16395 }
16396
16397 /* Print QUOTIENT. */
16398 do
16399 {
16400 int digit = quotient % 10;
16401 *--p = '0' + digit;
16402 }
16403 while ((quotient /= 10) != 0);
16404
16405 /* Print leading spaces. */
16406 while (buf < p)
16407 *--p = ' ';
16408 }
16409
16410 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16411 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16412 type of CODING_SYSTEM. Return updated pointer into BUF. */
16413
16414 static unsigned char invalid_eol_type[] = "(*invalid*)";
16415
16416 static char *
16417 decode_mode_spec_coding (coding_system, buf, eol_flag)
16418 Lisp_Object coding_system;
16419 register char *buf;
16420 int eol_flag;
16421 {
16422 Lisp_Object val;
16423 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16424 const unsigned char *eol_str;
16425 int eol_str_len;
16426 /* The EOL conversion we are using. */
16427 Lisp_Object eoltype;
16428
16429 val = Fget (coding_system, Qcoding_system);
16430 eoltype = Qnil;
16431
16432 if (!VECTORP (val)) /* Not yet decided. */
16433 {
16434 if (multibyte)
16435 *buf++ = '-';
16436 if (eol_flag)
16437 eoltype = eol_mnemonic_undecided;
16438 /* Don't mention EOL conversion if it isn't decided. */
16439 }
16440 else
16441 {
16442 Lisp_Object eolvalue;
16443
16444 eolvalue = Fget (coding_system, Qeol_type);
16445
16446 if (multibyte)
16447 *buf++ = XFASTINT (AREF (val, 1));
16448
16449 if (eol_flag)
16450 {
16451 /* The EOL conversion that is normal on this system. */
16452
16453 if (NILP (eolvalue)) /* Not yet decided. */
16454 eoltype = eol_mnemonic_undecided;
16455 else if (VECTORP (eolvalue)) /* Not yet decided. */
16456 eoltype = eol_mnemonic_undecided;
16457 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16458 eoltype = (XFASTINT (eolvalue) == 0
16459 ? eol_mnemonic_unix
16460 : (XFASTINT (eolvalue) == 1
16461 ? eol_mnemonic_dos : eol_mnemonic_mac));
16462 }
16463 }
16464
16465 if (eol_flag)
16466 {
16467 /* Mention the EOL conversion if it is not the usual one. */
16468 if (STRINGP (eoltype))
16469 {
16470 eol_str = SDATA (eoltype);
16471 eol_str_len = SBYTES (eoltype);
16472 }
16473 else if (INTEGERP (eoltype)
16474 && CHAR_VALID_P (XINT (eoltype), 0))
16475 {
16476 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16477 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16478 eol_str = tmp;
16479 }
16480 else
16481 {
16482 eol_str = invalid_eol_type;
16483 eol_str_len = sizeof (invalid_eol_type) - 1;
16484 }
16485 bcopy (eol_str, buf, eol_str_len);
16486 buf += eol_str_len;
16487 }
16488
16489 return buf;
16490 }
16491
16492 /* Return a string for the output of a mode line %-spec for window W,
16493 generated by character C. PRECISION >= 0 means don't return a
16494 string longer than that value. FIELD_WIDTH > 0 means pad the
16495 string returned with spaces to that value. Return 1 in *MULTIBYTE
16496 if the result is multibyte text.
16497
16498 Note we operate on the current buffer for most purposes,
16499 the exception being w->base_line_pos. */
16500
16501 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16502
16503 static char *
16504 decode_mode_spec (w, c, field_width, precision, multibyte)
16505 struct window *w;
16506 register int c;
16507 int field_width, precision;
16508 int *multibyte;
16509 {
16510 Lisp_Object obj;
16511 struct frame *f = XFRAME (WINDOW_FRAME (w));
16512 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16513 struct buffer *b = current_buffer;
16514
16515 obj = Qnil;
16516 *multibyte = 0;
16517
16518 switch (c)
16519 {
16520 case '*':
16521 if (!NILP (b->read_only))
16522 return "%";
16523 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16524 return "*";
16525 return "-";
16526
16527 case '+':
16528 /* This differs from %* only for a modified read-only buffer. */
16529 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16530 return "*";
16531 if (!NILP (b->read_only))
16532 return "%";
16533 return "-";
16534
16535 case '&':
16536 /* This differs from %* in ignoring read-only-ness. */
16537 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16538 return "*";
16539 return "-";
16540
16541 case '%':
16542 return "%";
16543
16544 case '[':
16545 {
16546 int i;
16547 char *p;
16548
16549 if (command_loop_level > 5)
16550 return "[[[... ";
16551 p = decode_mode_spec_buf;
16552 for (i = 0; i < command_loop_level; i++)
16553 *p++ = '[';
16554 *p = 0;
16555 return decode_mode_spec_buf;
16556 }
16557
16558 case ']':
16559 {
16560 int i;
16561 char *p;
16562
16563 if (command_loop_level > 5)
16564 return " ...]]]";
16565 p = decode_mode_spec_buf;
16566 for (i = 0; i < command_loop_level; i++)
16567 *p++ = ']';
16568 *p = 0;
16569 return decode_mode_spec_buf;
16570 }
16571
16572 case '-':
16573 {
16574 register int i;
16575
16576 /* Let lots_of_dashes be a string of infinite length. */
16577 if (!NILP (mode_line_string_list))
16578 return "--";
16579 if (field_width <= 0
16580 || field_width > sizeof (lots_of_dashes))
16581 {
16582 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16583 decode_mode_spec_buf[i] = '-';
16584 decode_mode_spec_buf[i] = '\0';
16585 return decode_mode_spec_buf;
16586 }
16587 else
16588 return lots_of_dashes;
16589 }
16590
16591 case 'b':
16592 obj = b->name;
16593 break;
16594
16595 case 'c':
16596 {
16597 int col = (int) current_column (); /* iftc */
16598 w->column_number_displayed = make_number (col);
16599 pint2str (decode_mode_spec_buf, field_width, col);
16600 return decode_mode_spec_buf;
16601 }
16602
16603 case 'F':
16604 /* %F displays the frame name. */
16605 if (!NILP (f->title))
16606 return (char *) SDATA (f->title);
16607 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16608 return (char *) SDATA (f->name);
16609 return "Emacs";
16610
16611 case 'f':
16612 obj = b->filename;
16613 break;
16614
16615 case 'i':
16616 {
16617 int size = ZV - BEGV;
16618 pint2str (decode_mode_spec_buf, field_width, size);
16619 return decode_mode_spec_buf;
16620 }
16621
16622 case 'I':
16623 {
16624 int size = ZV - BEGV;
16625 pint2hrstr (decode_mode_spec_buf, field_width, size);
16626 return decode_mode_spec_buf;
16627 }
16628
16629 case 'l':
16630 {
16631 int startpos = XMARKER (w->start)->charpos;
16632 int startpos_byte = marker_byte_position (w->start);
16633 int line, linepos, linepos_byte, topline;
16634 int nlines, junk;
16635 int height = WINDOW_TOTAL_LINES (w);
16636
16637 /* If we decided that this buffer isn't suitable for line numbers,
16638 don't forget that too fast. */
16639 if (EQ (w->base_line_pos, w->buffer))
16640 goto no_value;
16641 /* But do forget it, if the window shows a different buffer now. */
16642 else if (BUFFERP (w->base_line_pos))
16643 w->base_line_pos = Qnil;
16644
16645 /* If the buffer is very big, don't waste time. */
16646 if (INTEGERP (Vline_number_display_limit)
16647 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16648 {
16649 w->base_line_pos = Qnil;
16650 w->base_line_number = Qnil;
16651 goto no_value;
16652 }
16653
16654 if (!NILP (w->base_line_number)
16655 && !NILP (w->base_line_pos)
16656 && XFASTINT (w->base_line_pos) <= startpos)
16657 {
16658 line = XFASTINT (w->base_line_number);
16659 linepos = XFASTINT (w->base_line_pos);
16660 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16661 }
16662 else
16663 {
16664 line = 1;
16665 linepos = BUF_BEGV (b);
16666 linepos_byte = BUF_BEGV_BYTE (b);
16667 }
16668
16669 /* Count lines from base line to window start position. */
16670 nlines = display_count_lines (linepos, linepos_byte,
16671 startpos_byte,
16672 startpos, &junk);
16673
16674 topline = nlines + line;
16675
16676 /* Determine a new base line, if the old one is too close
16677 or too far away, or if we did not have one.
16678 "Too close" means it's plausible a scroll-down would
16679 go back past it. */
16680 if (startpos == BUF_BEGV (b))
16681 {
16682 w->base_line_number = make_number (topline);
16683 w->base_line_pos = make_number (BUF_BEGV (b));
16684 }
16685 else if (nlines < height + 25 || nlines > height * 3 + 50
16686 || linepos == BUF_BEGV (b))
16687 {
16688 int limit = BUF_BEGV (b);
16689 int limit_byte = BUF_BEGV_BYTE (b);
16690 int position;
16691 int distance = (height * 2 + 30) * line_number_display_limit_width;
16692
16693 if (startpos - distance > limit)
16694 {
16695 limit = startpos - distance;
16696 limit_byte = CHAR_TO_BYTE (limit);
16697 }
16698
16699 nlines = display_count_lines (startpos, startpos_byte,
16700 limit_byte,
16701 - (height * 2 + 30),
16702 &position);
16703 /* If we couldn't find the lines we wanted within
16704 line_number_display_limit_width chars per line,
16705 give up on line numbers for this window. */
16706 if (position == limit_byte && limit == startpos - distance)
16707 {
16708 w->base_line_pos = w->buffer;
16709 w->base_line_number = Qnil;
16710 goto no_value;
16711 }
16712
16713 w->base_line_number = make_number (topline - nlines);
16714 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16715 }
16716
16717 /* Now count lines from the start pos to point. */
16718 nlines = display_count_lines (startpos, startpos_byte,
16719 PT_BYTE, PT, &junk);
16720
16721 /* Record that we did display the line number. */
16722 line_number_displayed = 1;
16723
16724 /* Make the string to show. */
16725 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16726 return decode_mode_spec_buf;
16727 no_value:
16728 {
16729 char* p = decode_mode_spec_buf;
16730 int pad = field_width - 2;
16731 while (pad-- > 0)
16732 *p++ = ' ';
16733 *p++ = '?';
16734 *p++ = '?';
16735 *p = '\0';
16736 return decode_mode_spec_buf;
16737 }
16738 }
16739 break;
16740
16741 case 'm':
16742 obj = b->mode_name;
16743 break;
16744
16745 case 'n':
16746 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16747 return " Narrow";
16748 break;
16749
16750 case 'p':
16751 {
16752 int pos = marker_position (w->start);
16753 int total = BUF_ZV (b) - BUF_BEGV (b);
16754
16755 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16756 {
16757 if (pos <= BUF_BEGV (b))
16758 return "All";
16759 else
16760 return "Bottom";
16761 }
16762 else if (pos <= BUF_BEGV (b))
16763 return "Top";
16764 else
16765 {
16766 if (total > 1000000)
16767 /* Do it differently for a large value, to avoid overflow. */
16768 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16769 else
16770 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16771 /* We can't normally display a 3-digit number,
16772 so get us a 2-digit number that is close. */
16773 if (total == 100)
16774 total = 99;
16775 sprintf (decode_mode_spec_buf, "%2d%%", total);
16776 return decode_mode_spec_buf;
16777 }
16778 }
16779
16780 /* Display percentage of size above the bottom of the screen. */
16781 case 'P':
16782 {
16783 int toppos = marker_position (w->start);
16784 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16785 int total = BUF_ZV (b) - BUF_BEGV (b);
16786
16787 if (botpos >= BUF_ZV (b))
16788 {
16789 if (toppos <= BUF_BEGV (b))
16790 return "All";
16791 else
16792 return "Bottom";
16793 }
16794 else
16795 {
16796 if (total > 1000000)
16797 /* Do it differently for a large value, to avoid overflow. */
16798 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16799 else
16800 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16801 /* We can't normally display a 3-digit number,
16802 so get us a 2-digit number that is close. */
16803 if (total == 100)
16804 total = 99;
16805 if (toppos <= BUF_BEGV (b))
16806 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16807 else
16808 sprintf (decode_mode_spec_buf, "%2d%%", total);
16809 return decode_mode_spec_buf;
16810 }
16811 }
16812
16813 case 's':
16814 /* status of process */
16815 obj = Fget_buffer_process (Fcurrent_buffer ());
16816 if (NILP (obj))
16817 return "no process";
16818 #ifdef subprocesses
16819 obj = Fsymbol_name (Fprocess_status (obj));
16820 #endif
16821 break;
16822
16823 case 't': /* indicate TEXT or BINARY */
16824 #ifdef MODE_LINE_BINARY_TEXT
16825 return MODE_LINE_BINARY_TEXT (b);
16826 #else
16827 return "T";
16828 #endif
16829
16830 case 'z':
16831 /* coding-system (not including end-of-line format) */
16832 case 'Z':
16833 /* coding-system (including end-of-line type) */
16834 {
16835 int eol_flag = (c == 'Z');
16836 char *p = decode_mode_spec_buf;
16837
16838 if (! FRAME_WINDOW_P (f))
16839 {
16840 /* No need to mention EOL here--the terminal never needs
16841 to do EOL conversion. */
16842 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16843 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16844 }
16845 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16846 p, eol_flag);
16847
16848 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16849 #ifdef subprocesses
16850 obj = Fget_buffer_process (Fcurrent_buffer ());
16851 if (PROCESSP (obj))
16852 {
16853 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16854 p, eol_flag);
16855 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16856 p, eol_flag);
16857 }
16858 #endif /* subprocesses */
16859 #endif /* 0 */
16860 *p = 0;
16861 return decode_mode_spec_buf;
16862 }
16863 }
16864
16865 if (STRINGP (obj))
16866 {
16867 *multibyte = STRING_MULTIBYTE (obj);
16868 return (char *) SDATA (obj);
16869 }
16870 else
16871 return "";
16872 }
16873
16874
16875 /* Count up to COUNT lines starting from START / START_BYTE.
16876 But don't go beyond LIMIT_BYTE.
16877 Return the number of lines thus found (always nonnegative).
16878
16879 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16880
16881 static int
16882 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16883 int start, start_byte, limit_byte, count;
16884 int *byte_pos_ptr;
16885 {
16886 register unsigned char *cursor;
16887 unsigned char *base;
16888
16889 register int ceiling;
16890 register unsigned char *ceiling_addr;
16891 int orig_count = count;
16892
16893 /* If we are not in selective display mode,
16894 check only for newlines. */
16895 int selective_display = (!NILP (current_buffer->selective_display)
16896 && !INTEGERP (current_buffer->selective_display));
16897
16898 if (count > 0)
16899 {
16900 while (start_byte < limit_byte)
16901 {
16902 ceiling = BUFFER_CEILING_OF (start_byte);
16903 ceiling = min (limit_byte - 1, ceiling);
16904 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16905 base = (cursor = BYTE_POS_ADDR (start_byte));
16906 while (1)
16907 {
16908 if (selective_display)
16909 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16910 ;
16911 else
16912 while (*cursor != '\n' && ++cursor != ceiling_addr)
16913 ;
16914
16915 if (cursor != ceiling_addr)
16916 {
16917 if (--count == 0)
16918 {
16919 start_byte += cursor - base + 1;
16920 *byte_pos_ptr = start_byte;
16921 return orig_count;
16922 }
16923 else
16924 if (++cursor == ceiling_addr)
16925 break;
16926 }
16927 else
16928 break;
16929 }
16930 start_byte += cursor - base;
16931 }
16932 }
16933 else
16934 {
16935 while (start_byte > limit_byte)
16936 {
16937 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16938 ceiling = max (limit_byte, ceiling);
16939 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16940 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16941 while (1)
16942 {
16943 if (selective_display)
16944 while (--cursor != ceiling_addr
16945 && *cursor != '\n' && *cursor != 015)
16946 ;
16947 else
16948 while (--cursor != ceiling_addr && *cursor != '\n')
16949 ;
16950
16951 if (cursor != ceiling_addr)
16952 {
16953 if (++count == 0)
16954 {
16955 start_byte += cursor - base + 1;
16956 *byte_pos_ptr = start_byte;
16957 /* When scanning backwards, we should
16958 not count the newline posterior to which we stop. */
16959 return - orig_count - 1;
16960 }
16961 }
16962 else
16963 break;
16964 }
16965 /* Here we add 1 to compensate for the last decrement
16966 of CURSOR, which took it past the valid range. */
16967 start_byte += cursor - base + 1;
16968 }
16969 }
16970
16971 *byte_pos_ptr = limit_byte;
16972
16973 if (count < 0)
16974 return - orig_count + count;
16975 return orig_count - count;
16976
16977 }
16978
16979
16980 \f
16981 /***********************************************************************
16982 Displaying strings
16983 ***********************************************************************/
16984
16985 /* Display a NUL-terminated string, starting with index START.
16986
16987 If STRING is non-null, display that C string. Otherwise, the Lisp
16988 string LISP_STRING is displayed.
16989
16990 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16991 FACE_STRING. Display STRING or LISP_STRING with the face at
16992 FACE_STRING_POS in FACE_STRING:
16993
16994 Display the string in the environment given by IT, but use the
16995 standard display table, temporarily.
16996
16997 FIELD_WIDTH is the minimum number of output glyphs to produce.
16998 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16999 with spaces. If STRING has more characters, more than FIELD_WIDTH
17000 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
17001
17002 PRECISION is the maximum number of characters to output from
17003 STRING. PRECISION < 0 means don't truncate the string.
17004
17005 This is roughly equivalent to printf format specifiers:
17006
17007 FIELD_WIDTH PRECISION PRINTF
17008 ----------------------------------------
17009 -1 -1 %s
17010 -1 10 %.10s
17011 10 -1 %10s
17012 20 10 %20.10s
17013
17014 MULTIBYTE zero means do not display multibyte chars, > 0 means do
17015 display them, and < 0 means obey the current buffer's value of
17016 enable_multibyte_characters.
17017
17018 Value is the number of glyphs produced. */
17019
17020 static int
17021 display_string (string, lisp_string, face_string, face_string_pos,
17022 start, it, field_width, precision, max_x, multibyte)
17023 unsigned char *string;
17024 Lisp_Object lisp_string;
17025 Lisp_Object face_string;
17026 int face_string_pos;
17027 int start;
17028 struct it *it;
17029 int field_width, precision, max_x;
17030 int multibyte;
17031 {
17032 int hpos_at_start = it->hpos;
17033 int saved_face_id = it->face_id;
17034 struct glyph_row *row = it->glyph_row;
17035
17036 /* Initialize the iterator IT for iteration over STRING beginning
17037 with index START. */
17038 reseat_to_string (it, string, lisp_string, start,
17039 precision, field_width, multibyte);
17040
17041 /* If displaying STRING, set up the face of the iterator
17042 from LISP_STRING, if that's given. */
17043 if (STRINGP (face_string))
17044 {
17045 int endptr;
17046 struct face *face;
17047
17048 it->face_id
17049 = face_at_string_position (it->w, face_string, face_string_pos,
17050 0, it->region_beg_charpos,
17051 it->region_end_charpos,
17052 &endptr, it->base_face_id, 0);
17053 face = FACE_FROM_ID (it->f, it->face_id);
17054 it->face_box_p = face->box != FACE_NO_BOX;
17055 }
17056
17057 /* Set max_x to the maximum allowed X position. Don't let it go
17058 beyond the right edge of the window. */
17059 if (max_x <= 0)
17060 max_x = it->last_visible_x;
17061 else
17062 max_x = min (max_x, it->last_visible_x);
17063
17064 /* Skip over display elements that are not visible. because IT->w is
17065 hscrolled. */
17066 if (it->current_x < it->first_visible_x)
17067 move_it_in_display_line_to (it, 100000, it->first_visible_x,
17068 MOVE_TO_POS | MOVE_TO_X);
17069
17070 row->ascent = it->max_ascent;
17071 row->height = it->max_ascent + it->max_descent;
17072 row->phys_ascent = it->max_phys_ascent;
17073 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17074 row->extra_line_spacing = it->max_extra_line_spacing;
17075
17076 /* This condition is for the case that we are called with current_x
17077 past last_visible_x. */
17078 while (it->current_x < max_x)
17079 {
17080 int x_before, x, n_glyphs_before, i, nglyphs;
17081
17082 /* Get the next display element. */
17083 if (!get_next_display_element (it))
17084 break;
17085
17086 /* Produce glyphs. */
17087 x_before = it->current_x;
17088 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
17089 PRODUCE_GLYPHS (it);
17090
17091 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
17092 i = 0;
17093 x = x_before;
17094 while (i < nglyphs)
17095 {
17096 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17097
17098 if (!it->truncate_lines_p
17099 && x + glyph->pixel_width > max_x)
17100 {
17101 /* End of continued line or max_x reached. */
17102 if (CHAR_GLYPH_PADDING_P (*glyph))
17103 {
17104 /* A wide character is unbreakable. */
17105 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
17106 it->current_x = x_before;
17107 }
17108 else
17109 {
17110 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
17111 it->current_x = x;
17112 }
17113 break;
17114 }
17115 else if (x + glyph->pixel_width > it->first_visible_x)
17116 {
17117 /* Glyph is at least partially visible. */
17118 ++it->hpos;
17119 if (x < it->first_visible_x)
17120 it->glyph_row->x = x - it->first_visible_x;
17121 }
17122 else
17123 {
17124 /* Glyph is off the left margin of the display area.
17125 Should not happen. */
17126 abort ();
17127 }
17128
17129 row->ascent = max (row->ascent, it->max_ascent);
17130 row->height = max (row->height, it->max_ascent + it->max_descent);
17131 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17132 row->phys_height = max (row->phys_height,
17133 it->max_phys_ascent + it->max_phys_descent);
17134 row->extra_line_spacing = max (row->extra_line_spacing,
17135 it->max_extra_line_spacing);
17136 x += glyph->pixel_width;
17137 ++i;
17138 }
17139
17140 /* Stop if max_x reached. */
17141 if (i < nglyphs)
17142 break;
17143
17144 /* Stop at line ends. */
17145 if (ITERATOR_AT_END_OF_LINE_P (it))
17146 {
17147 it->continuation_lines_width = 0;
17148 break;
17149 }
17150
17151 set_iterator_to_next (it, 1);
17152
17153 /* Stop if truncating at the right edge. */
17154 if (it->truncate_lines_p
17155 && it->current_x >= it->last_visible_x)
17156 {
17157 /* Add truncation mark, but don't do it if the line is
17158 truncated at a padding space. */
17159 if (IT_CHARPOS (*it) < it->string_nchars)
17160 {
17161 if (!FRAME_WINDOW_P (it->f))
17162 {
17163 int i, n;
17164
17165 if (it->current_x > it->last_visible_x)
17166 {
17167 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17168 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17169 break;
17170 for (n = row->used[TEXT_AREA]; i < n; ++i)
17171 {
17172 row->used[TEXT_AREA] = i;
17173 produce_special_glyphs (it, IT_TRUNCATION);
17174 }
17175 }
17176 produce_special_glyphs (it, IT_TRUNCATION);
17177 }
17178 it->glyph_row->truncated_on_right_p = 1;
17179 }
17180 break;
17181 }
17182 }
17183
17184 /* Maybe insert a truncation at the left. */
17185 if (it->first_visible_x
17186 && IT_CHARPOS (*it) > 0)
17187 {
17188 if (!FRAME_WINDOW_P (it->f))
17189 insert_left_trunc_glyphs (it);
17190 it->glyph_row->truncated_on_left_p = 1;
17191 }
17192
17193 it->face_id = saved_face_id;
17194
17195 /* Value is number of columns displayed. */
17196 return it->hpos - hpos_at_start;
17197 }
17198
17199
17200 \f
17201 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
17202 appears as an element of LIST or as the car of an element of LIST.
17203 If PROPVAL is a list, compare each element against LIST in that
17204 way, and return 1/2 if any element of PROPVAL is found in LIST.
17205 Otherwise return 0. This function cannot quit.
17206 The return value is 2 if the text is invisible but with an ellipsis
17207 and 1 if it's invisible and without an ellipsis. */
17208
17209 int
17210 invisible_p (propval, list)
17211 register Lisp_Object propval;
17212 Lisp_Object list;
17213 {
17214 register Lisp_Object tail, proptail;
17215
17216 for (tail = list; CONSP (tail); tail = XCDR (tail))
17217 {
17218 register Lisp_Object tem;
17219 tem = XCAR (tail);
17220 if (EQ (propval, tem))
17221 return 1;
17222 if (CONSP (tem) && EQ (propval, XCAR (tem)))
17223 return NILP (XCDR (tem)) ? 1 : 2;
17224 }
17225
17226 if (CONSP (propval))
17227 {
17228 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
17229 {
17230 Lisp_Object propelt;
17231 propelt = XCAR (proptail);
17232 for (tail = list; CONSP (tail); tail = XCDR (tail))
17233 {
17234 register Lisp_Object tem;
17235 tem = XCAR (tail);
17236 if (EQ (propelt, tem))
17237 return 1;
17238 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
17239 return NILP (XCDR (tem)) ? 1 : 2;
17240 }
17241 }
17242 }
17243
17244 return 0;
17245 }
17246
17247 /* Calculate a width or height in pixels from a specification using
17248 the following elements:
17249
17250 SPEC ::=
17251 NUM - a (fractional) multiple of the default font width/height
17252 (NUM) - specifies exactly NUM pixels
17253 UNIT - a fixed number of pixels, see below.
17254 ELEMENT - size of a display element in pixels, see below.
17255 (NUM . SPEC) - equals NUM * SPEC
17256 (+ SPEC SPEC ...) - add pixel values
17257 (- SPEC SPEC ...) - subtract pixel values
17258 (- SPEC) - negate pixel value
17259
17260 NUM ::=
17261 INT or FLOAT - a number constant
17262 SYMBOL - use symbol's (buffer local) variable binding.
17263
17264 UNIT ::=
17265 in - pixels per inch *)
17266 mm - pixels per 1/1000 meter *)
17267 cm - pixels per 1/100 meter *)
17268 width - width of current font in pixels.
17269 height - height of current font in pixels.
17270
17271 *) using the ratio(s) defined in display-pixels-per-inch.
17272
17273 ELEMENT ::=
17274
17275 left-fringe - left fringe width in pixels
17276 right-fringe - right fringe width in pixels
17277
17278 left-margin - left margin width in pixels
17279 right-margin - right margin width in pixels
17280
17281 scroll-bar - scroll-bar area width in pixels
17282
17283 Examples:
17284
17285 Pixels corresponding to 5 inches:
17286 (5 . in)
17287
17288 Total width of non-text areas on left side of window (if scroll-bar is on left):
17289 '(space :width (+ left-fringe left-margin scroll-bar))
17290
17291 Align to first text column (in header line):
17292 '(space :align-to 0)
17293
17294 Align to middle of text area minus half the width of variable `my-image'
17295 containing a loaded image:
17296 '(space :align-to (0.5 . (- text my-image)))
17297
17298 Width of left margin minus width of 1 character in the default font:
17299 '(space :width (- left-margin 1))
17300
17301 Width of left margin minus width of 2 characters in the current font:
17302 '(space :width (- left-margin (2 . width)))
17303
17304 Center 1 character over left-margin (in header line):
17305 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17306
17307 Different ways to express width of left fringe plus left margin minus one pixel:
17308 '(space :width (- (+ left-fringe left-margin) (1)))
17309 '(space :width (+ left-fringe left-margin (- (1))))
17310 '(space :width (+ left-fringe left-margin (-1)))
17311
17312 */
17313
17314 #define NUMVAL(X) \
17315 ((INTEGERP (X) || FLOATP (X)) \
17316 ? XFLOATINT (X) \
17317 : - 1)
17318
17319 int
17320 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
17321 double *res;
17322 struct it *it;
17323 Lisp_Object prop;
17324 void *font;
17325 int width_p, *align_to;
17326 {
17327 double pixels;
17328
17329 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17330 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17331
17332 if (NILP (prop))
17333 return OK_PIXELS (0);
17334
17335 if (SYMBOLP (prop))
17336 {
17337 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17338 {
17339 char *unit = SDATA (SYMBOL_NAME (prop));
17340
17341 if (unit[0] == 'i' && unit[1] == 'n')
17342 pixels = 1.0;
17343 else if (unit[0] == 'm' && unit[1] == 'm')
17344 pixels = 25.4;
17345 else if (unit[0] == 'c' && unit[1] == 'm')
17346 pixels = 2.54;
17347 else
17348 pixels = 0;
17349 if (pixels > 0)
17350 {
17351 double ppi;
17352 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17353 || (CONSP (Vdisplay_pixels_per_inch)
17354 && (ppi = (width_p
17355 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17356 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17357 ppi > 0)))
17358 return OK_PIXELS (ppi / pixels);
17359
17360 return 0;
17361 }
17362 }
17363
17364 #ifdef HAVE_WINDOW_SYSTEM
17365 if (EQ (prop, Qheight))
17366 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17367 if (EQ (prop, Qwidth))
17368 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17369 #else
17370 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17371 return OK_PIXELS (1);
17372 #endif
17373
17374 if (EQ (prop, Qtext))
17375 return OK_PIXELS (width_p
17376 ? window_box_width (it->w, TEXT_AREA)
17377 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17378
17379 if (align_to && *align_to < 0)
17380 {
17381 *res = 0;
17382 if (EQ (prop, Qleft))
17383 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17384 if (EQ (prop, Qright))
17385 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17386 if (EQ (prop, Qcenter))
17387 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17388 + window_box_width (it->w, TEXT_AREA) / 2);
17389 if (EQ (prop, Qleft_fringe))
17390 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17391 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17392 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17393 if (EQ (prop, Qright_fringe))
17394 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17395 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17396 : window_box_right_offset (it->w, TEXT_AREA));
17397 if (EQ (prop, Qleft_margin))
17398 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17399 if (EQ (prop, Qright_margin))
17400 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17401 if (EQ (prop, Qscroll_bar))
17402 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17403 ? 0
17404 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17405 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17406 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17407 : 0)));
17408 }
17409 else
17410 {
17411 if (EQ (prop, Qleft_fringe))
17412 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17413 if (EQ (prop, Qright_fringe))
17414 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17415 if (EQ (prop, Qleft_margin))
17416 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17417 if (EQ (prop, Qright_margin))
17418 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17419 if (EQ (prop, Qscroll_bar))
17420 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17421 }
17422
17423 prop = Fbuffer_local_value (prop, it->w->buffer);
17424 }
17425
17426 if (INTEGERP (prop) || FLOATP (prop))
17427 {
17428 int base_unit = (width_p
17429 ? FRAME_COLUMN_WIDTH (it->f)
17430 : FRAME_LINE_HEIGHT (it->f));
17431 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17432 }
17433
17434 if (CONSP (prop))
17435 {
17436 Lisp_Object car = XCAR (prop);
17437 Lisp_Object cdr = XCDR (prop);
17438
17439 if (SYMBOLP (car))
17440 {
17441 #ifdef HAVE_WINDOW_SYSTEM
17442 if (valid_image_p (prop))
17443 {
17444 int id = lookup_image (it->f, prop);
17445 struct image *img = IMAGE_FROM_ID (it->f, id);
17446
17447 return OK_PIXELS (width_p ? img->width : img->height);
17448 }
17449 #endif
17450 if (EQ (car, Qplus) || EQ (car, Qminus))
17451 {
17452 int first = 1;
17453 double px;
17454
17455 pixels = 0;
17456 while (CONSP (cdr))
17457 {
17458 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17459 font, width_p, align_to))
17460 return 0;
17461 if (first)
17462 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17463 else
17464 pixels += px;
17465 cdr = XCDR (cdr);
17466 }
17467 if (EQ (car, Qminus))
17468 pixels = -pixels;
17469 return OK_PIXELS (pixels);
17470 }
17471
17472 car = Fbuffer_local_value (car, it->w->buffer);
17473 }
17474
17475 if (INTEGERP (car) || FLOATP (car))
17476 {
17477 double fact;
17478 pixels = XFLOATINT (car);
17479 if (NILP (cdr))
17480 return OK_PIXELS (pixels);
17481 if (calc_pixel_width_or_height (&fact, it, cdr,
17482 font, width_p, align_to))
17483 return OK_PIXELS (pixels * fact);
17484 return 0;
17485 }
17486
17487 return 0;
17488 }
17489
17490 return 0;
17491 }
17492
17493 \f
17494 /***********************************************************************
17495 Glyph Display
17496 ***********************************************************************/
17497
17498 #ifdef HAVE_WINDOW_SYSTEM
17499
17500 #if GLYPH_DEBUG
17501
17502 void
17503 dump_glyph_string (s)
17504 struct glyph_string *s;
17505 {
17506 fprintf (stderr, "glyph string\n");
17507 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17508 s->x, s->y, s->width, s->height);
17509 fprintf (stderr, " ybase = %d\n", s->ybase);
17510 fprintf (stderr, " hl = %d\n", s->hl);
17511 fprintf (stderr, " left overhang = %d, right = %d\n",
17512 s->left_overhang, s->right_overhang);
17513 fprintf (stderr, " nchars = %d\n", s->nchars);
17514 fprintf (stderr, " extends to end of line = %d\n",
17515 s->extends_to_end_of_line_p);
17516 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17517 fprintf (stderr, " bg width = %d\n", s->background_width);
17518 }
17519
17520 #endif /* GLYPH_DEBUG */
17521
17522 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17523 of XChar2b structures for S; it can't be allocated in
17524 init_glyph_string because it must be allocated via `alloca'. W
17525 is the window on which S is drawn. ROW and AREA are the glyph row
17526 and area within the row from which S is constructed. START is the
17527 index of the first glyph structure covered by S. HL is a
17528 face-override for drawing S. */
17529
17530 #ifdef HAVE_NTGUI
17531 #define OPTIONAL_HDC(hdc) hdc,
17532 #define DECLARE_HDC(hdc) HDC hdc;
17533 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17534 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17535 #endif
17536
17537 #ifndef OPTIONAL_HDC
17538 #define OPTIONAL_HDC(hdc)
17539 #define DECLARE_HDC(hdc)
17540 #define ALLOCATE_HDC(hdc, f)
17541 #define RELEASE_HDC(hdc, f)
17542 #endif
17543
17544 static void
17545 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17546 struct glyph_string *s;
17547 DECLARE_HDC (hdc)
17548 XChar2b *char2b;
17549 struct window *w;
17550 struct glyph_row *row;
17551 enum glyph_row_area area;
17552 int start;
17553 enum draw_glyphs_face hl;
17554 {
17555 bzero (s, sizeof *s);
17556 s->w = w;
17557 s->f = XFRAME (w->frame);
17558 #ifdef HAVE_NTGUI
17559 s->hdc = hdc;
17560 #endif
17561 s->display = FRAME_X_DISPLAY (s->f);
17562 s->window = FRAME_X_WINDOW (s->f);
17563 s->char2b = char2b;
17564 s->hl = hl;
17565 s->row = row;
17566 s->area = area;
17567 s->first_glyph = row->glyphs[area] + start;
17568 s->height = row->height;
17569 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17570
17571 /* Display the internal border below the tool-bar window. */
17572 if (WINDOWP (s->f->tool_bar_window)
17573 && s->w == XWINDOW (s->f->tool_bar_window))
17574 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17575
17576 s->ybase = s->y + row->ascent;
17577 }
17578
17579
17580 /* Append the list of glyph strings with head H and tail T to the list
17581 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17582
17583 static INLINE void
17584 append_glyph_string_lists (head, tail, h, t)
17585 struct glyph_string **head, **tail;
17586 struct glyph_string *h, *t;
17587 {
17588 if (h)
17589 {
17590 if (*head)
17591 (*tail)->next = h;
17592 else
17593 *head = h;
17594 h->prev = *tail;
17595 *tail = t;
17596 }
17597 }
17598
17599
17600 /* Prepend the list of glyph strings with head H and tail T to the
17601 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17602 result. */
17603
17604 static INLINE void
17605 prepend_glyph_string_lists (head, tail, h, t)
17606 struct glyph_string **head, **tail;
17607 struct glyph_string *h, *t;
17608 {
17609 if (h)
17610 {
17611 if (*head)
17612 (*head)->prev = t;
17613 else
17614 *tail = t;
17615 t->next = *head;
17616 *head = h;
17617 }
17618 }
17619
17620
17621 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17622 Set *HEAD and *TAIL to the resulting list. */
17623
17624 static INLINE void
17625 append_glyph_string (head, tail, s)
17626 struct glyph_string **head, **tail;
17627 struct glyph_string *s;
17628 {
17629 s->next = s->prev = NULL;
17630 append_glyph_string_lists (head, tail, s, s);
17631 }
17632
17633
17634 /* Get face and two-byte form of character glyph GLYPH on frame F.
17635 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17636 a pointer to a realized face that is ready for display. */
17637
17638 static INLINE struct face *
17639 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17640 struct frame *f;
17641 struct glyph *glyph;
17642 XChar2b *char2b;
17643 int *two_byte_p;
17644 {
17645 struct face *face;
17646
17647 xassert (glyph->type == CHAR_GLYPH);
17648 face = FACE_FROM_ID (f, glyph->face_id);
17649
17650 if (two_byte_p)
17651 *two_byte_p = 0;
17652
17653 if (!glyph->multibyte_p)
17654 {
17655 /* Unibyte case. We don't have to encode, but we have to make
17656 sure to use a face suitable for unibyte. */
17657 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17658 }
17659 else if (glyph->u.ch < 128
17660 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17661 {
17662 /* Case of ASCII in a face known to fit ASCII. */
17663 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17664 }
17665 else
17666 {
17667 int c1, c2, charset;
17668
17669 /* Split characters into bytes. If c2 is -1 afterwards, C is
17670 really a one-byte character so that byte1 is zero. */
17671 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17672 if (c2 > 0)
17673 STORE_XCHAR2B (char2b, c1, c2);
17674 else
17675 STORE_XCHAR2B (char2b, 0, c1);
17676
17677 /* Maybe encode the character in *CHAR2B. */
17678 if (charset != CHARSET_ASCII)
17679 {
17680 struct font_info *font_info
17681 = FONT_INFO_FROM_ID (f, face->font_info_id);
17682 if (font_info)
17683 glyph->font_type
17684 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17685 }
17686 }
17687
17688 /* Make sure X resources of the face are allocated. */
17689 xassert (face != NULL);
17690 PREPARE_FACE_FOR_DISPLAY (f, face);
17691 return face;
17692 }
17693
17694
17695 /* Fill glyph string S with composition components specified by S->cmp.
17696
17697 FACES is an array of faces for all components of this composition.
17698 S->gidx is the index of the first component for S.
17699 OVERLAPS_P non-zero means S should draw the foreground only, and
17700 use its physical height for clipping.
17701
17702 Value is the index of a component not in S. */
17703
17704 static int
17705 fill_composite_glyph_string (s, faces, overlaps_p)
17706 struct glyph_string *s;
17707 struct face **faces;
17708 int overlaps_p;
17709 {
17710 int i;
17711
17712 xassert (s);
17713
17714 s->for_overlaps_p = overlaps_p;
17715
17716 s->face = faces[s->gidx];
17717 s->font = s->face->font;
17718 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17719
17720 /* For all glyphs of this composition, starting at the offset
17721 S->gidx, until we reach the end of the definition or encounter a
17722 glyph that requires the different face, add it to S. */
17723 ++s->nchars;
17724 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17725 ++s->nchars;
17726
17727 /* All glyph strings for the same composition has the same width,
17728 i.e. the width set for the first component of the composition. */
17729
17730 s->width = s->first_glyph->pixel_width;
17731
17732 /* If the specified font could not be loaded, use the frame's
17733 default font, but record the fact that we couldn't load it in
17734 the glyph string so that we can draw rectangles for the
17735 characters of the glyph string. */
17736 if (s->font == NULL)
17737 {
17738 s->font_not_found_p = 1;
17739 s->font = FRAME_FONT (s->f);
17740 }
17741
17742 /* Adjust base line for subscript/superscript text. */
17743 s->ybase += s->first_glyph->voffset;
17744
17745 xassert (s->face && s->face->gc);
17746
17747 /* This glyph string must always be drawn with 16-bit functions. */
17748 s->two_byte_p = 1;
17749
17750 return s->gidx + s->nchars;
17751 }
17752
17753
17754 /* Fill glyph string S from a sequence of character glyphs.
17755
17756 FACE_ID is the face id of the string. START is the index of the
17757 first glyph to consider, END is the index of the last + 1.
17758 OVERLAPS_P non-zero means S should draw the foreground only, and
17759 use its physical height for clipping.
17760
17761 Value is the index of the first glyph not in S. */
17762
17763 static int
17764 fill_glyph_string (s, face_id, start, end, overlaps_p)
17765 struct glyph_string *s;
17766 int face_id;
17767 int start, end, overlaps_p;
17768 {
17769 struct glyph *glyph, *last;
17770 int voffset;
17771 int glyph_not_available_p;
17772
17773 xassert (s->f == XFRAME (s->w->frame));
17774 xassert (s->nchars == 0);
17775 xassert (start >= 0 && end > start);
17776
17777 s->for_overlaps_p = overlaps_p,
17778 glyph = s->row->glyphs[s->area] + start;
17779 last = s->row->glyphs[s->area] + end;
17780 voffset = glyph->voffset;
17781
17782 glyph_not_available_p = glyph->glyph_not_available_p;
17783
17784 while (glyph < last
17785 && glyph->type == CHAR_GLYPH
17786 && glyph->voffset == voffset
17787 /* Same face id implies same font, nowadays. */
17788 && glyph->face_id == face_id
17789 && glyph->glyph_not_available_p == glyph_not_available_p)
17790 {
17791 int two_byte_p;
17792
17793 s->face = get_glyph_face_and_encoding (s->f, glyph,
17794 s->char2b + s->nchars,
17795 &two_byte_p);
17796 s->two_byte_p = two_byte_p;
17797 ++s->nchars;
17798 xassert (s->nchars <= end - start);
17799 s->width += glyph->pixel_width;
17800 ++glyph;
17801 }
17802
17803 s->font = s->face->font;
17804 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17805
17806 /* If the specified font could not be loaded, use the frame's font,
17807 but record the fact that we couldn't load it in
17808 S->font_not_found_p so that we can draw rectangles for the
17809 characters of the glyph string. */
17810 if (s->font == NULL || glyph_not_available_p)
17811 {
17812 s->font_not_found_p = 1;
17813 s->font = FRAME_FONT (s->f);
17814 }
17815
17816 /* Adjust base line for subscript/superscript text. */
17817 s->ybase += voffset;
17818
17819 xassert (s->face && s->face->gc);
17820 return glyph - s->row->glyphs[s->area];
17821 }
17822
17823
17824 /* Fill glyph string S from image glyph S->first_glyph. */
17825
17826 static void
17827 fill_image_glyph_string (s)
17828 struct glyph_string *s;
17829 {
17830 xassert (s->first_glyph->type == IMAGE_GLYPH);
17831 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17832 xassert (s->img);
17833 s->slice = s->first_glyph->slice;
17834 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17835 s->font = s->face->font;
17836 s->width = s->first_glyph->pixel_width;
17837
17838 /* Adjust base line for subscript/superscript text. */
17839 s->ybase += s->first_glyph->voffset;
17840 }
17841
17842
17843 /* Fill glyph string S from a sequence of stretch glyphs.
17844
17845 ROW is the glyph row in which the glyphs are found, AREA is the
17846 area within the row. START is the index of the first glyph to
17847 consider, END is the index of the last + 1.
17848
17849 Value is the index of the first glyph not in S. */
17850
17851 static int
17852 fill_stretch_glyph_string (s, row, area, start, end)
17853 struct glyph_string *s;
17854 struct glyph_row *row;
17855 enum glyph_row_area area;
17856 int start, end;
17857 {
17858 struct glyph *glyph, *last;
17859 int voffset, face_id;
17860
17861 xassert (s->first_glyph->type == STRETCH_GLYPH);
17862
17863 glyph = s->row->glyphs[s->area] + start;
17864 last = s->row->glyphs[s->area] + end;
17865 face_id = glyph->face_id;
17866 s->face = FACE_FROM_ID (s->f, face_id);
17867 s->font = s->face->font;
17868 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17869 s->width = glyph->pixel_width;
17870 voffset = glyph->voffset;
17871
17872 for (++glyph;
17873 (glyph < last
17874 && glyph->type == STRETCH_GLYPH
17875 && glyph->voffset == voffset
17876 && glyph->face_id == face_id);
17877 ++glyph)
17878 s->width += glyph->pixel_width;
17879
17880 /* Adjust base line for subscript/superscript text. */
17881 s->ybase += voffset;
17882
17883 /* The case that face->gc == 0 is handled when drawing the glyph
17884 string by calling PREPARE_FACE_FOR_DISPLAY. */
17885 xassert (s->face);
17886 return glyph - s->row->glyphs[s->area];
17887 }
17888
17889
17890 /* EXPORT for RIF:
17891 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17892 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17893 assumed to be zero. */
17894
17895 void
17896 x_get_glyph_overhangs (glyph, f, left, right)
17897 struct glyph *glyph;
17898 struct frame *f;
17899 int *left, *right;
17900 {
17901 *left = *right = 0;
17902
17903 if (glyph->type == CHAR_GLYPH)
17904 {
17905 XFontStruct *font;
17906 struct face *face;
17907 struct font_info *font_info;
17908 XChar2b char2b;
17909 XCharStruct *pcm;
17910
17911 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17912 font = face->font;
17913 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17914 if (font /* ++KFS: Should this be font_info ? */
17915 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17916 {
17917 if (pcm->rbearing > pcm->width)
17918 *right = pcm->rbearing - pcm->width;
17919 if (pcm->lbearing < 0)
17920 *left = -pcm->lbearing;
17921 }
17922 }
17923 }
17924
17925
17926 /* Return the index of the first glyph preceding glyph string S that
17927 is overwritten by S because of S's left overhang. Value is -1
17928 if no glyphs are overwritten. */
17929
17930 static int
17931 left_overwritten (s)
17932 struct glyph_string *s;
17933 {
17934 int k;
17935
17936 if (s->left_overhang)
17937 {
17938 int x = 0, i;
17939 struct glyph *glyphs = s->row->glyphs[s->area];
17940 int first = s->first_glyph - glyphs;
17941
17942 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17943 x -= glyphs[i].pixel_width;
17944
17945 k = i + 1;
17946 }
17947 else
17948 k = -1;
17949
17950 return k;
17951 }
17952
17953
17954 /* Return the index of the first glyph preceding glyph string S that
17955 is overwriting S because of its right overhang. Value is -1 if no
17956 glyph in front of S overwrites S. */
17957
17958 static int
17959 left_overwriting (s)
17960 struct glyph_string *s;
17961 {
17962 int i, k, x;
17963 struct glyph *glyphs = s->row->glyphs[s->area];
17964 int first = s->first_glyph - glyphs;
17965
17966 k = -1;
17967 x = 0;
17968 for (i = first - 1; i >= 0; --i)
17969 {
17970 int left, right;
17971 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17972 if (x + right > 0)
17973 k = i;
17974 x -= glyphs[i].pixel_width;
17975 }
17976
17977 return k;
17978 }
17979
17980
17981 /* Return the index of the last glyph following glyph string S that is
17982 not overwritten by S because of S's right overhang. Value is -1 if
17983 no such glyph is found. */
17984
17985 static int
17986 right_overwritten (s)
17987 struct glyph_string *s;
17988 {
17989 int k = -1;
17990
17991 if (s->right_overhang)
17992 {
17993 int x = 0, i;
17994 struct glyph *glyphs = s->row->glyphs[s->area];
17995 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17996 int end = s->row->used[s->area];
17997
17998 for (i = first; i < end && s->right_overhang > x; ++i)
17999 x += glyphs[i].pixel_width;
18000
18001 k = i;
18002 }
18003
18004 return k;
18005 }
18006
18007
18008 /* Return the index of the last glyph following glyph string S that
18009 overwrites S because of its left overhang. Value is negative
18010 if no such glyph is found. */
18011
18012 static int
18013 right_overwriting (s)
18014 struct glyph_string *s;
18015 {
18016 int i, k, x;
18017 int end = s->row->used[s->area];
18018 struct glyph *glyphs = s->row->glyphs[s->area];
18019 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
18020
18021 k = -1;
18022 x = 0;
18023 for (i = first; i < end; ++i)
18024 {
18025 int left, right;
18026 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
18027 if (x - left < 0)
18028 k = i;
18029 x += glyphs[i].pixel_width;
18030 }
18031
18032 return k;
18033 }
18034
18035
18036 /* Get face and two-byte form of character C in face FACE_ID on frame
18037 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
18038 means we want to display multibyte text. DISPLAY_P non-zero means
18039 make sure that X resources for the face returned are allocated.
18040 Value is a pointer to a realized face that is ready for display if
18041 DISPLAY_P is non-zero. */
18042
18043 static INLINE struct face *
18044 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
18045 struct frame *f;
18046 int c, face_id;
18047 XChar2b *char2b;
18048 int multibyte_p, display_p;
18049 {
18050 struct face *face = FACE_FROM_ID (f, face_id);
18051
18052 if (!multibyte_p)
18053 {
18054 /* Unibyte case. We don't have to encode, but we have to make
18055 sure to use a face suitable for unibyte. */
18056 STORE_XCHAR2B (char2b, 0, c);
18057 face_id = FACE_FOR_CHAR (f, face, c);
18058 face = FACE_FROM_ID (f, face_id);
18059 }
18060 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
18061 {
18062 /* Case of ASCII in a face known to fit ASCII. */
18063 STORE_XCHAR2B (char2b, 0, c);
18064 }
18065 else
18066 {
18067 int c1, c2, charset;
18068
18069 /* Split characters into bytes. If c2 is -1 afterwards, C is
18070 really a one-byte character so that byte1 is zero. */
18071 SPLIT_CHAR (c, charset, c1, c2);
18072 if (c2 > 0)
18073 STORE_XCHAR2B (char2b, c1, c2);
18074 else
18075 STORE_XCHAR2B (char2b, 0, c1);
18076
18077 /* Maybe encode the character in *CHAR2B. */
18078 if (face->font != NULL)
18079 {
18080 struct font_info *font_info
18081 = FONT_INFO_FROM_ID (f, face->font_info_id);
18082 if (font_info)
18083 rif->encode_char (c, char2b, font_info, 0);
18084 }
18085 }
18086
18087 /* Make sure X resources of the face are allocated. */
18088 #ifdef HAVE_X_WINDOWS
18089 if (display_p)
18090 #endif
18091 {
18092 xassert (face != NULL);
18093 PREPARE_FACE_FOR_DISPLAY (f, face);
18094 }
18095
18096 return face;
18097 }
18098
18099
18100 /* Set background width of glyph string S. START is the index of the
18101 first glyph following S. LAST_X is the right-most x-position + 1
18102 in the drawing area. */
18103
18104 static INLINE void
18105 set_glyph_string_background_width (s, start, last_x)
18106 struct glyph_string *s;
18107 int start;
18108 int last_x;
18109 {
18110 /* If the face of this glyph string has to be drawn to the end of
18111 the drawing area, set S->extends_to_end_of_line_p. */
18112 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
18113
18114 if (start == s->row->used[s->area]
18115 && s->area == TEXT_AREA
18116 && ((s->hl == DRAW_NORMAL_TEXT
18117 && (s->row->fill_line_p
18118 || s->face->background != default_face->background
18119 || s->face->stipple != default_face->stipple
18120 || s->row->mouse_face_p))
18121 || s->hl == DRAW_MOUSE_FACE
18122 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
18123 && s->row->fill_line_p)))
18124 s->extends_to_end_of_line_p = 1;
18125
18126 /* If S extends its face to the end of the line, set its
18127 background_width to the distance to the right edge of the drawing
18128 area. */
18129 if (s->extends_to_end_of_line_p)
18130 s->background_width = last_x - s->x + 1;
18131 else
18132 s->background_width = s->width;
18133 }
18134
18135
18136 /* Compute overhangs and x-positions for glyph string S and its
18137 predecessors, or successors. X is the starting x-position for S.
18138 BACKWARD_P non-zero means process predecessors. */
18139
18140 static void
18141 compute_overhangs_and_x (s, x, backward_p)
18142 struct glyph_string *s;
18143 int x;
18144 int backward_p;
18145 {
18146 if (backward_p)
18147 {
18148 while (s)
18149 {
18150 if (rif->compute_glyph_string_overhangs)
18151 rif->compute_glyph_string_overhangs (s);
18152 x -= s->width;
18153 s->x = x;
18154 s = s->prev;
18155 }
18156 }
18157 else
18158 {
18159 while (s)
18160 {
18161 if (rif->compute_glyph_string_overhangs)
18162 rif->compute_glyph_string_overhangs (s);
18163 s->x = x;
18164 x += s->width;
18165 s = s->next;
18166 }
18167 }
18168 }
18169
18170
18171
18172 /* The following macros are only called from draw_glyphs below.
18173 They reference the following parameters of that function directly:
18174 `w', `row', `area', and `overlap_p'
18175 as well as the following local variables:
18176 `s', `f', and `hdc' (in W32) */
18177
18178 #ifdef HAVE_NTGUI
18179 /* On W32, silently add local `hdc' variable to argument list of
18180 init_glyph_string. */
18181 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18182 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
18183 #else
18184 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18185 init_glyph_string (s, char2b, w, row, area, start, hl)
18186 #endif
18187
18188 /* Add a glyph string for a stretch glyph to the list of strings
18189 between HEAD and TAIL. START is the index of the stretch glyph in
18190 row area AREA of glyph row ROW. END is the index of the last glyph
18191 in that glyph row area. X is the current output position assigned
18192 to the new glyph string constructed. HL overrides that face of the
18193 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18194 is the right-most x-position of the drawing area. */
18195
18196 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
18197 and below -- keep them on one line. */
18198 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18199 do \
18200 { \
18201 s = (struct glyph_string *) alloca (sizeof *s); \
18202 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18203 START = fill_stretch_glyph_string (s, row, area, START, END); \
18204 append_glyph_string (&HEAD, &TAIL, s); \
18205 s->x = (X); \
18206 } \
18207 while (0)
18208
18209
18210 /* Add a glyph string for an image glyph to the list of strings
18211 between HEAD and TAIL. START is the index of the image glyph in
18212 row area AREA of glyph row ROW. END is the index of the last glyph
18213 in that glyph row area. X is the current output position assigned
18214 to the new glyph string constructed. HL overrides that face of the
18215 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18216 is the right-most x-position of the drawing area. */
18217
18218 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18219 do \
18220 { \
18221 s = (struct glyph_string *) alloca (sizeof *s); \
18222 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18223 fill_image_glyph_string (s); \
18224 append_glyph_string (&HEAD, &TAIL, s); \
18225 ++START; \
18226 s->x = (X); \
18227 } \
18228 while (0)
18229
18230
18231 /* Add a glyph string for a sequence of character glyphs to the list
18232 of strings between HEAD and TAIL. START is the index of the first
18233 glyph in row area AREA of glyph row ROW that is part of the new
18234 glyph string. END is the index of the last glyph in that glyph row
18235 area. X is the current output position assigned to the new glyph
18236 string constructed. HL overrides that face of the glyph; e.g. it
18237 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
18238 right-most x-position of the drawing area. */
18239
18240 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18241 do \
18242 { \
18243 int c, face_id; \
18244 XChar2b *char2b; \
18245 \
18246 c = (row)->glyphs[area][START].u.ch; \
18247 face_id = (row)->glyphs[area][START].face_id; \
18248 \
18249 s = (struct glyph_string *) alloca (sizeof *s); \
18250 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
18251 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
18252 append_glyph_string (&HEAD, &TAIL, s); \
18253 s->x = (X); \
18254 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
18255 } \
18256 while (0)
18257
18258
18259 /* Add a glyph string for a composite sequence to the list of strings
18260 between HEAD and TAIL. START is the index of the first glyph in
18261 row area AREA of glyph row ROW that is part of the new glyph
18262 string. END is the index of the last glyph in that glyph row area.
18263 X is the current output position assigned to the new glyph string
18264 constructed. HL overrides that face of the glyph; e.g. it is
18265 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18266 x-position of the drawing area. */
18267
18268 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18269 do { \
18270 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18271 int face_id = (row)->glyphs[area][START].face_id; \
18272 struct face *base_face = FACE_FROM_ID (f, face_id); \
18273 struct composition *cmp = composition_table[cmp_id]; \
18274 int glyph_len = cmp->glyph_len; \
18275 XChar2b *char2b; \
18276 struct face **faces; \
18277 struct glyph_string *first_s = NULL; \
18278 int n; \
18279 \
18280 base_face = base_face->ascii_face; \
18281 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18282 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18283 /* At first, fill in `char2b' and `faces'. */ \
18284 for (n = 0; n < glyph_len; n++) \
18285 { \
18286 int c = COMPOSITION_GLYPH (cmp, n); \
18287 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
18288 faces[n] = FACE_FROM_ID (f, this_face_id); \
18289 get_char_face_and_encoding (f, c, this_face_id, \
18290 char2b + n, 1, 1); \
18291 } \
18292 \
18293 /* Make glyph_strings for each glyph sequence that is drawable by \
18294 the same face, and append them to HEAD/TAIL. */ \
18295 for (n = 0; n < cmp->glyph_len;) \
18296 { \
18297 s = (struct glyph_string *) alloca (sizeof *s); \
18298 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18299 append_glyph_string (&(HEAD), &(TAIL), s); \
18300 s->cmp = cmp; \
18301 s->gidx = n; \
18302 s->x = (X); \
18303 \
18304 if (n == 0) \
18305 first_s = s; \
18306 \
18307 n = fill_composite_glyph_string (s, faces, overlaps_p); \
18308 } \
18309 \
18310 ++START; \
18311 s = first_s; \
18312 } while (0)
18313
18314
18315 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18316 of AREA of glyph row ROW on window W between indices START and END.
18317 HL overrides the face for drawing glyph strings, e.g. it is
18318 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18319 x-positions of the drawing area.
18320
18321 This is an ugly monster macro construct because we must use alloca
18322 to allocate glyph strings (because draw_glyphs can be called
18323 asynchronously). */
18324
18325 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18326 do \
18327 { \
18328 HEAD = TAIL = NULL; \
18329 while (START < END) \
18330 { \
18331 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18332 switch (first_glyph->type) \
18333 { \
18334 case CHAR_GLYPH: \
18335 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18336 HL, X, LAST_X); \
18337 break; \
18338 \
18339 case COMPOSITE_GLYPH: \
18340 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18341 HL, X, LAST_X); \
18342 break; \
18343 \
18344 case STRETCH_GLYPH: \
18345 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18346 HL, X, LAST_X); \
18347 break; \
18348 \
18349 case IMAGE_GLYPH: \
18350 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18351 HL, X, LAST_X); \
18352 break; \
18353 \
18354 default: \
18355 abort (); \
18356 } \
18357 \
18358 set_glyph_string_background_width (s, START, LAST_X); \
18359 (X) += s->width; \
18360 } \
18361 } \
18362 while (0)
18363
18364
18365 /* Draw glyphs between START and END in AREA of ROW on window W,
18366 starting at x-position X. X is relative to AREA in W. HL is a
18367 face-override with the following meaning:
18368
18369 DRAW_NORMAL_TEXT draw normally
18370 DRAW_CURSOR draw in cursor face
18371 DRAW_MOUSE_FACE draw in mouse face.
18372 DRAW_INVERSE_VIDEO draw in mode line face
18373 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18374 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18375
18376 If OVERLAPS_P is non-zero, draw only the foreground of characters
18377 and clip to the physical height of ROW.
18378
18379 Value is the x-position reached, relative to AREA of W. */
18380
18381 static int
18382 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18383 struct window *w;
18384 int x;
18385 struct glyph_row *row;
18386 enum glyph_row_area area;
18387 int start, end;
18388 enum draw_glyphs_face hl;
18389 int overlaps_p;
18390 {
18391 struct glyph_string *head, *tail;
18392 struct glyph_string *s;
18393 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
18394 int last_x, area_width;
18395 int x_reached;
18396 int i, j;
18397 struct frame *f = XFRAME (WINDOW_FRAME (w));
18398 DECLARE_HDC (hdc);
18399
18400 ALLOCATE_HDC (hdc, f);
18401
18402 /* Let's rather be paranoid than getting a SEGV. */
18403 end = min (end, row->used[area]);
18404 start = max (0, start);
18405 start = min (end, start);
18406
18407 /* Translate X to frame coordinates. Set last_x to the right
18408 end of the drawing area. */
18409 if (row->full_width_p)
18410 {
18411 /* X is relative to the left edge of W, without scroll bars
18412 or fringes. */
18413 x += WINDOW_LEFT_EDGE_X (w);
18414 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18415 }
18416 else
18417 {
18418 int area_left = window_box_left (w, area);
18419 x += area_left;
18420 area_width = window_box_width (w, area);
18421 last_x = area_left + area_width;
18422 }
18423
18424 /* Build a doubly-linked list of glyph_string structures between
18425 head and tail from what we have to draw. Note that the macro
18426 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18427 the reason we use a separate variable `i'. */
18428 i = start;
18429 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18430 if (tail)
18431 x_reached = tail->x + tail->background_width;
18432 else
18433 x_reached = x;
18434
18435 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18436 the row, redraw some glyphs in front or following the glyph
18437 strings built above. */
18438 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18439 {
18440 int dummy_x = 0;
18441 struct glyph_string *h, *t;
18442
18443 /* Compute overhangs for all glyph strings. */
18444 if (rif->compute_glyph_string_overhangs)
18445 for (s = head; s; s = s->next)
18446 rif->compute_glyph_string_overhangs (s);
18447
18448 /* Prepend glyph strings for glyphs in front of the first glyph
18449 string that are overwritten because of the first glyph
18450 string's left overhang. The background of all strings
18451 prepended must be drawn because the first glyph string
18452 draws over it. */
18453 i = left_overwritten (head);
18454 if (i >= 0)
18455 {
18456 j = i;
18457 BUILD_GLYPH_STRINGS (j, start, h, t,
18458 DRAW_NORMAL_TEXT, dummy_x, last_x);
18459 start = i;
18460 compute_overhangs_and_x (t, head->x, 1);
18461 prepend_glyph_string_lists (&head, &tail, h, t);
18462 clip_head = head;
18463 }
18464
18465 /* Prepend glyph strings for glyphs in front of the first glyph
18466 string that overwrite that glyph string because of their
18467 right overhang. For these strings, only the foreground must
18468 be drawn, because it draws over the glyph string at `head'.
18469 The background must not be drawn because this would overwrite
18470 right overhangs of preceding glyphs for which no glyph
18471 strings exist. */
18472 i = left_overwriting (head);
18473 if (i >= 0)
18474 {
18475 clip_head = head;
18476 BUILD_GLYPH_STRINGS (i, start, h, t,
18477 DRAW_NORMAL_TEXT, dummy_x, last_x);
18478 for (s = h; s; s = s->next)
18479 s->background_filled_p = 1;
18480 compute_overhangs_and_x (t, head->x, 1);
18481 prepend_glyph_string_lists (&head, &tail, h, t);
18482 }
18483
18484 /* Append glyphs strings for glyphs following the last glyph
18485 string tail that are overwritten by tail. The background of
18486 these strings has to be drawn because tail's foreground draws
18487 over it. */
18488 i = right_overwritten (tail);
18489 if (i >= 0)
18490 {
18491 BUILD_GLYPH_STRINGS (end, i, h, t,
18492 DRAW_NORMAL_TEXT, x, last_x);
18493 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18494 append_glyph_string_lists (&head, &tail, h, t);
18495 clip_tail = tail;
18496 }
18497
18498 /* Append glyph strings for glyphs following the last glyph
18499 string tail that overwrite tail. The foreground of such
18500 glyphs has to be drawn because it writes into the background
18501 of tail. The background must not be drawn because it could
18502 paint over the foreground of following glyphs. */
18503 i = right_overwriting (tail);
18504 if (i >= 0)
18505 {
18506 clip_tail = tail;
18507 BUILD_GLYPH_STRINGS (end, i, h, t,
18508 DRAW_NORMAL_TEXT, x, last_x);
18509 for (s = h; s; s = s->next)
18510 s->background_filled_p = 1;
18511 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18512 append_glyph_string_lists (&head, &tail, h, t);
18513 }
18514 if (clip_head || clip_tail)
18515 for (s = head; s; s = s->next)
18516 {
18517 s->clip_head = clip_head;
18518 s->clip_tail = clip_tail;
18519 }
18520 }
18521
18522 /* Draw all strings. */
18523 for (s = head; s; s = s->next)
18524 rif->draw_glyph_string (s);
18525
18526 if (area == TEXT_AREA
18527 && !row->full_width_p
18528 /* When drawing overlapping rows, only the glyph strings'
18529 foreground is drawn, which doesn't erase a cursor
18530 completely. */
18531 && !overlaps_p)
18532 {
18533 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
18534 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
18535 : (tail ? tail->x + tail->background_width : x));
18536
18537 int text_left = window_box_left (w, TEXT_AREA);
18538 x0 -= text_left;
18539 x1 -= text_left;
18540
18541 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18542 row->y, MATRIX_ROW_BOTTOM_Y (row));
18543 }
18544
18545 /* Value is the x-position up to which drawn, relative to AREA of W.
18546 This doesn't include parts drawn because of overhangs. */
18547 if (row->full_width_p)
18548 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18549 else
18550 x_reached -= window_box_left (w, area);
18551
18552 RELEASE_HDC (hdc, f);
18553
18554 return x_reached;
18555 }
18556
18557 /* Expand row matrix if too narrow. Don't expand if area
18558 is not present. */
18559
18560 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
18561 { \
18562 if (!fonts_changed_p \
18563 && (it->glyph_row->glyphs[area] \
18564 < it->glyph_row->glyphs[area + 1])) \
18565 { \
18566 it->w->ncols_scale_factor++; \
18567 fonts_changed_p = 1; \
18568 } \
18569 }
18570
18571 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18572 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18573
18574 static INLINE void
18575 append_glyph (it)
18576 struct it *it;
18577 {
18578 struct glyph *glyph;
18579 enum glyph_row_area area = it->area;
18580
18581 xassert (it->glyph_row);
18582 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18583
18584 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18585 if (glyph < it->glyph_row->glyphs[area + 1])
18586 {
18587 glyph->charpos = CHARPOS (it->position);
18588 glyph->object = it->object;
18589 glyph->pixel_width = it->pixel_width;
18590 glyph->ascent = it->ascent;
18591 glyph->descent = it->descent;
18592 glyph->voffset = it->voffset;
18593 glyph->type = CHAR_GLYPH;
18594 glyph->multibyte_p = it->multibyte_p;
18595 glyph->left_box_line_p = it->start_of_box_run_p;
18596 glyph->right_box_line_p = it->end_of_box_run_p;
18597 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18598 || it->phys_descent > it->descent);
18599 glyph->padding_p = 0;
18600 glyph->glyph_not_available_p = it->glyph_not_available_p;
18601 glyph->face_id = it->face_id;
18602 glyph->u.ch = it->char_to_display;
18603 glyph->slice = null_glyph_slice;
18604 glyph->font_type = FONT_TYPE_UNKNOWN;
18605 ++it->glyph_row->used[area];
18606 }
18607 else
18608 IT_EXPAND_MATRIX_WIDTH (it, area);
18609 }
18610
18611 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18612 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18613
18614 static INLINE void
18615 append_composite_glyph (it)
18616 struct it *it;
18617 {
18618 struct glyph *glyph;
18619 enum glyph_row_area area = it->area;
18620
18621 xassert (it->glyph_row);
18622
18623 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18624 if (glyph < it->glyph_row->glyphs[area + 1])
18625 {
18626 glyph->charpos = CHARPOS (it->position);
18627 glyph->object = it->object;
18628 glyph->pixel_width = it->pixel_width;
18629 glyph->ascent = it->ascent;
18630 glyph->descent = it->descent;
18631 glyph->voffset = it->voffset;
18632 glyph->type = COMPOSITE_GLYPH;
18633 glyph->multibyte_p = it->multibyte_p;
18634 glyph->left_box_line_p = it->start_of_box_run_p;
18635 glyph->right_box_line_p = it->end_of_box_run_p;
18636 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18637 || it->phys_descent > it->descent);
18638 glyph->padding_p = 0;
18639 glyph->glyph_not_available_p = 0;
18640 glyph->face_id = it->face_id;
18641 glyph->u.cmp_id = it->cmp_id;
18642 glyph->slice = null_glyph_slice;
18643 glyph->font_type = FONT_TYPE_UNKNOWN;
18644 ++it->glyph_row->used[area];
18645 }
18646 else
18647 IT_EXPAND_MATRIX_WIDTH (it, area);
18648 }
18649
18650
18651 /* Change IT->ascent and IT->height according to the setting of
18652 IT->voffset. */
18653
18654 static INLINE void
18655 take_vertical_position_into_account (it)
18656 struct it *it;
18657 {
18658 if (it->voffset)
18659 {
18660 if (it->voffset < 0)
18661 /* Increase the ascent so that we can display the text higher
18662 in the line. */
18663 it->ascent -= it->voffset;
18664 else
18665 /* Increase the descent so that we can display the text lower
18666 in the line. */
18667 it->descent += it->voffset;
18668 }
18669 }
18670
18671
18672 /* Produce glyphs/get display metrics for the image IT is loaded with.
18673 See the description of struct display_iterator in dispextern.h for
18674 an overview of struct display_iterator. */
18675
18676 static void
18677 produce_image_glyph (it)
18678 struct it *it;
18679 {
18680 struct image *img;
18681 struct face *face;
18682 int glyph_ascent;
18683 struct glyph_slice slice;
18684
18685 xassert (it->what == IT_IMAGE);
18686
18687 face = FACE_FROM_ID (it->f, it->face_id);
18688 xassert (face);
18689 /* Make sure X resources of the face is loaded. */
18690 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18691
18692 if (it->image_id < 0)
18693 {
18694 /* Fringe bitmap. */
18695 it->ascent = it->phys_ascent = 0;
18696 it->descent = it->phys_descent = 0;
18697 it->pixel_width = 0;
18698 it->nglyphs = 0;
18699 return;
18700 }
18701
18702 img = IMAGE_FROM_ID (it->f, it->image_id);
18703 xassert (img);
18704 /* Make sure X resources of the image is loaded. */
18705 prepare_image_for_display (it->f, img);
18706
18707 slice.x = slice.y = 0;
18708 slice.width = img->width;
18709 slice.height = img->height;
18710
18711 if (INTEGERP (it->slice.x))
18712 slice.x = XINT (it->slice.x);
18713 else if (FLOATP (it->slice.x))
18714 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18715
18716 if (INTEGERP (it->slice.y))
18717 slice.y = XINT (it->slice.y);
18718 else if (FLOATP (it->slice.y))
18719 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18720
18721 if (INTEGERP (it->slice.width))
18722 slice.width = XINT (it->slice.width);
18723 else if (FLOATP (it->slice.width))
18724 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18725
18726 if (INTEGERP (it->slice.height))
18727 slice.height = XINT (it->slice.height);
18728 else if (FLOATP (it->slice.height))
18729 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18730
18731 if (slice.x >= img->width)
18732 slice.x = img->width;
18733 if (slice.y >= img->height)
18734 slice.y = img->height;
18735 if (slice.x + slice.width >= img->width)
18736 slice.width = img->width - slice.x;
18737 if (slice.y + slice.height > img->height)
18738 slice.height = img->height - slice.y;
18739
18740 if (slice.width == 0 || slice.height == 0)
18741 return;
18742
18743 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18744
18745 it->descent = slice.height - glyph_ascent;
18746 if (slice.y == 0)
18747 it->descent += img->vmargin;
18748 if (slice.y + slice.height == img->height)
18749 it->descent += img->vmargin;
18750 it->phys_descent = it->descent;
18751
18752 it->pixel_width = slice.width;
18753 if (slice.x == 0)
18754 it->pixel_width += img->hmargin;
18755 if (slice.x + slice.width == img->width)
18756 it->pixel_width += img->hmargin;
18757
18758 /* It's quite possible for images to have an ascent greater than
18759 their height, so don't get confused in that case. */
18760 if (it->descent < 0)
18761 it->descent = 0;
18762
18763 #if 0 /* this breaks image tiling */
18764 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18765 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18766 if (face_ascent > it->ascent)
18767 it->ascent = it->phys_ascent = face_ascent;
18768 #endif
18769
18770 it->nglyphs = 1;
18771
18772 if (face->box != FACE_NO_BOX)
18773 {
18774 if (face->box_line_width > 0)
18775 {
18776 if (slice.y == 0)
18777 it->ascent += face->box_line_width;
18778 if (slice.y + slice.height == img->height)
18779 it->descent += face->box_line_width;
18780 }
18781
18782 if (it->start_of_box_run_p && slice.x == 0)
18783 it->pixel_width += abs (face->box_line_width);
18784 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18785 it->pixel_width += abs (face->box_line_width);
18786 }
18787
18788 take_vertical_position_into_account (it);
18789
18790 if (it->glyph_row)
18791 {
18792 struct glyph *glyph;
18793 enum glyph_row_area area = it->area;
18794
18795 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18796 if (glyph < it->glyph_row->glyphs[area + 1])
18797 {
18798 glyph->charpos = CHARPOS (it->position);
18799 glyph->object = it->object;
18800 glyph->pixel_width = it->pixel_width;
18801 glyph->ascent = glyph_ascent;
18802 glyph->descent = it->descent;
18803 glyph->voffset = it->voffset;
18804 glyph->type = IMAGE_GLYPH;
18805 glyph->multibyte_p = it->multibyte_p;
18806 glyph->left_box_line_p = it->start_of_box_run_p;
18807 glyph->right_box_line_p = it->end_of_box_run_p;
18808 glyph->overlaps_vertically_p = 0;
18809 glyph->padding_p = 0;
18810 glyph->glyph_not_available_p = 0;
18811 glyph->face_id = it->face_id;
18812 glyph->u.img_id = img->id;
18813 glyph->slice = slice;
18814 glyph->font_type = FONT_TYPE_UNKNOWN;
18815 ++it->glyph_row->used[area];
18816 }
18817 else
18818 IT_EXPAND_MATRIX_WIDTH (it, area);
18819 }
18820 }
18821
18822
18823 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18824 of the glyph, WIDTH and HEIGHT are the width and height of the
18825 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18826
18827 static void
18828 append_stretch_glyph (it, object, width, height, ascent)
18829 struct it *it;
18830 Lisp_Object object;
18831 int width, height;
18832 int ascent;
18833 {
18834 struct glyph *glyph;
18835 enum glyph_row_area area = it->area;
18836
18837 xassert (ascent >= 0 && ascent <= height);
18838
18839 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18840 if (glyph < it->glyph_row->glyphs[area + 1])
18841 {
18842 glyph->charpos = CHARPOS (it->position);
18843 glyph->object = object;
18844 glyph->pixel_width = width;
18845 glyph->ascent = ascent;
18846 glyph->descent = height - ascent;
18847 glyph->voffset = it->voffset;
18848 glyph->type = STRETCH_GLYPH;
18849 glyph->multibyte_p = it->multibyte_p;
18850 glyph->left_box_line_p = it->start_of_box_run_p;
18851 glyph->right_box_line_p = it->end_of_box_run_p;
18852 glyph->overlaps_vertically_p = 0;
18853 glyph->padding_p = 0;
18854 glyph->glyph_not_available_p = 0;
18855 glyph->face_id = it->face_id;
18856 glyph->u.stretch.ascent = ascent;
18857 glyph->u.stretch.height = height;
18858 glyph->slice = null_glyph_slice;
18859 glyph->font_type = FONT_TYPE_UNKNOWN;
18860 ++it->glyph_row->used[area];
18861 }
18862 else
18863 IT_EXPAND_MATRIX_WIDTH (it, area);
18864 }
18865
18866
18867 /* Produce a stretch glyph for iterator IT. IT->object is the value
18868 of the glyph property displayed. The value must be a list
18869 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18870 being recognized:
18871
18872 1. `:width WIDTH' specifies that the space should be WIDTH *
18873 canonical char width wide. WIDTH may be an integer or floating
18874 point number.
18875
18876 2. `:relative-width FACTOR' specifies that the width of the stretch
18877 should be computed from the width of the first character having the
18878 `glyph' property, and should be FACTOR times that width.
18879
18880 3. `:align-to HPOS' specifies that the space should be wide enough
18881 to reach HPOS, a value in canonical character units.
18882
18883 Exactly one of the above pairs must be present.
18884
18885 4. `:height HEIGHT' specifies that the height of the stretch produced
18886 should be HEIGHT, measured in canonical character units.
18887
18888 5. `:relative-height FACTOR' specifies that the height of the
18889 stretch should be FACTOR times the height of the characters having
18890 the glyph property.
18891
18892 Either none or exactly one of 4 or 5 must be present.
18893
18894 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18895 of the stretch should be used for the ascent of the stretch.
18896 ASCENT must be in the range 0 <= ASCENT <= 100. */
18897
18898 static void
18899 produce_stretch_glyph (it)
18900 struct it *it;
18901 {
18902 /* (space :width WIDTH :height HEIGHT ...) */
18903 Lisp_Object prop, plist;
18904 int width = 0, height = 0, align_to = -1;
18905 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18906 int ascent = 0;
18907 double tem;
18908 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18909 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18910
18911 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18912
18913 /* List should start with `space'. */
18914 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18915 plist = XCDR (it->object);
18916
18917 /* Compute the width of the stretch. */
18918 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18919 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18920 {
18921 /* Absolute width `:width WIDTH' specified and valid. */
18922 zero_width_ok_p = 1;
18923 width = (int)tem;
18924 }
18925 else if (prop = Fplist_get (plist, QCrelative_width),
18926 NUMVAL (prop) > 0)
18927 {
18928 /* Relative width `:relative-width FACTOR' specified and valid.
18929 Compute the width of the characters having the `glyph'
18930 property. */
18931 struct it it2;
18932 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18933
18934 it2 = *it;
18935 if (it->multibyte_p)
18936 {
18937 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18938 - IT_BYTEPOS (*it));
18939 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18940 }
18941 else
18942 it2.c = *p, it2.len = 1;
18943
18944 it2.glyph_row = NULL;
18945 it2.what = IT_CHARACTER;
18946 x_produce_glyphs (&it2);
18947 width = NUMVAL (prop) * it2.pixel_width;
18948 }
18949 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18950 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18951 {
18952 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18953 align_to = (align_to < 0
18954 ? 0
18955 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18956 else if (align_to < 0)
18957 align_to = window_box_left_offset (it->w, TEXT_AREA);
18958 width = max (0, (int)tem + align_to - it->current_x);
18959 zero_width_ok_p = 1;
18960 }
18961 else
18962 /* Nothing specified -> width defaults to canonical char width. */
18963 width = FRAME_COLUMN_WIDTH (it->f);
18964
18965 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18966 width = 1;
18967
18968 /* Compute height. */
18969 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18970 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18971 {
18972 height = (int)tem;
18973 zero_height_ok_p = 1;
18974 }
18975 else if (prop = Fplist_get (plist, QCrelative_height),
18976 NUMVAL (prop) > 0)
18977 height = FONT_HEIGHT (font) * NUMVAL (prop);
18978 else
18979 height = FONT_HEIGHT (font);
18980
18981 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18982 height = 1;
18983
18984 /* Compute percentage of height used for ascent. If
18985 `:ascent ASCENT' is present and valid, use that. Otherwise,
18986 derive the ascent from the font in use. */
18987 if (prop = Fplist_get (plist, QCascent),
18988 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18989 ascent = height * NUMVAL (prop) / 100.0;
18990 else if (!NILP (prop)
18991 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18992 ascent = min (max (0, (int)tem), height);
18993 else
18994 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18995
18996 if (width > 0 && height > 0 && it->glyph_row)
18997 {
18998 Lisp_Object object = it->stack[it->sp - 1].string;
18999 if (!STRINGP (object))
19000 object = it->w->buffer;
19001 append_stretch_glyph (it, object, width, height, ascent);
19002 }
19003
19004 it->pixel_width = width;
19005 it->ascent = it->phys_ascent = ascent;
19006 it->descent = it->phys_descent = height - it->ascent;
19007 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
19008
19009 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
19010 {
19011 if (face->box_line_width > 0)
19012 {
19013 it->ascent += face->box_line_width;
19014 it->descent += face->box_line_width;
19015 }
19016
19017 if (it->start_of_box_run_p)
19018 it->pixel_width += abs (face->box_line_width);
19019 if (it->end_of_box_run_p)
19020 it->pixel_width += abs (face->box_line_width);
19021 }
19022
19023 take_vertical_position_into_account (it);
19024 }
19025
19026 /* Get line-height and line-spacing property at point.
19027 If line-height has format (HEIGHT TOTAL), return TOTAL
19028 in TOTAL_HEIGHT. */
19029
19030 static Lisp_Object
19031 get_line_height_property (it, prop)
19032 struct it *it;
19033 Lisp_Object prop;
19034 {
19035 Lisp_Object position, val;
19036
19037 if (STRINGP (it->object))
19038 position = make_number (IT_STRING_CHARPOS (*it));
19039 else if (BUFFERP (it->object))
19040 position = make_number (IT_CHARPOS (*it));
19041 else
19042 return Qnil;
19043
19044 return Fget_char_property (position, prop, it->object);
19045 }
19046
19047 /* Calculate line-height and line-spacing properties.
19048 An integer value specifies explicit pixel value.
19049 A float value specifies relative value to current face height.
19050 A cons (float . face-name) specifies relative value to
19051 height of specified face font.
19052
19053 Returns height in pixels, or nil. */
19054
19055
19056 static Lisp_Object
19057 calc_line_height_property (it, val, font, boff, override)
19058 struct it *it;
19059 Lisp_Object val;
19060 XFontStruct *font;
19061 int boff, override;
19062 {
19063 Lisp_Object face_name = Qnil;
19064 int ascent, descent, height;
19065
19066 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
19067 return val;
19068
19069 if (CONSP (val))
19070 {
19071 face_name = XCAR (val);
19072 val = XCDR (val);
19073 if (!NUMBERP (val))
19074 val = make_number (1);
19075 if (NILP (face_name))
19076 {
19077 height = it->ascent + it->descent;
19078 goto scale;
19079 }
19080 }
19081
19082 if (NILP (face_name))
19083 {
19084 font = FRAME_FONT (it->f);
19085 boff = FRAME_BASELINE_OFFSET (it->f);
19086 }
19087 else if (EQ (face_name, Qt))
19088 {
19089 override = 0;
19090 }
19091 else
19092 {
19093 int face_id;
19094 struct face *face;
19095 struct font_info *font_info;
19096
19097 face_id = lookup_named_face (it->f, face_name, ' ', 0);
19098 if (face_id < 0)
19099 return make_number (-1);
19100
19101 face = FACE_FROM_ID (it->f, face_id);
19102 font = face->font;
19103 if (font == NULL)
19104 return make_number (-1);
19105
19106 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19107 boff = font_info->baseline_offset;
19108 if (font_info->vertical_centering)
19109 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19110 }
19111
19112 ascent = FONT_BASE (font) + boff;
19113 descent = FONT_DESCENT (font) - boff;
19114
19115 if (override)
19116 {
19117 it->override_ascent = ascent;
19118 it->override_descent = descent;
19119 it->override_boff = boff;
19120 }
19121
19122 height = ascent + descent;
19123
19124 scale:
19125 if (FLOATP (val))
19126 height = (int)(XFLOAT_DATA (val) * height);
19127 else if (INTEGERP (val))
19128 height *= XINT (val);
19129
19130 return make_number (height);
19131 }
19132
19133
19134 /* RIF:
19135 Produce glyphs/get display metrics for the display element IT is
19136 loaded with. See the description of struct display_iterator in
19137 dispextern.h for an overview of struct display_iterator. */
19138
19139 void
19140 x_produce_glyphs (it)
19141 struct it *it;
19142 {
19143 int extra_line_spacing = it->extra_line_spacing;
19144
19145 it->glyph_not_available_p = 0;
19146
19147 if (it->what == IT_CHARACTER)
19148 {
19149 XChar2b char2b;
19150 XFontStruct *font;
19151 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19152 XCharStruct *pcm;
19153 int font_not_found_p;
19154 struct font_info *font_info;
19155 int boff; /* baseline offset */
19156 /* We may change it->multibyte_p upon unibyte<->multibyte
19157 conversion. So, save the current value now and restore it
19158 later.
19159
19160 Note: It seems that we don't have to record multibyte_p in
19161 struct glyph because the character code itself tells if or
19162 not the character is multibyte. Thus, in the future, we must
19163 consider eliminating the field `multibyte_p' in the struct
19164 glyph. */
19165 int saved_multibyte_p = it->multibyte_p;
19166
19167 /* Maybe translate single-byte characters to multibyte, or the
19168 other way. */
19169 it->char_to_display = it->c;
19170 if (!ASCII_BYTE_P (it->c))
19171 {
19172 if (unibyte_display_via_language_environment
19173 && SINGLE_BYTE_CHAR_P (it->c)
19174 && (it->c >= 0240
19175 || !NILP (Vnonascii_translation_table)))
19176 {
19177 it->char_to_display = unibyte_char_to_multibyte (it->c);
19178 it->multibyte_p = 1;
19179 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19180 face = FACE_FROM_ID (it->f, it->face_id);
19181 }
19182 else if (!SINGLE_BYTE_CHAR_P (it->c)
19183 && !it->multibyte_p)
19184 {
19185 it->multibyte_p = 1;
19186 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19187 face = FACE_FROM_ID (it->f, it->face_id);
19188 }
19189 }
19190
19191 /* Get font to use. Encode IT->char_to_display. */
19192 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19193 &char2b, it->multibyte_p, 0);
19194 font = face->font;
19195
19196 /* When no suitable font found, use the default font. */
19197 font_not_found_p = font == NULL;
19198 if (font_not_found_p)
19199 {
19200 font = FRAME_FONT (it->f);
19201 boff = FRAME_BASELINE_OFFSET (it->f);
19202 font_info = NULL;
19203 }
19204 else
19205 {
19206 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19207 boff = font_info->baseline_offset;
19208 if (font_info->vertical_centering)
19209 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19210 }
19211
19212 if (it->char_to_display >= ' '
19213 && (!it->multibyte_p || it->char_to_display < 128))
19214 {
19215 /* Either unibyte or ASCII. */
19216 int stretched_p;
19217
19218 it->nglyphs = 1;
19219
19220 pcm = rif->per_char_metric (font, &char2b,
19221 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
19222
19223 if (it->override_ascent >= 0)
19224 {
19225 it->ascent = it->override_ascent;
19226 it->descent = it->override_descent;
19227 boff = it->override_boff;
19228 }
19229 else
19230 {
19231 it->ascent = FONT_BASE (font) + boff;
19232 it->descent = FONT_DESCENT (font) - boff;
19233 }
19234
19235 if (pcm)
19236 {
19237 it->phys_ascent = pcm->ascent + boff;
19238 it->phys_descent = pcm->descent - boff;
19239 it->pixel_width = pcm->width;
19240 }
19241 else
19242 {
19243 it->glyph_not_available_p = 1;
19244 it->phys_ascent = it->ascent;
19245 it->phys_descent = it->descent;
19246 it->pixel_width = FONT_WIDTH (font);
19247 }
19248
19249 if (it->constrain_row_ascent_descent_p)
19250 {
19251 if (it->descent > it->max_descent)
19252 {
19253 it->ascent += it->descent - it->max_descent;
19254 it->descent = it->max_descent;
19255 }
19256 if (it->ascent > it->max_ascent)
19257 {
19258 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19259 it->ascent = it->max_ascent;
19260 }
19261 it->phys_ascent = min (it->phys_ascent, it->ascent);
19262 it->phys_descent = min (it->phys_descent, it->descent);
19263 extra_line_spacing = 0;
19264 }
19265
19266 /* If this is a space inside a region of text with
19267 `space-width' property, change its width. */
19268 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
19269 if (stretched_p)
19270 it->pixel_width *= XFLOATINT (it->space_width);
19271
19272 /* If face has a box, add the box thickness to the character
19273 height. If character has a box line to the left and/or
19274 right, add the box line width to the character's width. */
19275 if (face->box != FACE_NO_BOX)
19276 {
19277 int thick = face->box_line_width;
19278
19279 if (thick > 0)
19280 {
19281 it->ascent += thick;
19282 it->descent += thick;
19283 }
19284 else
19285 thick = -thick;
19286
19287 if (it->start_of_box_run_p)
19288 it->pixel_width += thick;
19289 if (it->end_of_box_run_p)
19290 it->pixel_width += thick;
19291 }
19292
19293 /* If face has an overline, add the height of the overline
19294 (1 pixel) and a 1 pixel margin to the character height. */
19295 if (face->overline_p)
19296 it->ascent += 2;
19297
19298 if (it->constrain_row_ascent_descent_p)
19299 {
19300 if (it->ascent > it->max_ascent)
19301 it->ascent = it->max_ascent;
19302 if (it->descent > it->max_descent)
19303 it->descent = it->max_descent;
19304 }
19305
19306 take_vertical_position_into_account (it);
19307
19308 /* If we have to actually produce glyphs, do it. */
19309 if (it->glyph_row)
19310 {
19311 if (stretched_p)
19312 {
19313 /* Translate a space with a `space-width' property
19314 into a stretch glyph. */
19315 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
19316 / FONT_HEIGHT (font));
19317 append_stretch_glyph (it, it->object, it->pixel_width,
19318 it->ascent + it->descent, ascent);
19319 }
19320 else
19321 append_glyph (it);
19322
19323 /* If characters with lbearing or rbearing are displayed
19324 in this line, record that fact in a flag of the
19325 glyph row. This is used to optimize X output code. */
19326 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
19327 it->glyph_row->contains_overlapping_glyphs_p = 1;
19328 }
19329 }
19330 else if (it->char_to_display == '\n')
19331 {
19332 /* A newline has no width but we need the height of the line.
19333 But if previous part of the line set a height, don't
19334 increase that height */
19335
19336 Lisp_Object height;
19337 Lisp_Object total_height = Qnil;
19338
19339 it->override_ascent = -1;
19340 it->pixel_width = 0;
19341 it->nglyphs = 0;
19342
19343 height = get_line_height_property(it, Qline_height);
19344 /* Split (line-height total-height) list */
19345 if (CONSP (height)
19346 && CONSP (XCDR (height))
19347 && NILP (XCDR (XCDR (height))))
19348 {
19349 total_height = XCAR (XCDR (height));
19350 height = XCAR (height);
19351 }
19352 height = calc_line_height_property(it, height, font, boff, 1);
19353
19354 if (it->override_ascent >= 0)
19355 {
19356 it->ascent = it->override_ascent;
19357 it->descent = it->override_descent;
19358 boff = it->override_boff;
19359 }
19360 else
19361 {
19362 it->ascent = FONT_BASE (font) + boff;
19363 it->descent = FONT_DESCENT (font) - boff;
19364 }
19365
19366 if (EQ (height, Qt))
19367 {
19368 if (it->descent > it->max_descent)
19369 {
19370 it->ascent += it->descent - it->max_descent;
19371 it->descent = it->max_descent;
19372 }
19373 if (it->ascent > it->max_ascent)
19374 {
19375 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19376 it->ascent = it->max_ascent;
19377 }
19378 it->phys_ascent = min (it->phys_ascent, it->ascent);
19379 it->phys_descent = min (it->phys_descent, it->descent);
19380 it->constrain_row_ascent_descent_p = 1;
19381 extra_line_spacing = 0;
19382 }
19383 else
19384 {
19385 Lisp_Object spacing;
19386 int total = 0;
19387
19388 it->phys_ascent = it->ascent;
19389 it->phys_descent = it->descent;
19390
19391 if ((it->max_ascent > 0 || it->max_descent > 0)
19392 && face->box != FACE_NO_BOX
19393 && face->box_line_width > 0)
19394 {
19395 it->ascent += face->box_line_width;
19396 it->descent += face->box_line_width;
19397 }
19398 if (!NILP (height)
19399 && XINT (height) > it->ascent + it->descent)
19400 it->ascent = XINT (height) - it->descent;
19401
19402 if (!NILP (total_height))
19403 spacing = calc_line_height_property(it, total_height, font, boff, 0);
19404 else
19405 {
19406 spacing = get_line_height_property(it, Qline_spacing);
19407 spacing = calc_line_height_property(it, spacing, font, boff, 0);
19408 }
19409 if (INTEGERP (spacing))
19410 {
19411 extra_line_spacing = XINT (spacing);
19412 if (!NILP (total_height))
19413 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19414 }
19415 }
19416 }
19417 else if (it->char_to_display == '\t')
19418 {
19419 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
19420 int x = it->current_x + it->continuation_lines_width;
19421 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19422
19423 /* If the distance from the current position to the next tab
19424 stop is less than a space character width, use the
19425 tab stop after that. */
19426 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
19427 next_tab_x += tab_width;
19428
19429 it->pixel_width = next_tab_x - x;
19430 it->nglyphs = 1;
19431 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19432 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19433
19434 if (it->glyph_row)
19435 {
19436 append_stretch_glyph (it, it->object, it->pixel_width,
19437 it->ascent + it->descent, it->ascent);
19438 }
19439 }
19440 else
19441 {
19442 /* A multi-byte character. Assume that the display width of the
19443 character is the width of the character multiplied by the
19444 width of the font. */
19445
19446 /* If we found a font, this font should give us the right
19447 metrics. If we didn't find a font, use the frame's
19448 default font and calculate the width of the character
19449 from the charset width; this is what old redisplay code
19450 did. */
19451
19452 pcm = rif->per_char_metric (font, &char2b,
19453 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19454
19455 if (font_not_found_p || !pcm)
19456 {
19457 int charset = CHAR_CHARSET (it->char_to_display);
19458
19459 it->glyph_not_available_p = 1;
19460 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19461 * CHARSET_WIDTH (charset));
19462 it->phys_ascent = FONT_BASE (font) + boff;
19463 it->phys_descent = FONT_DESCENT (font) - boff;
19464 }
19465 else
19466 {
19467 it->pixel_width = pcm->width;
19468 it->phys_ascent = pcm->ascent + boff;
19469 it->phys_descent = pcm->descent - boff;
19470 if (it->glyph_row
19471 && (pcm->lbearing < 0
19472 || pcm->rbearing > pcm->width))
19473 it->glyph_row->contains_overlapping_glyphs_p = 1;
19474 }
19475 it->nglyphs = 1;
19476 it->ascent = FONT_BASE (font) + boff;
19477 it->descent = FONT_DESCENT (font) - boff;
19478 if (face->box != FACE_NO_BOX)
19479 {
19480 int thick = face->box_line_width;
19481
19482 if (thick > 0)
19483 {
19484 it->ascent += thick;
19485 it->descent += thick;
19486 }
19487 else
19488 thick = - thick;
19489
19490 if (it->start_of_box_run_p)
19491 it->pixel_width += thick;
19492 if (it->end_of_box_run_p)
19493 it->pixel_width += thick;
19494 }
19495
19496 /* If face has an overline, add the height of the overline
19497 (1 pixel) and a 1 pixel margin to the character height. */
19498 if (face->overline_p)
19499 it->ascent += 2;
19500
19501 take_vertical_position_into_account (it);
19502
19503 if (it->glyph_row)
19504 append_glyph (it);
19505 }
19506 it->multibyte_p = saved_multibyte_p;
19507 }
19508 else if (it->what == IT_COMPOSITION)
19509 {
19510 /* Note: A composition is represented as one glyph in the
19511 glyph matrix. There are no padding glyphs. */
19512 XChar2b char2b;
19513 XFontStruct *font;
19514 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19515 XCharStruct *pcm;
19516 int font_not_found_p;
19517 struct font_info *font_info;
19518 int boff; /* baseline offset */
19519 struct composition *cmp = composition_table[it->cmp_id];
19520
19521 /* Maybe translate single-byte characters to multibyte. */
19522 it->char_to_display = it->c;
19523 if (unibyte_display_via_language_environment
19524 && SINGLE_BYTE_CHAR_P (it->c)
19525 && (it->c >= 0240
19526 || (it->c >= 0200
19527 && !NILP (Vnonascii_translation_table))))
19528 {
19529 it->char_to_display = unibyte_char_to_multibyte (it->c);
19530 }
19531
19532 /* Get face and font to use. Encode IT->char_to_display. */
19533 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19534 face = FACE_FROM_ID (it->f, it->face_id);
19535 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19536 &char2b, it->multibyte_p, 0);
19537 font = face->font;
19538
19539 /* When no suitable font found, use the default font. */
19540 font_not_found_p = font == NULL;
19541 if (font_not_found_p)
19542 {
19543 font = FRAME_FONT (it->f);
19544 boff = FRAME_BASELINE_OFFSET (it->f);
19545 font_info = NULL;
19546 }
19547 else
19548 {
19549 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19550 boff = font_info->baseline_offset;
19551 if (font_info->vertical_centering)
19552 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19553 }
19554
19555 /* There are no padding glyphs, so there is only one glyph to
19556 produce for the composition. Important is that pixel_width,
19557 ascent and descent are the values of what is drawn by
19558 draw_glyphs (i.e. the values of the overall glyphs composed). */
19559 it->nglyphs = 1;
19560
19561 /* If we have not yet calculated pixel size data of glyphs of
19562 the composition for the current face font, calculate them
19563 now. Theoretically, we have to check all fonts for the
19564 glyphs, but that requires much time and memory space. So,
19565 here we check only the font of the first glyph. This leads
19566 to incorrect display very rarely, and C-l (recenter) can
19567 correct the display anyway. */
19568 if (cmp->font != (void *) font)
19569 {
19570 /* Ascent and descent of the font of the first character of
19571 this composition (adjusted by baseline offset). Ascent
19572 and descent of overall glyphs should not be less than
19573 them respectively. */
19574 int font_ascent = FONT_BASE (font) + boff;
19575 int font_descent = FONT_DESCENT (font) - boff;
19576 /* Bounding box of the overall glyphs. */
19577 int leftmost, rightmost, lowest, highest;
19578 int i, width, ascent, descent;
19579
19580 cmp->font = (void *) font;
19581
19582 /* Initialize the bounding box. */
19583 if (font_info
19584 && (pcm = rif->per_char_metric (font, &char2b,
19585 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19586 {
19587 width = pcm->width;
19588 ascent = pcm->ascent;
19589 descent = pcm->descent;
19590 }
19591 else
19592 {
19593 width = FONT_WIDTH (font);
19594 ascent = FONT_BASE (font);
19595 descent = FONT_DESCENT (font);
19596 }
19597
19598 rightmost = width;
19599 lowest = - descent + boff;
19600 highest = ascent + boff;
19601 leftmost = 0;
19602
19603 if (font_info
19604 && font_info->default_ascent
19605 && CHAR_TABLE_P (Vuse_default_ascent)
19606 && !NILP (Faref (Vuse_default_ascent,
19607 make_number (it->char_to_display))))
19608 highest = font_info->default_ascent + boff;
19609
19610 /* Draw the first glyph at the normal position. It may be
19611 shifted to right later if some other glyphs are drawn at
19612 the left. */
19613 cmp->offsets[0] = 0;
19614 cmp->offsets[1] = boff;
19615
19616 /* Set cmp->offsets for the remaining glyphs. */
19617 for (i = 1; i < cmp->glyph_len; i++)
19618 {
19619 int left, right, btm, top;
19620 int ch = COMPOSITION_GLYPH (cmp, i);
19621 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19622
19623 face = FACE_FROM_ID (it->f, face_id);
19624 get_char_face_and_encoding (it->f, ch, face->id,
19625 &char2b, it->multibyte_p, 0);
19626 font = face->font;
19627 if (font == NULL)
19628 {
19629 font = FRAME_FONT (it->f);
19630 boff = FRAME_BASELINE_OFFSET (it->f);
19631 font_info = NULL;
19632 }
19633 else
19634 {
19635 font_info
19636 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19637 boff = font_info->baseline_offset;
19638 if (font_info->vertical_centering)
19639 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19640 }
19641
19642 if (font_info
19643 && (pcm = rif->per_char_metric (font, &char2b,
19644 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19645 {
19646 width = pcm->width;
19647 ascent = pcm->ascent;
19648 descent = pcm->descent;
19649 }
19650 else
19651 {
19652 width = FONT_WIDTH (font);
19653 ascent = 1;
19654 descent = 0;
19655 }
19656
19657 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19658 {
19659 /* Relative composition with or without
19660 alternate chars. */
19661 left = (leftmost + rightmost - width) / 2;
19662 btm = - descent + boff;
19663 if (font_info && font_info->relative_compose
19664 && (! CHAR_TABLE_P (Vignore_relative_composition)
19665 || NILP (Faref (Vignore_relative_composition,
19666 make_number (ch)))))
19667 {
19668
19669 if (- descent >= font_info->relative_compose)
19670 /* One extra pixel between two glyphs. */
19671 btm = highest + 1;
19672 else if (ascent <= 0)
19673 /* One extra pixel between two glyphs. */
19674 btm = lowest - 1 - ascent - descent;
19675 }
19676 }
19677 else
19678 {
19679 /* A composition rule is specified by an integer
19680 value that encodes global and new reference
19681 points (GREF and NREF). GREF and NREF are
19682 specified by numbers as below:
19683
19684 0---1---2 -- ascent
19685 | |
19686 | |
19687 | |
19688 9--10--11 -- center
19689 | |
19690 ---3---4---5--- baseline
19691 | |
19692 6---7---8 -- descent
19693 */
19694 int rule = COMPOSITION_RULE (cmp, i);
19695 int gref, nref, grefx, grefy, nrefx, nrefy;
19696
19697 COMPOSITION_DECODE_RULE (rule, gref, nref);
19698 grefx = gref % 3, nrefx = nref % 3;
19699 grefy = gref / 3, nrefy = nref / 3;
19700
19701 left = (leftmost
19702 + grefx * (rightmost - leftmost) / 2
19703 - nrefx * width / 2);
19704 btm = ((grefy == 0 ? highest
19705 : grefy == 1 ? 0
19706 : grefy == 2 ? lowest
19707 : (highest + lowest) / 2)
19708 - (nrefy == 0 ? ascent + descent
19709 : nrefy == 1 ? descent - boff
19710 : nrefy == 2 ? 0
19711 : (ascent + descent) / 2));
19712 }
19713
19714 cmp->offsets[i * 2] = left;
19715 cmp->offsets[i * 2 + 1] = btm + descent;
19716
19717 /* Update the bounding box of the overall glyphs. */
19718 right = left + width;
19719 top = btm + descent + ascent;
19720 if (left < leftmost)
19721 leftmost = left;
19722 if (right > rightmost)
19723 rightmost = right;
19724 if (top > highest)
19725 highest = top;
19726 if (btm < lowest)
19727 lowest = btm;
19728 }
19729
19730 /* If there are glyphs whose x-offsets are negative,
19731 shift all glyphs to the right and make all x-offsets
19732 non-negative. */
19733 if (leftmost < 0)
19734 {
19735 for (i = 0; i < cmp->glyph_len; i++)
19736 cmp->offsets[i * 2] -= leftmost;
19737 rightmost -= leftmost;
19738 }
19739
19740 cmp->pixel_width = rightmost;
19741 cmp->ascent = highest;
19742 cmp->descent = - lowest;
19743 if (cmp->ascent < font_ascent)
19744 cmp->ascent = font_ascent;
19745 if (cmp->descent < font_descent)
19746 cmp->descent = font_descent;
19747 }
19748
19749 it->pixel_width = cmp->pixel_width;
19750 it->ascent = it->phys_ascent = cmp->ascent;
19751 it->descent = it->phys_descent = cmp->descent;
19752
19753 if (face->box != FACE_NO_BOX)
19754 {
19755 int thick = face->box_line_width;
19756
19757 if (thick > 0)
19758 {
19759 it->ascent += thick;
19760 it->descent += thick;
19761 }
19762 else
19763 thick = - thick;
19764
19765 if (it->start_of_box_run_p)
19766 it->pixel_width += thick;
19767 if (it->end_of_box_run_p)
19768 it->pixel_width += thick;
19769 }
19770
19771 /* If face has an overline, add the height of the overline
19772 (1 pixel) and a 1 pixel margin to the character height. */
19773 if (face->overline_p)
19774 it->ascent += 2;
19775
19776 take_vertical_position_into_account (it);
19777
19778 if (it->glyph_row)
19779 append_composite_glyph (it);
19780 }
19781 else if (it->what == IT_IMAGE)
19782 produce_image_glyph (it);
19783 else if (it->what == IT_STRETCH)
19784 produce_stretch_glyph (it);
19785
19786 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19787 because this isn't true for images with `:ascent 100'. */
19788 xassert (it->ascent >= 0 && it->descent >= 0);
19789 if (it->area == TEXT_AREA)
19790 it->current_x += it->pixel_width;
19791
19792 if (extra_line_spacing > 0)
19793 {
19794 it->descent += extra_line_spacing;
19795 if (extra_line_spacing > it->max_extra_line_spacing)
19796 it->max_extra_line_spacing = extra_line_spacing;
19797 }
19798
19799 it->max_ascent = max (it->max_ascent, it->ascent);
19800 it->max_descent = max (it->max_descent, it->descent);
19801 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19802 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19803 }
19804
19805 /* EXPORT for RIF:
19806 Output LEN glyphs starting at START at the nominal cursor position.
19807 Advance the nominal cursor over the text. The global variable
19808 updated_window contains the window being updated, updated_row is
19809 the glyph row being updated, and updated_area is the area of that
19810 row being updated. */
19811
19812 void
19813 x_write_glyphs (start, len)
19814 struct glyph *start;
19815 int len;
19816 {
19817 int x, hpos;
19818
19819 xassert (updated_window && updated_row);
19820 BLOCK_INPUT;
19821
19822 /* Write glyphs. */
19823
19824 hpos = start - updated_row->glyphs[updated_area];
19825 x = draw_glyphs (updated_window, output_cursor.x,
19826 updated_row, updated_area,
19827 hpos, hpos + len,
19828 DRAW_NORMAL_TEXT, 0);
19829
19830 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19831 if (updated_area == TEXT_AREA
19832 && updated_window->phys_cursor_on_p
19833 && updated_window->phys_cursor.vpos == output_cursor.vpos
19834 && updated_window->phys_cursor.hpos >= hpos
19835 && updated_window->phys_cursor.hpos < hpos + len)
19836 updated_window->phys_cursor_on_p = 0;
19837
19838 UNBLOCK_INPUT;
19839
19840 /* Advance the output cursor. */
19841 output_cursor.hpos += len;
19842 output_cursor.x = x;
19843 }
19844
19845
19846 /* EXPORT for RIF:
19847 Insert LEN glyphs from START at the nominal cursor position. */
19848
19849 void
19850 x_insert_glyphs (start, len)
19851 struct glyph *start;
19852 int len;
19853 {
19854 struct frame *f;
19855 struct window *w;
19856 int line_height, shift_by_width, shifted_region_width;
19857 struct glyph_row *row;
19858 struct glyph *glyph;
19859 int frame_x, frame_y, hpos;
19860
19861 xassert (updated_window && updated_row);
19862 BLOCK_INPUT;
19863 w = updated_window;
19864 f = XFRAME (WINDOW_FRAME (w));
19865
19866 /* Get the height of the line we are in. */
19867 row = updated_row;
19868 line_height = row->height;
19869
19870 /* Get the width of the glyphs to insert. */
19871 shift_by_width = 0;
19872 for (glyph = start; glyph < start + len; ++glyph)
19873 shift_by_width += glyph->pixel_width;
19874
19875 /* Get the width of the region to shift right. */
19876 shifted_region_width = (window_box_width (w, updated_area)
19877 - output_cursor.x
19878 - shift_by_width);
19879
19880 /* Shift right. */
19881 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19882 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19883
19884 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19885 line_height, shift_by_width);
19886
19887 /* Write the glyphs. */
19888 hpos = start - row->glyphs[updated_area];
19889 draw_glyphs (w, output_cursor.x, row, updated_area,
19890 hpos, hpos + len,
19891 DRAW_NORMAL_TEXT, 0);
19892
19893 /* Advance the output cursor. */
19894 output_cursor.hpos += len;
19895 output_cursor.x += shift_by_width;
19896 UNBLOCK_INPUT;
19897 }
19898
19899
19900 /* EXPORT for RIF:
19901 Erase the current text line from the nominal cursor position
19902 (inclusive) to pixel column TO_X (exclusive). The idea is that
19903 everything from TO_X onward is already erased.
19904
19905 TO_X is a pixel position relative to updated_area of
19906 updated_window. TO_X == -1 means clear to the end of this area. */
19907
19908 void
19909 x_clear_end_of_line (to_x)
19910 int to_x;
19911 {
19912 struct frame *f;
19913 struct window *w = updated_window;
19914 int max_x, min_y, max_y;
19915 int from_x, from_y, to_y;
19916
19917 xassert (updated_window && updated_row);
19918 f = XFRAME (w->frame);
19919
19920 if (updated_row->full_width_p)
19921 max_x = WINDOW_TOTAL_WIDTH (w);
19922 else
19923 max_x = window_box_width (w, updated_area);
19924 max_y = window_text_bottom_y (w);
19925
19926 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19927 of window. For TO_X > 0, truncate to end of drawing area. */
19928 if (to_x == 0)
19929 return;
19930 else if (to_x < 0)
19931 to_x = max_x;
19932 else
19933 to_x = min (to_x, max_x);
19934
19935 to_y = min (max_y, output_cursor.y + updated_row->height);
19936
19937 /* Notice if the cursor will be cleared by this operation. */
19938 if (!updated_row->full_width_p)
19939 notice_overwritten_cursor (w, updated_area,
19940 output_cursor.x, -1,
19941 updated_row->y,
19942 MATRIX_ROW_BOTTOM_Y (updated_row));
19943
19944 from_x = output_cursor.x;
19945
19946 /* Translate to frame coordinates. */
19947 if (updated_row->full_width_p)
19948 {
19949 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19950 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19951 }
19952 else
19953 {
19954 int area_left = window_box_left (w, updated_area);
19955 from_x += area_left;
19956 to_x += area_left;
19957 }
19958
19959 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19960 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19961 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19962
19963 /* Prevent inadvertently clearing to end of the X window. */
19964 if (to_x > from_x && to_y > from_y)
19965 {
19966 BLOCK_INPUT;
19967 rif->clear_frame_area (f, from_x, from_y,
19968 to_x - from_x, to_y - from_y);
19969 UNBLOCK_INPUT;
19970 }
19971 }
19972
19973 #endif /* HAVE_WINDOW_SYSTEM */
19974
19975
19976 \f
19977 /***********************************************************************
19978 Cursor types
19979 ***********************************************************************/
19980
19981 /* Value is the internal representation of the specified cursor type
19982 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19983 of the bar cursor. */
19984
19985 static enum text_cursor_kinds
19986 get_specified_cursor_type (arg, width)
19987 Lisp_Object arg;
19988 int *width;
19989 {
19990 enum text_cursor_kinds type;
19991
19992 if (NILP (arg))
19993 return NO_CURSOR;
19994
19995 if (EQ (arg, Qbox))
19996 return FILLED_BOX_CURSOR;
19997
19998 if (EQ (arg, Qhollow))
19999 return HOLLOW_BOX_CURSOR;
20000
20001 if (EQ (arg, Qbar))
20002 {
20003 *width = 2;
20004 return BAR_CURSOR;
20005 }
20006
20007 if (CONSP (arg)
20008 && EQ (XCAR (arg), Qbar)
20009 && INTEGERP (XCDR (arg))
20010 && XINT (XCDR (arg)) >= 0)
20011 {
20012 *width = XINT (XCDR (arg));
20013 return BAR_CURSOR;
20014 }
20015
20016 if (EQ (arg, Qhbar))
20017 {
20018 *width = 2;
20019 return HBAR_CURSOR;
20020 }
20021
20022 if (CONSP (arg)
20023 && EQ (XCAR (arg), Qhbar)
20024 && INTEGERP (XCDR (arg))
20025 && XINT (XCDR (arg)) >= 0)
20026 {
20027 *width = XINT (XCDR (arg));
20028 return HBAR_CURSOR;
20029 }
20030
20031 /* Treat anything unknown as "hollow box cursor".
20032 It was bad to signal an error; people have trouble fixing
20033 .Xdefaults with Emacs, when it has something bad in it. */
20034 type = HOLLOW_BOX_CURSOR;
20035
20036 return type;
20037 }
20038
20039 /* Set the default cursor types for specified frame. */
20040 void
20041 set_frame_cursor_types (f, arg)
20042 struct frame *f;
20043 Lisp_Object arg;
20044 {
20045 int width;
20046 Lisp_Object tem;
20047
20048 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
20049 FRAME_CURSOR_WIDTH (f) = width;
20050
20051 /* By default, set up the blink-off state depending on the on-state. */
20052
20053 tem = Fassoc (arg, Vblink_cursor_alist);
20054 if (!NILP (tem))
20055 {
20056 FRAME_BLINK_OFF_CURSOR (f)
20057 = get_specified_cursor_type (XCDR (tem), &width);
20058 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
20059 }
20060 else
20061 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
20062 }
20063
20064
20065 /* Return the cursor we want to be displayed in window W. Return
20066 width of bar/hbar cursor through WIDTH arg. Return with
20067 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
20068 (i.e. if the `system caret' should track this cursor).
20069
20070 In a mini-buffer window, we want the cursor only to appear if we
20071 are reading input from this window. For the selected window, we
20072 want the cursor type given by the frame parameter or buffer local
20073 setting of cursor-type. If explicitly marked off, draw no cursor.
20074 In all other cases, we want a hollow box cursor. */
20075
20076 static enum text_cursor_kinds
20077 get_window_cursor_type (w, glyph, width, active_cursor)
20078 struct window *w;
20079 struct glyph *glyph;
20080 int *width;
20081 int *active_cursor;
20082 {
20083 struct frame *f = XFRAME (w->frame);
20084 struct buffer *b = XBUFFER (w->buffer);
20085 int cursor_type = DEFAULT_CURSOR;
20086 Lisp_Object alt_cursor;
20087 int non_selected = 0;
20088
20089 *active_cursor = 1;
20090
20091 /* Echo area */
20092 if (cursor_in_echo_area
20093 && FRAME_HAS_MINIBUF_P (f)
20094 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
20095 {
20096 if (w == XWINDOW (echo_area_window))
20097 {
20098 *width = FRAME_CURSOR_WIDTH (f);
20099 return FRAME_DESIRED_CURSOR (f);
20100 }
20101
20102 *active_cursor = 0;
20103 non_selected = 1;
20104 }
20105
20106 /* Nonselected window or nonselected frame. */
20107 else if (w != XWINDOW (f->selected_window)
20108 #ifdef HAVE_WINDOW_SYSTEM
20109 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
20110 #endif
20111 )
20112 {
20113 *active_cursor = 0;
20114
20115 if (MINI_WINDOW_P (w) && minibuf_level == 0)
20116 return NO_CURSOR;
20117
20118 non_selected = 1;
20119 }
20120
20121 /* Never display a cursor in a window in which cursor-type is nil. */
20122 if (NILP (b->cursor_type))
20123 return NO_CURSOR;
20124
20125 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
20126 if (non_selected)
20127 {
20128 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
20129 return get_specified_cursor_type (alt_cursor, width);
20130 }
20131
20132 /* Get the normal cursor type for this window. */
20133 if (EQ (b->cursor_type, Qt))
20134 {
20135 cursor_type = FRAME_DESIRED_CURSOR (f);
20136 *width = FRAME_CURSOR_WIDTH (f);
20137 }
20138 else
20139 cursor_type = get_specified_cursor_type (b->cursor_type, width);
20140
20141 /* Use normal cursor if not blinked off. */
20142 if (!w->cursor_off_p)
20143 {
20144 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
20145 if (cursor_type == FILLED_BOX_CURSOR)
20146 cursor_type = HOLLOW_BOX_CURSOR;
20147 }
20148 return cursor_type;
20149 }
20150
20151 /* Cursor is blinked off, so determine how to "toggle" it. */
20152
20153 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
20154 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
20155 return get_specified_cursor_type (XCDR (alt_cursor), width);
20156
20157 /* Then see if frame has specified a specific blink off cursor type. */
20158 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
20159 {
20160 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
20161 return FRAME_BLINK_OFF_CURSOR (f);
20162 }
20163
20164 #if 0
20165 /* Some people liked having a permanently visible blinking cursor,
20166 while others had very strong opinions against it. So it was
20167 decided to remove it. KFS 2003-09-03 */
20168
20169 /* Finally perform built-in cursor blinking:
20170 filled box <-> hollow box
20171 wide [h]bar <-> narrow [h]bar
20172 narrow [h]bar <-> no cursor
20173 other type <-> no cursor */
20174
20175 if (cursor_type == FILLED_BOX_CURSOR)
20176 return HOLLOW_BOX_CURSOR;
20177
20178 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
20179 {
20180 *width = 1;
20181 return cursor_type;
20182 }
20183 #endif
20184
20185 return NO_CURSOR;
20186 }
20187
20188
20189 #ifdef HAVE_WINDOW_SYSTEM
20190
20191 /* Notice when the text cursor of window W has been completely
20192 overwritten by a drawing operation that outputs glyphs in AREA
20193 starting at X0 and ending at X1 in the line starting at Y0 and
20194 ending at Y1. X coordinates are area-relative. X1 < 0 means all
20195 the rest of the line after X0 has been written. Y coordinates
20196 are window-relative. */
20197
20198 static void
20199 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
20200 struct window *w;
20201 enum glyph_row_area area;
20202 int x0, y0, x1, y1;
20203 {
20204 int cx0, cx1, cy0, cy1;
20205 struct glyph_row *row;
20206
20207 if (!w->phys_cursor_on_p)
20208 return;
20209 if (area != TEXT_AREA)
20210 return;
20211
20212 if (w->phys_cursor.vpos < 0
20213 || w->phys_cursor.vpos >= w->current_matrix->nrows
20214 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
20215 !(row->enabled_p && row->displays_text_p)))
20216 return;
20217
20218 if (row->cursor_in_fringe_p)
20219 {
20220 row->cursor_in_fringe_p = 0;
20221 draw_fringe_bitmap (w, row, 0);
20222 w->phys_cursor_on_p = 0;
20223 return;
20224 }
20225
20226 cx0 = w->phys_cursor.x;
20227 cx1 = cx0 + w->phys_cursor_width;
20228 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
20229 return;
20230
20231 /* The cursor image will be completely removed from the
20232 screen if the output area intersects the cursor area in
20233 y-direction. When we draw in [y0 y1[, and some part of
20234 the cursor is at y < y0, that part must have been drawn
20235 before. When scrolling, the cursor is erased before
20236 actually scrolling, so we don't come here. When not
20237 scrolling, the rows above the old cursor row must have
20238 changed, and in this case these rows must have written
20239 over the cursor image.
20240
20241 Likewise if part of the cursor is below y1, with the
20242 exception of the cursor being in the first blank row at
20243 the buffer and window end because update_text_area
20244 doesn't draw that row. (Except when it does, but
20245 that's handled in update_text_area.) */
20246
20247 cy0 = w->phys_cursor.y;
20248 cy1 = cy0 + w->phys_cursor_height;
20249 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
20250 return;
20251
20252 w->phys_cursor_on_p = 0;
20253 }
20254
20255 #endif /* HAVE_WINDOW_SYSTEM */
20256
20257 \f
20258 /************************************************************************
20259 Mouse Face
20260 ************************************************************************/
20261
20262 #ifdef HAVE_WINDOW_SYSTEM
20263
20264 /* EXPORT for RIF:
20265 Fix the display of area AREA of overlapping row ROW in window W. */
20266
20267 void
20268 x_fix_overlapping_area (w, row, area)
20269 struct window *w;
20270 struct glyph_row *row;
20271 enum glyph_row_area area;
20272 {
20273 int i, x;
20274
20275 BLOCK_INPUT;
20276
20277 x = 0;
20278 for (i = 0; i < row->used[area];)
20279 {
20280 if (row->glyphs[area][i].overlaps_vertically_p)
20281 {
20282 int start = i, start_x = x;
20283
20284 do
20285 {
20286 x += row->glyphs[area][i].pixel_width;
20287 ++i;
20288 }
20289 while (i < row->used[area]
20290 && row->glyphs[area][i].overlaps_vertically_p);
20291
20292 draw_glyphs (w, start_x, row, area,
20293 start, i,
20294 DRAW_NORMAL_TEXT, 1);
20295 }
20296 else
20297 {
20298 x += row->glyphs[area][i].pixel_width;
20299 ++i;
20300 }
20301 }
20302
20303 UNBLOCK_INPUT;
20304 }
20305
20306
20307 /* EXPORT:
20308 Draw the cursor glyph of window W in glyph row ROW. See the
20309 comment of draw_glyphs for the meaning of HL. */
20310
20311 void
20312 draw_phys_cursor_glyph (w, row, hl)
20313 struct window *w;
20314 struct glyph_row *row;
20315 enum draw_glyphs_face hl;
20316 {
20317 /* If cursor hpos is out of bounds, don't draw garbage. This can
20318 happen in mini-buffer windows when switching between echo area
20319 glyphs and mini-buffer. */
20320 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
20321 {
20322 int on_p = w->phys_cursor_on_p;
20323 int x1;
20324 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
20325 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
20326 hl, 0);
20327 w->phys_cursor_on_p = on_p;
20328
20329 if (hl == DRAW_CURSOR)
20330 w->phys_cursor_width = x1 - w->phys_cursor.x;
20331 /* When we erase the cursor, and ROW is overlapped by other
20332 rows, make sure that these overlapping parts of other rows
20333 are redrawn. */
20334 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
20335 {
20336 if (row > w->current_matrix->rows
20337 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
20338 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
20339
20340 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
20341 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
20342 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
20343 }
20344 }
20345 }
20346
20347
20348 /* EXPORT:
20349 Erase the image of a cursor of window W from the screen. */
20350
20351 void
20352 erase_phys_cursor (w)
20353 struct window *w;
20354 {
20355 struct frame *f = XFRAME (w->frame);
20356 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20357 int hpos = w->phys_cursor.hpos;
20358 int vpos = w->phys_cursor.vpos;
20359 int mouse_face_here_p = 0;
20360 struct glyph_matrix *active_glyphs = w->current_matrix;
20361 struct glyph_row *cursor_row;
20362 struct glyph *cursor_glyph;
20363 enum draw_glyphs_face hl;
20364
20365 /* No cursor displayed or row invalidated => nothing to do on the
20366 screen. */
20367 if (w->phys_cursor_type == NO_CURSOR)
20368 goto mark_cursor_off;
20369
20370 /* VPOS >= active_glyphs->nrows means that window has been resized.
20371 Don't bother to erase the cursor. */
20372 if (vpos >= active_glyphs->nrows)
20373 goto mark_cursor_off;
20374
20375 /* If row containing cursor is marked invalid, there is nothing we
20376 can do. */
20377 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20378 if (!cursor_row->enabled_p)
20379 goto mark_cursor_off;
20380
20381 /* If line spacing is > 0, old cursor may only be partially visible in
20382 window after split-window. So adjust visible height. */
20383 cursor_row->visible_height = min (cursor_row->visible_height,
20384 window_text_bottom_y (w) - cursor_row->y);
20385
20386 /* If row is completely invisible, don't attempt to delete a cursor which
20387 isn't there. This can happen if cursor is at top of a window, and
20388 we switch to a buffer with a header line in that window. */
20389 if (cursor_row->visible_height <= 0)
20390 goto mark_cursor_off;
20391
20392 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20393 if (cursor_row->cursor_in_fringe_p)
20394 {
20395 cursor_row->cursor_in_fringe_p = 0;
20396 draw_fringe_bitmap (w, cursor_row, 0);
20397 goto mark_cursor_off;
20398 }
20399
20400 /* This can happen when the new row is shorter than the old one.
20401 In this case, either draw_glyphs or clear_end_of_line
20402 should have cleared the cursor. Note that we wouldn't be
20403 able to erase the cursor in this case because we don't have a
20404 cursor glyph at hand. */
20405 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20406 goto mark_cursor_off;
20407
20408 /* If the cursor is in the mouse face area, redisplay that when
20409 we clear the cursor. */
20410 if (! NILP (dpyinfo->mouse_face_window)
20411 && w == XWINDOW (dpyinfo->mouse_face_window)
20412 && (vpos > dpyinfo->mouse_face_beg_row
20413 || (vpos == dpyinfo->mouse_face_beg_row
20414 && hpos >= dpyinfo->mouse_face_beg_col))
20415 && (vpos < dpyinfo->mouse_face_end_row
20416 || (vpos == dpyinfo->mouse_face_end_row
20417 && hpos < dpyinfo->mouse_face_end_col))
20418 /* Don't redraw the cursor's spot in mouse face if it is at the
20419 end of a line (on a newline). The cursor appears there, but
20420 mouse highlighting does not. */
20421 && cursor_row->used[TEXT_AREA] > hpos)
20422 mouse_face_here_p = 1;
20423
20424 /* Maybe clear the display under the cursor. */
20425 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20426 {
20427 int x, y;
20428 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20429 int width;
20430
20431 cursor_glyph = get_phys_cursor_glyph (w);
20432 if (cursor_glyph == NULL)
20433 goto mark_cursor_off;
20434
20435 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20436 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20437 width = min (cursor_glyph->pixel_width,
20438 window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
20439
20440 rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
20441 }
20442
20443 /* Erase the cursor by redrawing the character underneath it. */
20444 if (mouse_face_here_p)
20445 hl = DRAW_MOUSE_FACE;
20446 else
20447 hl = DRAW_NORMAL_TEXT;
20448 draw_phys_cursor_glyph (w, cursor_row, hl);
20449
20450 mark_cursor_off:
20451 w->phys_cursor_on_p = 0;
20452 w->phys_cursor_type = NO_CURSOR;
20453 }
20454
20455
20456 /* EXPORT:
20457 Display or clear cursor of window W. If ON is zero, clear the
20458 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20459 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20460
20461 void
20462 display_and_set_cursor (w, on, hpos, vpos, x, y)
20463 struct window *w;
20464 int on, hpos, vpos, x, y;
20465 {
20466 struct frame *f = XFRAME (w->frame);
20467 int new_cursor_type;
20468 int new_cursor_width;
20469 int active_cursor;
20470 struct glyph_row *glyph_row;
20471 struct glyph *glyph;
20472
20473 /* This is pointless on invisible frames, and dangerous on garbaged
20474 windows and frames; in the latter case, the frame or window may
20475 be in the midst of changing its size, and x and y may be off the
20476 window. */
20477 if (! FRAME_VISIBLE_P (f)
20478 || FRAME_GARBAGED_P (f)
20479 || vpos >= w->current_matrix->nrows
20480 || hpos >= w->current_matrix->matrix_w)
20481 return;
20482
20483 /* If cursor is off and we want it off, return quickly. */
20484 if (!on && !w->phys_cursor_on_p)
20485 return;
20486
20487 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20488 /* If cursor row is not enabled, we don't really know where to
20489 display the cursor. */
20490 if (!glyph_row->enabled_p)
20491 {
20492 w->phys_cursor_on_p = 0;
20493 return;
20494 }
20495
20496 glyph = NULL;
20497 if (!glyph_row->exact_window_width_line_p
20498 || hpos < glyph_row->used[TEXT_AREA])
20499 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20500
20501 xassert (interrupt_input_blocked);
20502
20503 /* Set new_cursor_type to the cursor we want to be displayed. */
20504 new_cursor_type = get_window_cursor_type (w, glyph,
20505 &new_cursor_width, &active_cursor);
20506
20507 /* If cursor is currently being shown and we don't want it to be or
20508 it is in the wrong place, or the cursor type is not what we want,
20509 erase it. */
20510 if (w->phys_cursor_on_p
20511 && (!on
20512 || w->phys_cursor.x != x
20513 || w->phys_cursor.y != y
20514 || new_cursor_type != w->phys_cursor_type
20515 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20516 && new_cursor_width != w->phys_cursor_width)))
20517 erase_phys_cursor (w);
20518
20519 /* Don't check phys_cursor_on_p here because that flag is only set
20520 to zero in some cases where we know that the cursor has been
20521 completely erased, to avoid the extra work of erasing the cursor
20522 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20523 still not be visible, or it has only been partly erased. */
20524 if (on)
20525 {
20526 w->phys_cursor_ascent = glyph_row->ascent;
20527 w->phys_cursor_height = glyph_row->height;
20528
20529 /* Set phys_cursor_.* before x_draw_.* is called because some
20530 of them may need the information. */
20531 w->phys_cursor.x = x;
20532 w->phys_cursor.y = glyph_row->y;
20533 w->phys_cursor.hpos = hpos;
20534 w->phys_cursor.vpos = vpos;
20535 }
20536
20537 rif->draw_window_cursor (w, glyph_row, x, y,
20538 new_cursor_type, new_cursor_width,
20539 on, active_cursor);
20540 }
20541
20542
20543 /* Switch the display of W's cursor on or off, according to the value
20544 of ON. */
20545
20546 static void
20547 update_window_cursor (w, on)
20548 struct window *w;
20549 int on;
20550 {
20551 /* Don't update cursor in windows whose frame is in the process
20552 of being deleted. */
20553 if (w->current_matrix)
20554 {
20555 BLOCK_INPUT;
20556 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20557 w->phys_cursor.x, w->phys_cursor.y);
20558 UNBLOCK_INPUT;
20559 }
20560 }
20561
20562
20563 /* Call update_window_cursor with parameter ON_P on all leaf windows
20564 in the window tree rooted at W. */
20565
20566 static void
20567 update_cursor_in_window_tree (w, on_p)
20568 struct window *w;
20569 int on_p;
20570 {
20571 while (w)
20572 {
20573 if (!NILP (w->hchild))
20574 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20575 else if (!NILP (w->vchild))
20576 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20577 else
20578 update_window_cursor (w, on_p);
20579
20580 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20581 }
20582 }
20583
20584
20585 /* EXPORT:
20586 Display the cursor on window W, or clear it, according to ON_P.
20587 Don't change the cursor's position. */
20588
20589 void
20590 x_update_cursor (f, on_p)
20591 struct frame *f;
20592 int on_p;
20593 {
20594 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20595 }
20596
20597
20598 /* EXPORT:
20599 Clear the cursor of window W to background color, and mark the
20600 cursor as not shown. This is used when the text where the cursor
20601 is is about to be rewritten. */
20602
20603 void
20604 x_clear_cursor (w)
20605 struct window *w;
20606 {
20607 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20608 update_window_cursor (w, 0);
20609 }
20610
20611
20612 /* EXPORT:
20613 Display the active region described by mouse_face_* according to DRAW. */
20614
20615 void
20616 show_mouse_face (dpyinfo, draw)
20617 Display_Info *dpyinfo;
20618 enum draw_glyphs_face draw;
20619 {
20620 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20621 struct frame *f = XFRAME (WINDOW_FRAME (w));
20622
20623 if (/* If window is in the process of being destroyed, don't bother
20624 to do anything. */
20625 w->current_matrix != NULL
20626 /* Don't update mouse highlight if hidden */
20627 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20628 /* Recognize when we are called to operate on rows that don't exist
20629 anymore. This can happen when a window is split. */
20630 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20631 {
20632 int phys_cursor_on_p = w->phys_cursor_on_p;
20633 struct glyph_row *row, *first, *last;
20634
20635 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20636 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20637
20638 for (row = first; row <= last && row->enabled_p; ++row)
20639 {
20640 int start_hpos, end_hpos, start_x;
20641
20642 /* For all but the first row, the highlight starts at column 0. */
20643 if (row == first)
20644 {
20645 start_hpos = dpyinfo->mouse_face_beg_col;
20646 start_x = dpyinfo->mouse_face_beg_x;
20647 }
20648 else
20649 {
20650 start_hpos = 0;
20651 start_x = 0;
20652 }
20653
20654 if (row == last)
20655 end_hpos = dpyinfo->mouse_face_end_col;
20656 else
20657 end_hpos = row->used[TEXT_AREA];
20658
20659 if (end_hpos > start_hpos)
20660 {
20661 draw_glyphs (w, start_x, row, TEXT_AREA,
20662 start_hpos, end_hpos,
20663 draw, 0);
20664
20665 row->mouse_face_p
20666 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20667 }
20668 }
20669
20670 /* When we've written over the cursor, arrange for it to
20671 be displayed again. */
20672 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20673 {
20674 BLOCK_INPUT;
20675 display_and_set_cursor (w, 1,
20676 w->phys_cursor.hpos, w->phys_cursor.vpos,
20677 w->phys_cursor.x, w->phys_cursor.y);
20678 UNBLOCK_INPUT;
20679 }
20680 }
20681
20682 /* Change the mouse cursor. */
20683 if (draw == DRAW_NORMAL_TEXT)
20684 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20685 else if (draw == DRAW_MOUSE_FACE)
20686 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20687 else
20688 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20689 }
20690
20691 /* EXPORT:
20692 Clear out the mouse-highlighted active region.
20693 Redraw it un-highlighted first. Value is non-zero if mouse
20694 face was actually drawn unhighlighted. */
20695
20696 int
20697 clear_mouse_face (dpyinfo)
20698 Display_Info *dpyinfo;
20699 {
20700 int cleared = 0;
20701
20702 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20703 {
20704 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20705 cleared = 1;
20706 }
20707
20708 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20709 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20710 dpyinfo->mouse_face_window = Qnil;
20711 dpyinfo->mouse_face_overlay = Qnil;
20712 return cleared;
20713 }
20714
20715
20716 /* EXPORT:
20717 Non-zero if physical cursor of window W is within mouse face. */
20718
20719 int
20720 cursor_in_mouse_face_p (w)
20721 struct window *w;
20722 {
20723 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20724 int in_mouse_face = 0;
20725
20726 if (WINDOWP (dpyinfo->mouse_face_window)
20727 && XWINDOW (dpyinfo->mouse_face_window) == w)
20728 {
20729 int hpos = w->phys_cursor.hpos;
20730 int vpos = w->phys_cursor.vpos;
20731
20732 if (vpos >= dpyinfo->mouse_face_beg_row
20733 && vpos <= dpyinfo->mouse_face_end_row
20734 && (vpos > dpyinfo->mouse_face_beg_row
20735 || hpos >= dpyinfo->mouse_face_beg_col)
20736 && (vpos < dpyinfo->mouse_face_end_row
20737 || hpos < dpyinfo->mouse_face_end_col
20738 || dpyinfo->mouse_face_past_end))
20739 in_mouse_face = 1;
20740 }
20741
20742 return in_mouse_face;
20743 }
20744
20745
20746
20747 \f
20748 /* Find the glyph matrix position of buffer position CHARPOS in window
20749 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20750 current glyphs must be up to date. If CHARPOS is above window
20751 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20752 of last line in W. In the row containing CHARPOS, stop before glyphs
20753 having STOP as object. */
20754
20755 #if 1 /* This is a version of fast_find_position that's more correct
20756 in the presence of hscrolling, for example. I didn't install
20757 it right away because the problem fixed is minor, it failed
20758 in 20.x as well, and I think it's too risky to install
20759 so near the release of 21.1. 2001-09-25 gerd. */
20760
20761 static int
20762 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20763 struct window *w;
20764 int charpos;
20765 int *hpos, *vpos, *x, *y;
20766 Lisp_Object stop;
20767 {
20768 struct glyph_row *row, *first;
20769 struct glyph *glyph, *end;
20770 int past_end = 0;
20771
20772 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20773 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20774 {
20775 *x = first->x;
20776 *y = first->y;
20777 *hpos = 0;
20778 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
20779 return 1;
20780 }
20781
20782 row = row_containing_pos (w, charpos, first, NULL, 0);
20783 if (row == NULL)
20784 {
20785 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20786 past_end = 1;
20787 }
20788
20789 /* If whole rows or last part of a row came from a display overlay,
20790 row_containing_pos will skip over such rows because their end pos
20791 equals the start pos of the overlay or interval.
20792
20793 Move back if we have a STOP object and previous row's
20794 end glyph came from STOP. */
20795 if (!NILP (stop))
20796 {
20797 struct glyph_row *prev;
20798 while ((prev = row - 1, prev >= first)
20799 && MATRIX_ROW_END_CHARPOS (prev) == charpos
20800 && prev->used[TEXT_AREA] > 0)
20801 {
20802 struct glyph *beg = prev->glyphs[TEXT_AREA];
20803 glyph = beg + prev->used[TEXT_AREA];
20804 while (--glyph >= beg
20805 && INTEGERP (glyph->object));
20806 if (glyph < beg
20807 || !EQ (stop, glyph->object))
20808 break;
20809 row = prev;
20810 }
20811 }
20812
20813 *x = row->x;
20814 *y = row->y;
20815 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20816
20817 glyph = row->glyphs[TEXT_AREA];
20818 end = glyph + row->used[TEXT_AREA];
20819
20820 /* Skip over glyphs not having an object at the start of the row.
20821 These are special glyphs like truncation marks on terminal
20822 frames. */
20823 if (row->displays_text_p)
20824 while (glyph < end
20825 && INTEGERP (glyph->object)
20826 && !EQ (stop, glyph->object)
20827 && glyph->charpos < 0)
20828 {
20829 *x += glyph->pixel_width;
20830 ++glyph;
20831 }
20832
20833 while (glyph < end
20834 && !INTEGERP (glyph->object)
20835 && !EQ (stop, glyph->object)
20836 && (!BUFFERP (glyph->object)
20837 || glyph->charpos < charpos))
20838 {
20839 *x += glyph->pixel_width;
20840 ++glyph;
20841 }
20842
20843 *hpos = glyph - row->glyphs[TEXT_AREA];
20844 return !past_end;
20845 }
20846
20847 #else /* not 1 */
20848
20849 static int
20850 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20851 struct window *w;
20852 int pos;
20853 int *hpos, *vpos, *x, *y;
20854 Lisp_Object stop;
20855 {
20856 int i;
20857 int lastcol;
20858 int maybe_next_line_p = 0;
20859 int line_start_position;
20860 int yb = window_text_bottom_y (w);
20861 struct glyph_row *row, *best_row;
20862 int row_vpos, best_row_vpos;
20863 int current_x;
20864
20865 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20866 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20867
20868 while (row->y < yb)
20869 {
20870 if (row->used[TEXT_AREA])
20871 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20872 else
20873 line_start_position = 0;
20874
20875 if (line_start_position > pos)
20876 break;
20877 /* If the position sought is the end of the buffer,
20878 don't include the blank lines at the bottom of the window. */
20879 else if (line_start_position == pos
20880 && pos == BUF_ZV (XBUFFER (w->buffer)))
20881 {
20882 maybe_next_line_p = 1;
20883 break;
20884 }
20885 else if (line_start_position > 0)
20886 {
20887 best_row = row;
20888 best_row_vpos = row_vpos;
20889 }
20890
20891 if (row->y + row->height >= yb)
20892 break;
20893
20894 ++row;
20895 ++row_vpos;
20896 }
20897
20898 /* Find the right column within BEST_ROW. */
20899 lastcol = 0;
20900 current_x = best_row->x;
20901 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20902 {
20903 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20904 int charpos = glyph->charpos;
20905
20906 if (BUFFERP (glyph->object))
20907 {
20908 if (charpos == pos)
20909 {
20910 *hpos = i;
20911 *vpos = best_row_vpos;
20912 *x = current_x;
20913 *y = best_row->y;
20914 return 1;
20915 }
20916 else if (charpos > pos)
20917 break;
20918 }
20919 else if (EQ (glyph->object, stop))
20920 break;
20921
20922 if (charpos > 0)
20923 lastcol = i;
20924 current_x += glyph->pixel_width;
20925 }
20926
20927 /* If we're looking for the end of the buffer,
20928 and we didn't find it in the line we scanned,
20929 use the start of the following line. */
20930 if (maybe_next_line_p)
20931 {
20932 ++best_row;
20933 ++best_row_vpos;
20934 lastcol = 0;
20935 current_x = best_row->x;
20936 }
20937
20938 *vpos = best_row_vpos;
20939 *hpos = lastcol + 1;
20940 *x = current_x;
20941 *y = best_row->y;
20942 return 0;
20943 }
20944
20945 #endif /* not 1 */
20946
20947
20948 /* Find the position of the glyph for position POS in OBJECT in
20949 window W's current matrix, and return in *X, *Y the pixel
20950 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20951
20952 RIGHT_P non-zero means return the position of the right edge of the
20953 glyph, RIGHT_P zero means return the left edge position.
20954
20955 If no glyph for POS exists in the matrix, return the position of
20956 the glyph with the next smaller position that is in the matrix, if
20957 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20958 exists in the matrix, return the position of the glyph with the
20959 next larger position in OBJECT.
20960
20961 Value is non-zero if a glyph was found. */
20962
20963 static int
20964 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20965 struct window *w;
20966 int pos;
20967 Lisp_Object object;
20968 int *hpos, *vpos, *x, *y;
20969 int right_p;
20970 {
20971 int yb = window_text_bottom_y (w);
20972 struct glyph_row *r;
20973 struct glyph *best_glyph = NULL;
20974 struct glyph_row *best_row = NULL;
20975 int best_x = 0;
20976
20977 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20978 r->enabled_p && r->y < yb;
20979 ++r)
20980 {
20981 struct glyph *g = r->glyphs[TEXT_AREA];
20982 struct glyph *e = g + r->used[TEXT_AREA];
20983 int gx;
20984
20985 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20986 if (EQ (g->object, object))
20987 {
20988 if (g->charpos == pos)
20989 {
20990 best_glyph = g;
20991 best_x = gx;
20992 best_row = r;
20993 goto found;
20994 }
20995 else if (best_glyph == NULL
20996 || ((abs (g->charpos - pos)
20997 < abs (best_glyph->charpos - pos))
20998 && (right_p
20999 ? g->charpos < pos
21000 : g->charpos > pos)))
21001 {
21002 best_glyph = g;
21003 best_x = gx;
21004 best_row = r;
21005 }
21006 }
21007 }
21008
21009 found:
21010
21011 if (best_glyph)
21012 {
21013 *x = best_x;
21014 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
21015
21016 if (right_p)
21017 {
21018 *x += best_glyph->pixel_width;
21019 ++*hpos;
21020 }
21021
21022 *y = best_row->y;
21023 *vpos = best_row - w->current_matrix->rows;
21024 }
21025
21026 return best_glyph != NULL;
21027 }
21028
21029
21030 /* See if position X, Y is within a hot-spot of an image. */
21031
21032 static int
21033 on_hot_spot_p (hot_spot, x, y)
21034 Lisp_Object hot_spot;
21035 int x, y;
21036 {
21037 if (!CONSP (hot_spot))
21038 return 0;
21039
21040 if (EQ (XCAR (hot_spot), Qrect))
21041 {
21042 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
21043 Lisp_Object rect = XCDR (hot_spot);
21044 Lisp_Object tem;
21045 if (!CONSP (rect))
21046 return 0;
21047 if (!CONSP (XCAR (rect)))
21048 return 0;
21049 if (!CONSP (XCDR (rect)))
21050 return 0;
21051 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
21052 return 0;
21053 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
21054 return 0;
21055 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
21056 return 0;
21057 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
21058 return 0;
21059 return 1;
21060 }
21061 else if (EQ (XCAR (hot_spot), Qcircle))
21062 {
21063 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
21064 Lisp_Object circ = XCDR (hot_spot);
21065 Lisp_Object lr, lx0, ly0;
21066 if (CONSP (circ)
21067 && CONSP (XCAR (circ))
21068 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
21069 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
21070 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
21071 {
21072 double r = XFLOATINT (lr);
21073 double dx = XINT (lx0) - x;
21074 double dy = XINT (ly0) - y;
21075 return (dx * dx + dy * dy <= r * r);
21076 }
21077 }
21078 else if (EQ (XCAR (hot_spot), Qpoly))
21079 {
21080 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
21081 if (VECTORP (XCDR (hot_spot)))
21082 {
21083 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
21084 Lisp_Object *poly = v->contents;
21085 int n = v->size;
21086 int i;
21087 int inside = 0;
21088 Lisp_Object lx, ly;
21089 int x0, y0;
21090
21091 /* Need an even number of coordinates, and at least 3 edges. */
21092 if (n < 6 || n & 1)
21093 return 0;
21094
21095 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
21096 If count is odd, we are inside polygon. Pixels on edges
21097 may or may not be included depending on actual geometry of the
21098 polygon. */
21099 if ((lx = poly[n-2], !INTEGERP (lx))
21100 || (ly = poly[n-1], !INTEGERP (lx)))
21101 return 0;
21102 x0 = XINT (lx), y0 = XINT (ly);
21103 for (i = 0; i < n; i += 2)
21104 {
21105 int x1 = x0, y1 = y0;
21106 if ((lx = poly[i], !INTEGERP (lx))
21107 || (ly = poly[i+1], !INTEGERP (ly)))
21108 return 0;
21109 x0 = XINT (lx), y0 = XINT (ly);
21110
21111 /* Does this segment cross the X line? */
21112 if (x0 >= x)
21113 {
21114 if (x1 >= x)
21115 continue;
21116 }
21117 else if (x1 < x)
21118 continue;
21119 if (y > y0 && y > y1)
21120 continue;
21121 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
21122 inside = !inside;
21123 }
21124 return inside;
21125 }
21126 }
21127 /* If we don't understand the format, pretend we're not in the hot-spot. */
21128 return 0;
21129 }
21130
21131 Lisp_Object
21132 find_hot_spot (map, x, y)
21133 Lisp_Object map;
21134 int x, y;
21135 {
21136 while (CONSP (map))
21137 {
21138 if (CONSP (XCAR (map))
21139 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
21140 return XCAR (map);
21141 map = XCDR (map);
21142 }
21143
21144 return Qnil;
21145 }
21146
21147 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
21148 3, 3, 0,
21149 doc: /* Lookup in image map MAP coordinates X and Y.
21150 An image map is an alist where each element has the format (AREA ID PLIST).
21151 An AREA is specified as either a rectangle, a circle, or a polygon:
21152 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
21153 pixel coordinates of the upper left and bottom right corners.
21154 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
21155 and the radius of the circle; r may be a float or integer.
21156 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
21157 vector describes one corner in the polygon.
21158 Returns the alist element for the first matching AREA in MAP. */)
21159 (map, x, y)
21160 Lisp_Object map;
21161 Lisp_Object x, y;
21162 {
21163 if (NILP (map))
21164 return Qnil;
21165
21166 CHECK_NUMBER (x);
21167 CHECK_NUMBER (y);
21168
21169 return find_hot_spot (map, XINT (x), XINT (y));
21170 }
21171
21172
21173 /* Display frame CURSOR, optionally using shape defined by POINTER. */
21174 static void
21175 define_frame_cursor1 (f, cursor, pointer)
21176 struct frame *f;
21177 Cursor cursor;
21178 Lisp_Object pointer;
21179 {
21180 /* Do not change cursor shape while dragging mouse. */
21181 if (!NILP (do_mouse_tracking))
21182 return;
21183
21184 if (!NILP (pointer))
21185 {
21186 if (EQ (pointer, Qarrow))
21187 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21188 else if (EQ (pointer, Qhand))
21189 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
21190 else if (EQ (pointer, Qtext))
21191 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21192 else if (EQ (pointer, intern ("hdrag")))
21193 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21194 #ifdef HAVE_X_WINDOWS
21195 else if (EQ (pointer, intern ("vdrag")))
21196 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
21197 #endif
21198 else if (EQ (pointer, intern ("hourglass")))
21199 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
21200 else if (EQ (pointer, Qmodeline))
21201 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
21202 else
21203 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21204 }
21205
21206 if (cursor != No_Cursor)
21207 rif->define_frame_cursor (f, cursor);
21208 }
21209
21210 /* Take proper action when mouse has moved to the mode or header line
21211 or marginal area AREA of window W, x-position X and y-position Y.
21212 X is relative to the start of the text display area of W, so the
21213 width of bitmap areas and scroll bars must be subtracted to get a
21214 position relative to the start of the mode line. */
21215
21216 static void
21217 note_mode_line_or_margin_highlight (w, x, y, area)
21218 struct window *w;
21219 int x, y;
21220 enum window_part area;
21221 {
21222 struct frame *f = XFRAME (w->frame);
21223 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21224 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21225 Lisp_Object pointer = Qnil;
21226 int charpos, dx, dy, width, height;
21227 Lisp_Object string, object = Qnil;
21228 Lisp_Object pos, help;
21229
21230 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
21231 string = mode_line_string (w, area, &x, &y, &charpos,
21232 &object, &dx, &dy, &width, &height);
21233 else
21234 {
21235 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
21236 string = marginal_area_string (w, area, &x, &y, &charpos,
21237 &object, &dx, &dy, &width, &height);
21238 }
21239
21240 help = Qnil;
21241
21242 if (IMAGEP (object))
21243 {
21244 Lisp_Object image_map, hotspot;
21245 if ((image_map = Fplist_get (XCDR (object), QCmap),
21246 !NILP (image_map))
21247 && (hotspot = find_hot_spot (image_map, dx, dy),
21248 CONSP (hotspot))
21249 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21250 {
21251 Lisp_Object area_id, plist;
21252
21253 area_id = XCAR (hotspot);
21254 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21255 If so, we could look for mouse-enter, mouse-leave
21256 properties in PLIST (and do something...). */
21257 hotspot = XCDR (hotspot);
21258 if (CONSP (hotspot)
21259 && (plist = XCAR (hotspot), CONSP (plist)))
21260 {
21261 pointer = Fplist_get (plist, Qpointer);
21262 if (NILP (pointer))
21263 pointer = Qhand;
21264 help = Fplist_get (plist, Qhelp_echo);
21265 if (!NILP (help))
21266 {
21267 help_echo_string = help;
21268 /* Is this correct? ++kfs */
21269 XSETWINDOW (help_echo_window, w);
21270 help_echo_object = w->buffer;
21271 help_echo_pos = charpos;
21272 }
21273 }
21274 }
21275 if (NILP (pointer))
21276 pointer = Fplist_get (XCDR (object), QCpointer);
21277 }
21278
21279 if (STRINGP (string))
21280 {
21281 pos = make_number (charpos);
21282 /* If we're on a string with `help-echo' text property, arrange
21283 for the help to be displayed. This is done by setting the
21284 global variable help_echo_string to the help string. */
21285 if (NILP (help))
21286 {
21287 help = Fget_text_property (pos, Qhelp_echo, string);
21288 if (!NILP (help))
21289 {
21290 help_echo_string = help;
21291 XSETWINDOW (help_echo_window, w);
21292 help_echo_object = string;
21293 help_echo_pos = charpos;
21294 }
21295 }
21296
21297 if (NILP (pointer))
21298 pointer = Fget_text_property (pos, Qpointer, string);
21299
21300 /* Change the mouse pointer according to what is under X/Y. */
21301 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
21302 {
21303 Lisp_Object map;
21304 map = Fget_text_property (pos, Qlocal_map, string);
21305 if (!KEYMAPP (map))
21306 map = Fget_text_property (pos, Qkeymap, string);
21307 if (!KEYMAPP (map))
21308 cursor = dpyinfo->vertical_scroll_bar_cursor;
21309 }
21310 }
21311
21312 define_frame_cursor1 (f, cursor, pointer);
21313 }
21314
21315
21316 /* EXPORT:
21317 Take proper action when the mouse has moved to position X, Y on
21318 frame F as regards highlighting characters that have mouse-face
21319 properties. Also de-highlighting chars where the mouse was before.
21320 X and Y can be negative or out of range. */
21321
21322 void
21323 note_mouse_highlight (f, x, y)
21324 struct frame *f;
21325 int x, y;
21326 {
21327 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21328 enum window_part part;
21329 Lisp_Object window;
21330 struct window *w;
21331 Cursor cursor = No_Cursor;
21332 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
21333 struct buffer *b;
21334
21335 /* When a menu is active, don't highlight because this looks odd. */
21336 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
21337 if (popup_activated ())
21338 return;
21339 #endif
21340
21341 if (NILP (Vmouse_highlight)
21342 || !f->glyphs_initialized_p)
21343 return;
21344
21345 dpyinfo->mouse_face_mouse_x = x;
21346 dpyinfo->mouse_face_mouse_y = y;
21347 dpyinfo->mouse_face_mouse_frame = f;
21348
21349 if (dpyinfo->mouse_face_defer)
21350 return;
21351
21352 if (gc_in_progress)
21353 {
21354 dpyinfo->mouse_face_deferred_gc = 1;
21355 return;
21356 }
21357
21358 /* Which window is that in? */
21359 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
21360
21361 /* If we were displaying active text in another window, clear that.
21362 Also clear if we move out of text area in same window. */
21363 if (! EQ (window, dpyinfo->mouse_face_window)
21364 || (part != ON_TEXT && !NILP (dpyinfo->mouse_face_window)))
21365 clear_mouse_face (dpyinfo);
21366
21367 /* Not on a window -> return. */
21368 if (!WINDOWP (window))
21369 return;
21370
21371 /* Reset help_echo_string. It will get recomputed below. */
21372 help_echo_string = Qnil;
21373
21374 /* Convert to window-relative pixel coordinates. */
21375 w = XWINDOW (window);
21376 frame_to_window_pixel_xy (w, &x, &y);
21377
21378 /* Handle tool-bar window differently since it doesn't display a
21379 buffer. */
21380 if (EQ (window, f->tool_bar_window))
21381 {
21382 note_tool_bar_highlight (f, x, y);
21383 return;
21384 }
21385
21386 /* Mouse is on the mode, header line or margin? */
21387 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
21388 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
21389 {
21390 note_mode_line_or_margin_highlight (w, x, y, part);
21391 return;
21392 }
21393
21394 if (part == ON_VERTICAL_BORDER)
21395 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21396 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21397 || part == ON_SCROLL_BAR)
21398 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21399 else
21400 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21401
21402 /* Are we in a window whose display is up to date?
21403 And verify the buffer's text has not changed. */
21404 b = XBUFFER (w->buffer);
21405 if (part == ON_TEXT
21406 && EQ (w->window_end_valid, w->buffer)
21407 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
21408 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
21409 {
21410 int hpos, vpos, pos, i, dx, dy, area;
21411 struct glyph *glyph;
21412 Lisp_Object object;
21413 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21414 Lisp_Object *overlay_vec = NULL;
21415 int noverlays;
21416 struct buffer *obuf;
21417 int obegv, ozv, same_region;
21418
21419 /* Find the glyph under X/Y. */
21420 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21421
21422 /* Look for :pointer property on image. */
21423 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21424 {
21425 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21426 if (img != NULL && IMAGEP (img->spec))
21427 {
21428 Lisp_Object image_map, hotspot;
21429 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
21430 !NILP (image_map))
21431 && (hotspot = find_hot_spot (image_map,
21432 glyph->slice.x + dx,
21433 glyph->slice.y + dy),
21434 CONSP (hotspot))
21435 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21436 {
21437 Lisp_Object area_id, plist;
21438
21439 area_id = XCAR (hotspot);
21440 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21441 If so, we could look for mouse-enter, mouse-leave
21442 properties in PLIST (and do something...). */
21443 hotspot = XCDR (hotspot);
21444 if (CONSP (hotspot)
21445 && (plist = XCAR (hotspot), CONSP (plist)))
21446 {
21447 pointer = Fplist_get (plist, Qpointer);
21448 if (NILP (pointer))
21449 pointer = Qhand;
21450 help_echo_string = Fplist_get (plist, Qhelp_echo);
21451 if (!NILP (help_echo_string))
21452 {
21453 help_echo_window = window;
21454 help_echo_object = glyph->object;
21455 help_echo_pos = glyph->charpos;
21456 }
21457 }
21458 }
21459 if (NILP (pointer))
21460 pointer = Fplist_get (XCDR (img->spec), QCpointer);
21461 }
21462 }
21463
21464 /* Clear mouse face if X/Y not over text. */
21465 if (glyph == NULL
21466 || area != TEXT_AREA
21467 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21468 {
21469 if (clear_mouse_face (dpyinfo))
21470 cursor = No_Cursor;
21471 if (NILP (pointer))
21472 {
21473 if (area != TEXT_AREA)
21474 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21475 else
21476 pointer = Vvoid_text_area_pointer;
21477 }
21478 goto set_cursor;
21479 }
21480
21481 pos = glyph->charpos;
21482 object = glyph->object;
21483 if (!STRINGP (object) && !BUFFERP (object))
21484 goto set_cursor;
21485
21486 /* If we get an out-of-range value, return now; avoid an error. */
21487 if (BUFFERP (object) && pos > BUF_Z (b))
21488 goto set_cursor;
21489
21490 /* Make the window's buffer temporarily current for
21491 overlays_at and compute_char_face. */
21492 obuf = current_buffer;
21493 current_buffer = b;
21494 obegv = BEGV;
21495 ozv = ZV;
21496 BEGV = BEG;
21497 ZV = Z;
21498
21499 /* Is this char mouse-active or does it have help-echo? */
21500 position = make_number (pos);
21501
21502 if (BUFFERP (object))
21503 {
21504 /* Put all the overlays we want in a vector in overlay_vec. */
21505 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21506 /* Sort overlays into increasing priority order. */
21507 noverlays = sort_overlays (overlay_vec, noverlays, w);
21508 }
21509 else
21510 noverlays = 0;
21511
21512 same_region = (EQ (window, dpyinfo->mouse_face_window)
21513 && vpos >= dpyinfo->mouse_face_beg_row
21514 && vpos <= dpyinfo->mouse_face_end_row
21515 && (vpos > dpyinfo->mouse_face_beg_row
21516 || hpos >= dpyinfo->mouse_face_beg_col)
21517 && (vpos < dpyinfo->mouse_face_end_row
21518 || hpos < dpyinfo->mouse_face_end_col
21519 || dpyinfo->mouse_face_past_end));
21520
21521 if (same_region)
21522 cursor = No_Cursor;
21523
21524 /* Check mouse-face highlighting. */
21525 if (! same_region
21526 /* If there exists an overlay with mouse-face overlapping
21527 the one we are currently highlighting, we have to
21528 check if we enter the overlapping overlay, and then
21529 highlight only that. */
21530 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21531 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21532 {
21533 /* Find the highest priority overlay that has a mouse-face
21534 property. */
21535 overlay = Qnil;
21536 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21537 {
21538 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21539 if (!NILP (mouse_face))
21540 overlay = overlay_vec[i];
21541 }
21542
21543 /* If we're actually highlighting the same overlay as
21544 before, there's no need to do that again. */
21545 if (!NILP (overlay)
21546 && EQ (overlay, dpyinfo->mouse_face_overlay))
21547 goto check_help_echo;
21548
21549 dpyinfo->mouse_face_overlay = overlay;
21550
21551 /* Clear the display of the old active region, if any. */
21552 if (clear_mouse_face (dpyinfo))
21553 cursor = No_Cursor;
21554
21555 /* If no overlay applies, get a text property. */
21556 if (NILP (overlay))
21557 mouse_face = Fget_text_property (position, Qmouse_face, object);
21558
21559 /* Handle the overlay case. */
21560 if (!NILP (overlay))
21561 {
21562 /* Find the range of text around this char that
21563 should be active. */
21564 Lisp_Object before, after;
21565 int ignore;
21566
21567 before = Foverlay_start (overlay);
21568 after = Foverlay_end (overlay);
21569 /* Record this as the current active region. */
21570 fast_find_position (w, XFASTINT (before),
21571 &dpyinfo->mouse_face_beg_col,
21572 &dpyinfo->mouse_face_beg_row,
21573 &dpyinfo->mouse_face_beg_x,
21574 &dpyinfo->mouse_face_beg_y, Qnil);
21575
21576 dpyinfo->mouse_face_past_end
21577 = !fast_find_position (w, XFASTINT (after),
21578 &dpyinfo->mouse_face_end_col,
21579 &dpyinfo->mouse_face_end_row,
21580 &dpyinfo->mouse_face_end_x,
21581 &dpyinfo->mouse_face_end_y, Qnil);
21582 dpyinfo->mouse_face_window = window;
21583
21584 dpyinfo->mouse_face_face_id
21585 = face_at_buffer_position (w, pos, 0, 0,
21586 &ignore, pos + 1,
21587 !dpyinfo->mouse_face_hidden);
21588
21589 /* Display it as active. */
21590 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21591 cursor = No_Cursor;
21592 }
21593 /* Handle the text property case. */
21594 else if (!NILP (mouse_face) && BUFFERP (object))
21595 {
21596 /* Find the range of text around this char that
21597 should be active. */
21598 Lisp_Object before, after, beginning, end;
21599 int ignore;
21600
21601 beginning = Fmarker_position (w->start);
21602 end = make_number (BUF_Z (XBUFFER (object))
21603 - XFASTINT (w->window_end_pos));
21604 before
21605 = Fprevious_single_property_change (make_number (pos + 1),
21606 Qmouse_face,
21607 object, beginning);
21608 after
21609 = Fnext_single_property_change (position, Qmouse_face,
21610 object, end);
21611
21612 /* Record this as the current active region. */
21613 fast_find_position (w, XFASTINT (before),
21614 &dpyinfo->mouse_face_beg_col,
21615 &dpyinfo->mouse_face_beg_row,
21616 &dpyinfo->mouse_face_beg_x,
21617 &dpyinfo->mouse_face_beg_y, Qnil);
21618 dpyinfo->mouse_face_past_end
21619 = !fast_find_position (w, XFASTINT (after),
21620 &dpyinfo->mouse_face_end_col,
21621 &dpyinfo->mouse_face_end_row,
21622 &dpyinfo->mouse_face_end_x,
21623 &dpyinfo->mouse_face_end_y, Qnil);
21624 dpyinfo->mouse_face_window = window;
21625
21626 if (BUFFERP (object))
21627 dpyinfo->mouse_face_face_id
21628 = face_at_buffer_position (w, pos, 0, 0,
21629 &ignore, pos + 1,
21630 !dpyinfo->mouse_face_hidden);
21631
21632 /* Display it as active. */
21633 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21634 cursor = No_Cursor;
21635 }
21636 else if (!NILP (mouse_face) && STRINGP (object))
21637 {
21638 Lisp_Object b, e;
21639 int ignore;
21640
21641 b = Fprevious_single_property_change (make_number (pos + 1),
21642 Qmouse_face,
21643 object, Qnil);
21644 e = Fnext_single_property_change (position, Qmouse_face,
21645 object, Qnil);
21646 if (NILP (b))
21647 b = make_number (0);
21648 if (NILP (e))
21649 e = make_number (SCHARS (object) - 1);
21650 fast_find_string_pos (w, XINT (b), object,
21651 &dpyinfo->mouse_face_beg_col,
21652 &dpyinfo->mouse_face_beg_row,
21653 &dpyinfo->mouse_face_beg_x,
21654 &dpyinfo->mouse_face_beg_y, 0);
21655 fast_find_string_pos (w, XINT (e), object,
21656 &dpyinfo->mouse_face_end_col,
21657 &dpyinfo->mouse_face_end_row,
21658 &dpyinfo->mouse_face_end_x,
21659 &dpyinfo->mouse_face_end_y, 1);
21660 dpyinfo->mouse_face_past_end = 0;
21661 dpyinfo->mouse_face_window = window;
21662 dpyinfo->mouse_face_face_id
21663 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21664 glyph->face_id, 1);
21665 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21666 cursor = No_Cursor;
21667 }
21668 else if (STRINGP (object) && NILP (mouse_face))
21669 {
21670 /* A string which doesn't have mouse-face, but
21671 the text ``under'' it might have. */
21672 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21673 int start = MATRIX_ROW_START_CHARPOS (r);
21674
21675 pos = string_buffer_position (w, object, start);
21676 if (pos > 0)
21677 mouse_face = get_char_property_and_overlay (make_number (pos),
21678 Qmouse_face,
21679 w->buffer,
21680 &overlay);
21681 if (!NILP (mouse_face) && !NILP (overlay))
21682 {
21683 Lisp_Object before = Foverlay_start (overlay);
21684 Lisp_Object after = Foverlay_end (overlay);
21685 int ignore;
21686
21687 /* Note that we might not be able to find position
21688 BEFORE in the glyph matrix if the overlay is
21689 entirely covered by a `display' property. In
21690 this case, we overshoot. So let's stop in
21691 the glyph matrix before glyphs for OBJECT. */
21692 fast_find_position (w, XFASTINT (before),
21693 &dpyinfo->mouse_face_beg_col,
21694 &dpyinfo->mouse_face_beg_row,
21695 &dpyinfo->mouse_face_beg_x,
21696 &dpyinfo->mouse_face_beg_y,
21697 object);
21698
21699 dpyinfo->mouse_face_past_end
21700 = !fast_find_position (w, XFASTINT (after),
21701 &dpyinfo->mouse_face_end_col,
21702 &dpyinfo->mouse_face_end_row,
21703 &dpyinfo->mouse_face_end_x,
21704 &dpyinfo->mouse_face_end_y,
21705 Qnil);
21706 dpyinfo->mouse_face_window = window;
21707 dpyinfo->mouse_face_face_id
21708 = face_at_buffer_position (w, pos, 0, 0,
21709 &ignore, pos + 1,
21710 !dpyinfo->mouse_face_hidden);
21711
21712 /* Display it as active. */
21713 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21714 cursor = No_Cursor;
21715 }
21716 }
21717 }
21718
21719 check_help_echo:
21720
21721 /* Look for a `help-echo' property. */
21722 if (NILP (help_echo_string)) {
21723 Lisp_Object help, overlay;
21724
21725 /* Check overlays first. */
21726 help = overlay = Qnil;
21727 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21728 {
21729 overlay = overlay_vec[i];
21730 help = Foverlay_get (overlay, Qhelp_echo);
21731 }
21732
21733 if (!NILP (help))
21734 {
21735 help_echo_string = help;
21736 help_echo_window = window;
21737 help_echo_object = overlay;
21738 help_echo_pos = pos;
21739 }
21740 else
21741 {
21742 Lisp_Object object = glyph->object;
21743 int charpos = glyph->charpos;
21744
21745 /* Try text properties. */
21746 if (STRINGP (object)
21747 && charpos >= 0
21748 && charpos < SCHARS (object))
21749 {
21750 help = Fget_text_property (make_number (charpos),
21751 Qhelp_echo, object);
21752 if (NILP (help))
21753 {
21754 /* If the string itself doesn't specify a help-echo,
21755 see if the buffer text ``under'' it does. */
21756 struct glyph_row *r
21757 = MATRIX_ROW (w->current_matrix, vpos);
21758 int start = MATRIX_ROW_START_CHARPOS (r);
21759 int pos = string_buffer_position (w, object, start);
21760 if (pos > 0)
21761 {
21762 help = Fget_char_property (make_number (pos),
21763 Qhelp_echo, w->buffer);
21764 if (!NILP (help))
21765 {
21766 charpos = pos;
21767 object = w->buffer;
21768 }
21769 }
21770 }
21771 }
21772 else if (BUFFERP (object)
21773 && charpos >= BEGV
21774 && charpos < ZV)
21775 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21776 object);
21777
21778 if (!NILP (help))
21779 {
21780 help_echo_string = help;
21781 help_echo_window = window;
21782 help_echo_object = object;
21783 help_echo_pos = charpos;
21784 }
21785 }
21786 }
21787
21788 /* Look for a `pointer' property. */
21789 if (NILP (pointer))
21790 {
21791 /* Check overlays first. */
21792 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21793 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21794
21795 if (NILP (pointer))
21796 {
21797 Lisp_Object object = glyph->object;
21798 int charpos = glyph->charpos;
21799
21800 /* Try text properties. */
21801 if (STRINGP (object)
21802 && charpos >= 0
21803 && charpos < SCHARS (object))
21804 {
21805 pointer = Fget_text_property (make_number (charpos),
21806 Qpointer, object);
21807 if (NILP (pointer))
21808 {
21809 /* If the string itself doesn't specify a pointer,
21810 see if the buffer text ``under'' it does. */
21811 struct glyph_row *r
21812 = MATRIX_ROW (w->current_matrix, vpos);
21813 int start = MATRIX_ROW_START_CHARPOS (r);
21814 int pos = string_buffer_position (w, object, start);
21815 if (pos > 0)
21816 pointer = Fget_char_property (make_number (pos),
21817 Qpointer, w->buffer);
21818 }
21819 }
21820 else if (BUFFERP (object)
21821 && charpos >= BEGV
21822 && charpos < ZV)
21823 pointer = Fget_text_property (make_number (charpos),
21824 Qpointer, object);
21825 }
21826 }
21827
21828 BEGV = obegv;
21829 ZV = ozv;
21830 current_buffer = obuf;
21831 }
21832
21833 set_cursor:
21834
21835 define_frame_cursor1 (f, cursor, pointer);
21836 }
21837
21838
21839 /* EXPORT for RIF:
21840 Clear any mouse-face on window W. This function is part of the
21841 redisplay interface, and is called from try_window_id and similar
21842 functions to ensure the mouse-highlight is off. */
21843
21844 void
21845 x_clear_window_mouse_face (w)
21846 struct window *w;
21847 {
21848 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21849 Lisp_Object window;
21850
21851 BLOCK_INPUT;
21852 XSETWINDOW (window, w);
21853 if (EQ (window, dpyinfo->mouse_face_window))
21854 clear_mouse_face (dpyinfo);
21855 UNBLOCK_INPUT;
21856 }
21857
21858
21859 /* EXPORT:
21860 Just discard the mouse face information for frame F, if any.
21861 This is used when the size of F is changed. */
21862
21863 void
21864 cancel_mouse_face (f)
21865 struct frame *f;
21866 {
21867 Lisp_Object window;
21868 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21869
21870 window = dpyinfo->mouse_face_window;
21871 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21872 {
21873 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21874 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21875 dpyinfo->mouse_face_window = Qnil;
21876 }
21877 }
21878
21879
21880 #endif /* HAVE_WINDOW_SYSTEM */
21881
21882 \f
21883 /***********************************************************************
21884 Exposure Events
21885 ***********************************************************************/
21886
21887 #ifdef HAVE_WINDOW_SYSTEM
21888
21889 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21890 which intersects rectangle R. R is in window-relative coordinates. */
21891
21892 static void
21893 expose_area (w, row, r, area)
21894 struct window *w;
21895 struct glyph_row *row;
21896 XRectangle *r;
21897 enum glyph_row_area area;
21898 {
21899 struct glyph *first = row->glyphs[area];
21900 struct glyph *end = row->glyphs[area] + row->used[area];
21901 struct glyph *last;
21902 int first_x, start_x, x;
21903
21904 if (area == TEXT_AREA && row->fill_line_p)
21905 /* If row extends face to end of line write the whole line. */
21906 draw_glyphs (w, 0, row, area,
21907 0, row->used[area],
21908 DRAW_NORMAL_TEXT, 0);
21909 else
21910 {
21911 /* Set START_X to the window-relative start position for drawing glyphs of
21912 AREA. The first glyph of the text area can be partially visible.
21913 The first glyphs of other areas cannot. */
21914 start_x = window_box_left_offset (w, area);
21915 x = start_x;
21916 if (area == TEXT_AREA)
21917 x += row->x;
21918
21919 /* Find the first glyph that must be redrawn. */
21920 while (first < end
21921 && x + first->pixel_width < r->x)
21922 {
21923 x += first->pixel_width;
21924 ++first;
21925 }
21926
21927 /* Find the last one. */
21928 last = first;
21929 first_x = x;
21930 while (last < end
21931 && x < r->x + r->width)
21932 {
21933 x += last->pixel_width;
21934 ++last;
21935 }
21936
21937 /* Repaint. */
21938 if (last > first)
21939 draw_glyphs (w, first_x - start_x, row, area,
21940 first - row->glyphs[area], last - row->glyphs[area],
21941 DRAW_NORMAL_TEXT, 0);
21942 }
21943 }
21944
21945
21946 /* Redraw the parts of the glyph row ROW on window W intersecting
21947 rectangle R. R is in window-relative coordinates. Value is
21948 non-zero if mouse-face was overwritten. */
21949
21950 static int
21951 expose_line (w, row, r)
21952 struct window *w;
21953 struct glyph_row *row;
21954 XRectangle *r;
21955 {
21956 xassert (row->enabled_p);
21957
21958 if (row->mode_line_p || w->pseudo_window_p)
21959 draw_glyphs (w, 0, row, TEXT_AREA,
21960 0, row->used[TEXT_AREA],
21961 DRAW_NORMAL_TEXT, 0);
21962 else
21963 {
21964 if (row->used[LEFT_MARGIN_AREA])
21965 expose_area (w, row, r, LEFT_MARGIN_AREA);
21966 if (row->used[TEXT_AREA])
21967 expose_area (w, row, r, TEXT_AREA);
21968 if (row->used[RIGHT_MARGIN_AREA])
21969 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21970 draw_row_fringe_bitmaps (w, row);
21971 }
21972
21973 return row->mouse_face_p;
21974 }
21975
21976
21977 /* Redraw those parts of glyphs rows during expose event handling that
21978 overlap other rows. Redrawing of an exposed line writes over parts
21979 of lines overlapping that exposed line; this function fixes that.
21980
21981 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21982 row in W's current matrix that is exposed and overlaps other rows.
21983 LAST_OVERLAPPING_ROW is the last such row. */
21984
21985 static void
21986 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21987 struct window *w;
21988 struct glyph_row *first_overlapping_row;
21989 struct glyph_row *last_overlapping_row;
21990 {
21991 struct glyph_row *row;
21992
21993 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21994 if (row->overlapping_p)
21995 {
21996 xassert (row->enabled_p && !row->mode_line_p);
21997
21998 if (row->used[LEFT_MARGIN_AREA])
21999 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
22000
22001 if (row->used[TEXT_AREA])
22002 x_fix_overlapping_area (w, row, TEXT_AREA);
22003
22004 if (row->used[RIGHT_MARGIN_AREA])
22005 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
22006 }
22007 }
22008
22009
22010 /* Return non-zero if W's cursor intersects rectangle R. */
22011
22012 static int
22013 phys_cursor_in_rect_p (w, r)
22014 struct window *w;
22015 XRectangle *r;
22016 {
22017 XRectangle cr, result;
22018 struct glyph *cursor_glyph;
22019
22020 cursor_glyph = get_phys_cursor_glyph (w);
22021 if (cursor_glyph)
22022 {
22023 /* r is relative to W's box, but w->phys_cursor.x is relative
22024 to left edge of W's TEXT area. Adjust it. */
22025 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
22026 cr.y = w->phys_cursor.y;
22027 cr.width = cursor_glyph->pixel_width;
22028 cr.height = w->phys_cursor_height;
22029 /* ++KFS: W32 version used W32-specific IntersectRect here, but
22030 I assume the effect is the same -- and this is portable. */
22031 return x_intersect_rectangles (&cr, r, &result);
22032 }
22033 else
22034 return 0;
22035 }
22036
22037
22038 /* EXPORT:
22039 Draw a vertical window border to the right of window W if W doesn't
22040 have vertical scroll bars. */
22041
22042 void
22043 x_draw_vertical_border (w)
22044 struct window *w;
22045 {
22046 /* We could do better, if we knew what type of scroll-bar the adjacent
22047 windows (on either side) have... But we don't :-(
22048 However, I think this works ok. ++KFS 2003-04-25 */
22049
22050 /* Redraw borders between horizontally adjacent windows. Don't
22051 do it for frames with vertical scroll bars because either the
22052 right scroll bar of a window, or the left scroll bar of its
22053 neighbor will suffice as a border. */
22054 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
22055 return;
22056
22057 if (!WINDOW_RIGHTMOST_P (w)
22058 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
22059 {
22060 int x0, x1, y0, y1;
22061
22062 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22063 y1 -= 1;
22064
22065 rif->draw_vertical_window_border (w, x1, y0, y1);
22066 }
22067 else if (!WINDOW_LEFTMOST_P (w)
22068 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
22069 {
22070 int x0, x1, y0, y1;
22071
22072 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22073 y1 -= 1;
22074
22075 rif->draw_vertical_window_border (w, x0, y0, y1);
22076 }
22077 }
22078
22079
22080 /* Redraw the part of window W intersection rectangle FR. Pixel
22081 coordinates in FR are frame-relative. Call this function with
22082 input blocked. Value is non-zero if the exposure overwrites
22083 mouse-face. */
22084
22085 static int
22086 expose_window (w, fr)
22087 struct window *w;
22088 XRectangle *fr;
22089 {
22090 struct frame *f = XFRAME (w->frame);
22091 XRectangle wr, r;
22092 int mouse_face_overwritten_p = 0;
22093
22094 /* If window is not yet fully initialized, do nothing. This can
22095 happen when toolkit scroll bars are used and a window is split.
22096 Reconfiguring the scroll bar will generate an expose for a newly
22097 created window. */
22098 if (w->current_matrix == NULL)
22099 return 0;
22100
22101 /* When we're currently updating the window, display and current
22102 matrix usually don't agree. Arrange for a thorough display
22103 later. */
22104 if (w == updated_window)
22105 {
22106 SET_FRAME_GARBAGED (f);
22107 return 0;
22108 }
22109
22110 /* Frame-relative pixel rectangle of W. */
22111 wr.x = WINDOW_LEFT_EDGE_X (w);
22112 wr.y = WINDOW_TOP_EDGE_Y (w);
22113 wr.width = WINDOW_TOTAL_WIDTH (w);
22114 wr.height = WINDOW_TOTAL_HEIGHT (w);
22115
22116 if (x_intersect_rectangles (fr, &wr, &r))
22117 {
22118 int yb = window_text_bottom_y (w);
22119 struct glyph_row *row;
22120 int cursor_cleared_p;
22121 struct glyph_row *first_overlapping_row, *last_overlapping_row;
22122
22123 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
22124 r.x, r.y, r.width, r.height));
22125
22126 /* Convert to window coordinates. */
22127 r.x -= WINDOW_LEFT_EDGE_X (w);
22128 r.y -= WINDOW_TOP_EDGE_Y (w);
22129
22130 /* Turn off the cursor. */
22131 if (!w->pseudo_window_p
22132 && phys_cursor_in_rect_p (w, &r))
22133 {
22134 x_clear_cursor (w);
22135 cursor_cleared_p = 1;
22136 }
22137 else
22138 cursor_cleared_p = 0;
22139
22140 /* Update lines intersecting rectangle R. */
22141 first_overlapping_row = last_overlapping_row = NULL;
22142 for (row = w->current_matrix->rows;
22143 row->enabled_p;
22144 ++row)
22145 {
22146 int y0 = row->y;
22147 int y1 = MATRIX_ROW_BOTTOM_Y (row);
22148
22149 if ((y0 >= r.y && y0 < r.y + r.height)
22150 || (y1 > r.y && y1 < r.y + r.height)
22151 || (r.y >= y0 && r.y < y1)
22152 || (r.y + r.height > y0 && r.y + r.height < y1))
22153 {
22154 /* A header line may be overlapping, but there is no need
22155 to fix overlapping areas for them. KFS 2005-02-12 */
22156 if (row->overlapping_p && !row->mode_line_p)
22157 {
22158 if (first_overlapping_row == NULL)
22159 first_overlapping_row = row;
22160 last_overlapping_row = row;
22161 }
22162
22163 if (expose_line (w, row, &r))
22164 mouse_face_overwritten_p = 1;
22165 }
22166
22167 if (y1 >= yb)
22168 break;
22169 }
22170
22171 /* Display the mode line if there is one. */
22172 if (WINDOW_WANTS_MODELINE_P (w)
22173 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
22174 row->enabled_p)
22175 && row->y < r.y + r.height)
22176 {
22177 if (expose_line (w, row, &r))
22178 mouse_face_overwritten_p = 1;
22179 }
22180
22181 if (!w->pseudo_window_p)
22182 {
22183 /* Fix the display of overlapping rows. */
22184 if (first_overlapping_row)
22185 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
22186
22187 /* Draw border between windows. */
22188 x_draw_vertical_border (w);
22189
22190 /* Turn the cursor on again. */
22191 if (cursor_cleared_p)
22192 update_window_cursor (w, 1);
22193 }
22194 }
22195
22196 return mouse_face_overwritten_p;
22197 }
22198
22199
22200
22201 /* Redraw (parts) of all windows in the window tree rooted at W that
22202 intersect R. R contains frame pixel coordinates. Value is
22203 non-zero if the exposure overwrites mouse-face. */
22204
22205 static int
22206 expose_window_tree (w, r)
22207 struct window *w;
22208 XRectangle *r;
22209 {
22210 struct frame *f = XFRAME (w->frame);
22211 int mouse_face_overwritten_p = 0;
22212
22213 while (w && !FRAME_GARBAGED_P (f))
22214 {
22215 if (!NILP (w->hchild))
22216 mouse_face_overwritten_p
22217 |= expose_window_tree (XWINDOW (w->hchild), r);
22218 else if (!NILP (w->vchild))
22219 mouse_face_overwritten_p
22220 |= expose_window_tree (XWINDOW (w->vchild), r);
22221 else
22222 mouse_face_overwritten_p |= expose_window (w, r);
22223
22224 w = NILP (w->next) ? NULL : XWINDOW (w->next);
22225 }
22226
22227 return mouse_face_overwritten_p;
22228 }
22229
22230
22231 /* EXPORT:
22232 Redisplay an exposed area of frame F. X and Y are the upper-left
22233 corner of the exposed rectangle. W and H are width and height of
22234 the exposed area. All are pixel values. W or H zero means redraw
22235 the entire frame. */
22236
22237 void
22238 expose_frame (f, x, y, w, h)
22239 struct frame *f;
22240 int x, y, w, h;
22241 {
22242 XRectangle r;
22243 int mouse_face_overwritten_p = 0;
22244
22245 TRACE ((stderr, "expose_frame "));
22246
22247 /* No need to redraw if frame will be redrawn soon. */
22248 if (FRAME_GARBAGED_P (f))
22249 {
22250 TRACE ((stderr, " garbaged\n"));
22251 return;
22252 }
22253
22254 /* If basic faces haven't been realized yet, there is no point in
22255 trying to redraw anything. This can happen when we get an expose
22256 event while Emacs is starting, e.g. by moving another window. */
22257 if (FRAME_FACE_CACHE (f) == NULL
22258 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
22259 {
22260 TRACE ((stderr, " no faces\n"));
22261 return;
22262 }
22263
22264 if (w == 0 || h == 0)
22265 {
22266 r.x = r.y = 0;
22267 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
22268 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
22269 }
22270 else
22271 {
22272 r.x = x;
22273 r.y = y;
22274 r.width = w;
22275 r.height = h;
22276 }
22277
22278 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
22279 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
22280
22281 if (WINDOWP (f->tool_bar_window))
22282 mouse_face_overwritten_p
22283 |= expose_window (XWINDOW (f->tool_bar_window), &r);
22284
22285 #ifdef HAVE_X_WINDOWS
22286 #ifndef MSDOS
22287 #ifndef USE_X_TOOLKIT
22288 if (WINDOWP (f->menu_bar_window))
22289 mouse_face_overwritten_p
22290 |= expose_window (XWINDOW (f->menu_bar_window), &r);
22291 #endif /* not USE_X_TOOLKIT */
22292 #endif
22293 #endif
22294
22295 /* Some window managers support a focus-follows-mouse style with
22296 delayed raising of frames. Imagine a partially obscured frame,
22297 and moving the mouse into partially obscured mouse-face on that
22298 frame. The visible part of the mouse-face will be highlighted,
22299 then the WM raises the obscured frame. With at least one WM, KDE
22300 2.1, Emacs is not getting any event for the raising of the frame
22301 (even tried with SubstructureRedirectMask), only Expose events.
22302 These expose events will draw text normally, i.e. not
22303 highlighted. Which means we must redo the highlight here.
22304 Subsume it under ``we love X''. --gerd 2001-08-15 */
22305 /* Included in Windows version because Windows most likely does not
22306 do the right thing if any third party tool offers
22307 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
22308 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
22309 {
22310 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22311 if (f == dpyinfo->mouse_face_mouse_frame)
22312 {
22313 int x = dpyinfo->mouse_face_mouse_x;
22314 int y = dpyinfo->mouse_face_mouse_y;
22315 clear_mouse_face (dpyinfo);
22316 note_mouse_highlight (f, x, y);
22317 }
22318 }
22319 }
22320
22321
22322 /* EXPORT:
22323 Determine the intersection of two rectangles R1 and R2. Return
22324 the intersection in *RESULT. Value is non-zero if RESULT is not
22325 empty. */
22326
22327 int
22328 x_intersect_rectangles (r1, r2, result)
22329 XRectangle *r1, *r2, *result;
22330 {
22331 XRectangle *left, *right;
22332 XRectangle *upper, *lower;
22333 int intersection_p = 0;
22334
22335 /* Rearrange so that R1 is the left-most rectangle. */
22336 if (r1->x < r2->x)
22337 left = r1, right = r2;
22338 else
22339 left = r2, right = r1;
22340
22341 /* X0 of the intersection is right.x0, if this is inside R1,
22342 otherwise there is no intersection. */
22343 if (right->x <= left->x + left->width)
22344 {
22345 result->x = right->x;
22346
22347 /* The right end of the intersection is the minimum of the
22348 the right ends of left and right. */
22349 result->width = (min (left->x + left->width, right->x + right->width)
22350 - result->x);
22351
22352 /* Same game for Y. */
22353 if (r1->y < r2->y)
22354 upper = r1, lower = r2;
22355 else
22356 upper = r2, lower = r1;
22357
22358 /* The upper end of the intersection is lower.y0, if this is inside
22359 of upper. Otherwise, there is no intersection. */
22360 if (lower->y <= upper->y + upper->height)
22361 {
22362 result->y = lower->y;
22363
22364 /* The lower end of the intersection is the minimum of the lower
22365 ends of upper and lower. */
22366 result->height = (min (lower->y + lower->height,
22367 upper->y + upper->height)
22368 - result->y);
22369 intersection_p = 1;
22370 }
22371 }
22372
22373 return intersection_p;
22374 }
22375
22376 #endif /* HAVE_WINDOW_SYSTEM */
22377
22378 \f
22379 /***********************************************************************
22380 Initialization
22381 ***********************************************************************/
22382
22383 void
22384 syms_of_xdisp ()
22385 {
22386 Vwith_echo_area_save_vector = Qnil;
22387 staticpro (&Vwith_echo_area_save_vector);
22388
22389 Vmessage_stack = Qnil;
22390 staticpro (&Vmessage_stack);
22391
22392 Qinhibit_redisplay = intern ("inhibit-redisplay");
22393 staticpro (&Qinhibit_redisplay);
22394
22395 message_dolog_marker1 = Fmake_marker ();
22396 staticpro (&message_dolog_marker1);
22397 message_dolog_marker2 = Fmake_marker ();
22398 staticpro (&message_dolog_marker2);
22399 message_dolog_marker3 = Fmake_marker ();
22400 staticpro (&message_dolog_marker3);
22401
22402 #if GLYPH_DEBUG
22403 defsubr (&Sdump_frame_glyph_matrix);
22404 defsubr (&Sdump_glyph_matrix);
22405 defsubr (&Sdump_glyph_row);
22406 defsubr (&Sdump_tool_bar_row);
22407 defsubr (&Strace_redisplay);
22408 defsubr (&Strace_to_stderr);
22409 #endif
22410 #ifdef HAVE_WINDOW_SYSTEM
22411 defsubr (&Stool_bar_lines_needed);
22412 defsubr (&Slookup_image_map);
22413 #endif
22414 defsubr (&Sformat_mode_line);
22415
22416 staticpro (&Qmenu_bar_update_hook);
22417 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22418
22419 staticpro (&Qoverriding_terminal_local_map);
22420 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22421
22422 staticpro (&Qoverriding_local_map);
22423 Qoverriding_local_map = intern ("overriding-local-map");
22424
22425 staticpro (&Qwindow_scroll_functions);
22426 Qwindow_scroll_functions = intern ("window-scroll-functions");
22427
22428 staticpro (&Qredisplay_end_trigger_functions);
22429 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22430
22431 staticpro (&Qinhibit_point_motion_hooks);
22432 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22433
22434 QCdata = intern (":data");
22435 staticpro (&QCdata);
22436 Qdisplay = intern ("display");
22437 staticpro (&Qdisplay);
22438 Qspace_width = intern ("space-width");
22439 staticpro (&Qspace_width);
22440 Qraise = intern ("raise");
22441 staticpro (&Qraise);
22442 Qslice = intern ("slice");
22443 staticpro (&Qslice);
22444 Qspace = intern ("space");
22445 staticpro (&Qspace);
22446 Qmargin = intern ("margin");
22447 staticpro (&Qmargin);
22448 Qpointer = intern ("pointer");
22449 staticpro (&Qpointer);
22450 Qleft_margin = intern ("left-margin");
22451 staticpro (&Qleft_margin);
22452 Qright_margin = intern ("right-margin");
22453 staticpro (&Qright_margin);
22454 Qcenter = intern ("center");
22455 staticpro (&Qcenter);
22456 Qline_height = intern ("line-height");
22457 staticpro (&Qline_height);
22458 QCalign_to = intern (":align-to");
22459 staticpro (&QCalign_to);
22460 QCrelative_width = intern (":relative-width");
22461 staticpro (&QCrelative_width);
22462 QCrelative_height = intern (":relative-height");
22463 staticpro (&QCrelative_height);
22464 QCeval = intern (":eval");
22465 staticpro (&QCeval);
22466 QCpropertize = intern (":propertize");
22467 staticpro (&QCpropertize);
22468 QCfile = intern (":file");
22469 staticpro (&QCfile);
22470 Qfontified = intern ("fontified");
22471 staticpro (&Qfontified);
22472 Qfontification_functions = intern ("fontification-functions");
22473 staticpro (&Qfontification_functions);
22474 Qtrailing_whitespace = intern ("trailing-whitespace");
22475 staticpro (&Qtrailing_whitespace);
22476 Qescape_glyph = intern ("escape-glyph");
22477 staticpro (&Qescape_glyph);
22478 Qimage = intern ("image");
22479 staticpro (&Qimage);
22480 QCmap = intern (":map");
22481 staticpro (&QCmap);
22482 QCpointer = intern (":pointer");
22483 staticpro (&QCpointer);
22484 Qrect = intern ("rect");
22485 staticpro (&Qrect);
22486 Qcircle = intern ("circle");
22487 staticpro (&Qcircle);
22488 Qpoly = intern ("poly");
22489 staticpro (&Qpoly);
22490 Qmessage_truncate_lines = intern ("message-truncate-lines");
22491 staticpro (&Qmessage_truncate_lines);
22492 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22493 staticpro (&Qcursor_in_non_selected_windows);
22494 Qgrow_only = intern ("grow-only");
22495 staticpro (&Qgrow_only);
22496 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22497 staticpro (&Qinhibit_menubar_update);
22498 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22499 staticpro (&Qinhibit_eval_during_redisplay);
22500 Qposition = intern ("position");
22501 staticpro (&Qposition);
22502 Qbuffer_position = intern ("buffer-position");
22503 staticpro (&Qbuffer_position);
22504 Qobject = intern ("object");
22505 staticpro (&Qobject);
22506 Qbar = intern ("bar");
22507 staticpro (&Qbar);
22508 Qhbar = intern ("hbar");
22509 staticpro (&Qhbar);
22510 Qbox = intern ("box");
22511 staticpro (&Qbox);
22512 Qhollow = intern ("hollow");
22513 staticpro (&Qhollow);
22514 Qhand = intern ("hand");
22515 staticpro (&Qhand);
22516 Qarrow = intern ("arrow");
22517 staticpro (&Qarrow);
22518 Qtext = intern ("text");
22519 staticpro (&Qtext);
22520 Qrisky_local_variable = intern ("risky-local-variable");
22521 staticpro (&Qrisky_local_variable);
22522 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22523 staticpro (&Qinhibit_free_realized_faces);
22524
22525 list_of_error = Fcons (Fcons (intern ("error"),
22526 Fcons (intern ("void-variable"), Qnil)),
22527 Qnil);
22528 staticpro (&list_of_error);
22529
22530 Qlast_arrow_position = intern ("last-arrow-position");
22531 staticpro (&Qlast_arrow_position);
22532 Qlast_arrow_string = intern ("last-arrow-string");
22533 staticpro (&Qlast_arrow_string);
22534
22535 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22536 staticpro (&Qoverlay_arrow_string);
22537 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22538 staticpro (&Qoverlay_arrow_bitmap);
22539
22540 echo_buffer[0] = echo_buffer[1] = Qnil;
22541 staticpro (&echo_buffer[0]);
22542 staticpro (&echo_buffer[1]);
22543
22544 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22545 staticpro (&echo_area_buffer[0]);
22546 staticpro (&echo_area_buffer[1]);
22547
22548 Vmessages_buffer_name = build_string ("*Messages*");
22549 staticpro (&Vmessages_buffer_name);
22550
22551 mode_line_proptrans_alist = Qnil;
22552 staticpro (&mode_line_proptrans_alist);
22553
22554 mode_line_string_list = Qnil;
22555 staticpro (&mode_line_string_list);
22556
22557 help_echo_string = Qnil;
22558 staticpro (&help_echo_string);
22559 help_echo_object = Qnil;
22560 staticpro (&help_echo_object);
22561 help_echo_window = Qnil;
22562 staticpro (&help_echo_window);
22563 previous_help_echo_string = Qnil;
22564 staticpro (&previous_help_echo_string);
22565 help_echo_pos = -1;
22566
22567 #ifdef HAVE_WINDOW_SYSTEM
22568 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22569 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22570 For example, if a block cursor is over a tab, it will be drawn as
22571 wide as that tab on the display. */);
22572 x_stretch_cursor_p = 0;
22573 #endif
22574
22575 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22576 doc: /* *Non-nil means highlight trailing whitespace.
22577 The face used for trailing whitespace is `trailing-whitespace'. */);
22578 Vshow_trailing_whitespace = Qnil;
22579
22580 DEFVAR_LISP ("show-nonbreak-escape", &Vshow_nonbreak_escape,
22581 doc: /* *Non-nil means display escape character before non-break space and hyphen. */);
22582 Vshow_nonbreak_escape = Qt;
22583
22584 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22585 doc: /* *The pointer shape to show in void text areas.
22586 Nil means to show the text pointer. Other options are `arrow', `text',
22587 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22588 Vvoid_text_area_pointer = Qarrow;
22589
22590 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22591 doc: /* Non-nil means don't actually do any redisplay.
22592 This is used for internal purposes. */);
22593 Vinhibit_redisplay = Qnil;
22594
22595 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22596 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22597 Vglobal_mode_string = Qnil;
22598
22599 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22600 doc: /* Marker for where to display an arrow on top of the buffer text.
22601 This must be the beginning of a line in order to work.
22602 See also `overlay-arrow-string'. */);
22603 Voverlay_arrow_position = Qnil;
22604
22605 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22606 doc: /* String to display as an arrow in non-window frames.
22607 See also `overlay-arrow-position'. */);
22608 Voverlay_arrow_string = build_string ("=>");
22609
22610 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22611 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22612 The symbols on this list are examined during redisplay to determine
22613 where to display overlay arrows. */);
22614 Voverlay_arrow_variable_list
22615 = Fcons (intern ("overlay-arrow-position"), Qnil);
22616
22617 DEFVAR_INT ("scroll-step", &scroll_step,
22618 doc: /* *The number of lines to try scrolling a window by when point moves out.
22619 If that fails to bring point back on frame, point is centered instead.
22620 If this is zero, point is always centered after it moves off frame.
22621 If you want scrolling to always be a line at a time, you should set
22622 `scroll-conservatively' to a large value rather than set this to 1. */);
22623
22624 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22625 doc: /* *Scroll up to this many lines, to bring point back on screen.
22626 A value of zero means to scroll the text to center point vertically
22627 in the window. */);
22628 scroll_conservatively = 0;
22629
22630 DEFVAR_INT ("scroll-margin", &scroll_margin,
22631 doc: /* *Number of lines of margin at the top and bottom of a window.
22632 Recenter the window whenever point gets within this many lines
22633 of the top or bottom of the window. */);
22634 scroll_margin = 0;
22635
22636 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22637 doc: /* Pixels per inch on current display.
22638 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22639 Vdisplay_pixels_per_inch = make_float (72.0);
22640
22641 #if GLYPH_DEBUG
22642 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22643 #endif
22644
22645 DEFVAR_BOOL ("truncate-partial-width-windows",
22646 &truncate_partial_width_windows,
22647 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22648 truncate_partial_width_windows = 1;
22649
22650 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22651 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22652 Any other value means to use the appropriate face, `mode-line',
22653 `header-line', or `menu' respectively. */);
22654 mode_line_inverse_video = 1;
22655
22656 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22657 doc: /* *Maximum buffer size for which line number should be displayed.
22658 If the buffer is bigger than this, the line number does not appear
22659 in the mode line. A value of nil means no limit. */);
22660 Vline_number_display_limit = Qnil;
22661
22662 DEFVAR_INT ("line-number-display-limit-width",
22663 &line_number_display_limit_width,
22664 doc: /* *Maximum line width (in characters) for line number display.
22665 If the average length of the lines near point is bigger than this, then the
22666 line number may be omitted from the mode line. */);
22667 line_number_display_limit_width = 200;
22668
22669 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22670 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22671 highlight_nonselected_windows = 0;
22672
22673 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22674 doc: /* Non-nil if more than one frame is visible on this display.
22675 Minibuffer-only frames don't count, but iconified frames do.
22676 This variable is not guaranteed to be accurate except while processing
22677 `frame-title-format' and `icon-title-format'. */);
22678
22679 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22680 doc: /* Template for displaying the title bar of visible frames.
22681 \(Assuming the window manager supports this feature.)
22682 This variable has the same structure as `mode-line-format' (which see),
22683 and is used only on frames for which no explicit name has been set
22684 \(see `modify-frame-parameters'). */);
22685
22686 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22687 doc: /* Template for displaying the title bar of an iconified frame.
22688 \(Assuming the window manager supports this feature.)
22689 This variable has the same structure as `mode-line-format' (which see),
22690 and is used only on frames for which no explicit name has been set
22691 \(see `modify-frame-parameters'). */);
22692 Vicon_title_format
22693 = Vframe_title_format
22694 = Fcons (intern ("multiple-frames"),
22695 Fcons (build_string ("%b"),
22696 Fcons (Fcons (empty_string,
22697 Fcons (intern ("invocation-name"),
22698 Fcons (build_string ("@"),
22699 Fcons (intern ("system-name"),
22700 Qnil)))),
22701 Qnil)));
22702
22703 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22704 doc: /* Maximum number of lines to keep in the message log buffer.
22705 If nil, disable message logging. If t, log messages but don't truncate
22706 the buffer when it becomes large. */);
22707 Vmessage_log_max = make_number (50);
22708
22709 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22710 doc: /* Functions called before redisplay, if window sizes have changed.
22711 The value should be a list of functions that take one argument.
22712 Just before redisplay, for each frame, if any of its windows have changed
22713 size since the last redisplay, or have been split or deleted,
22714 all the functions in the list are called, with the frame as argument. */);
22715 Vwindow_size_change_functions = Qnil;
22716
22717 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22718 doc: /* List of functions to call before redisplaying a window with scrolling.
22719 Each function is called with two arguments, the window
22720 and its new display-start position. Note that the value of `window-end'
22721 is not valid when these functions are called. */);
22722 Vwindow_scroll_functions = Qnil;
22723
22724 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22725 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22726 mouse_autoselect_window = 0;
22727
22728 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22729 doc: /* *Non-nil means automatically resize tool-bars.
22730 This increases a tool-bar's height if not all tool-bar items are visible.
22731 It decreases a tool-bar's height when it would display blank lines
22732 otherwise. */);
22733 auto_resize_tool_bars_p = 1;
22734
22735 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22736 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22737 auto_raise_tool_bar_buttons_p = 1;
22738
22739 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
22740 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
22741 make_cursor_line_fully_visible_p = 1;
22742
22743 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22744 doc: /* *Margin around tool-bar buttons in pixels.
22745 If an integer, use that for both horizontal and vertical margins.
22746 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22747 HORZ specifying the horizontal margin, and VERT specifying the
22748 vertical margin. */);
22749 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22750
22751 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22752 doc: /* *Relief thickness of tool-bar buttons. */);
22753 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22754
22755 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22756 doc: /* List of functions to call to fontify regions of text.
22757 Each function is called with one argument POS. Functions must
22758 fontify a region starting at POS in the current buffer, and give
22759 fontified regions the property `fontified'. */);
22760 Vfontification_functions = Qnil;
22761 Fmake_variable_buffer_local (Qfontification_functions);
22762
22763 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22764 &unibyte_display_via_language_environment,
22765 doc: /* *Non-nil means display unibyte text according to language environment.
22766 Specifically this means that unibyte non-ASCII characters
22767 are displayed by converting them to the equivalent multibyte characters
22768 according to the current language environment. As a result, they are
22769 displayed according to the current fontset. */);
22770 unibyte_display_via_language_environment = 0;
22771
22772 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22773 doc: /* *Maximum height for resizing mini-windows.
22774 If a float, it specifies a fraction of the mini-window frame's height.
22775 If an integer, it specifies a number of lines. */);
22776 Vmax_mini_window_height = make_float (0.25);
22777
22778 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22779 doc: /* *How to resize mini-windows.
22780 A value of nil means don't automatically resize mini-windows.
22781 A value of t means resize them to fit the text displayed in them.
22782 A value of `grow-only', the default, means let mini-windows grow
22783 only, until their display becomes empty, at which point the windows
22784 go back to their normal size. */);
22785 Vresize_mini_windows = Qgrow_only;
22786
22787 DEFVAR_LISP ("cursor-in-non-selected-windows",
22788 &Vcursor_in_non_selected_windows,
22789 doc: /* *Cursor type to display in non-selected windows.
22790 t means to use hollow box cursor. See `cursor-type' for other values. */);
22791 Vcursor_in_non_selected_windows = Qt;
22792
22793 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22794 doc: /* Alist specifying how to blink the cursor off.
22795 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22796 `cursor-type' frame-parameter or variable equals ON-STATE,
22797 comparing using `equal', Emacs uses OFF-STATE to specify
22798 how to blink it off. */);
22799 Vblink_cursor_alist = Qnil;
22800
22801 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22802 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22803 automatic_hscrolling_p = 1;
22804
22805 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22806 doc: /* *How many columns away from the window edge point is allowed to get
22807 before automatic hscrolling will horizontally scroll the window. */);
22808 hscroll_margin = 5;
22809
22810 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22811 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22812 When point is less than `automatic-hscroll-margin' columns from the window
22813 edge, automatic hscrolling will scroll the window by the amount of columns
22814 determined by this variable. If its value is a positive integer, scroll that
22815 many columns. If it's a positive floating-point number, it specifies the
22816 fraction of the window's width to scroll. If it's nil or zero, point will be
22817 centered horizontally after the scroll. Any other value, including negative
22818 numbers, are treated as if the value were zero.
22819
22820 Automatic hscrolling always moves point outside the scroll margin, so if
22821 point was more than scroll step columns inside the margin, the window will
22822 scroll more than the value given by the scroll step.
22823
22824 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22825 and `scroll-right' overrides this variable's effect. */);
22826 Vhscroll_step = make_number (0);
22827
22828 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22829 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22830 Bind this around calls to `message' to let it take effect. */);
22831 message_truncate_lines = 0;
22832
22833 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22834 doc: /* Normal hook run to update the menu bar definitions.
22835 Redisplay runs this hook before it redisplays the menu bar.
22836 This is used to update submenus such as Buffers,
22837 whose contents depend on various data. */);
22838 Vmenu_bar_update_hook = Qnil;
22839
22840 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22841 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22842 inhibit_menubar_update = 0;
22843
22844 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22845 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22846 inhibit_eval_during_redisplay = 0;
22847
22848 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22849 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22850 inhibit_free_realized_faces = 0;
22851
22852 #if GLYPH_DEBUG
22853 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22854 doc: /* Inhibit try_window_id display optimization. */);
22855 inhibit_try_window_id = 0;
22856
22857 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22858 doc: /* Inhibit try_window_reusing display optimization. */);
22859 inhibit_try_window_reusing = 0;
22860
22861 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22862 doc: /* Inhibit try_cursor_movement display optimization. */);
22863 inhibit_try_cursor_movement = 0;
22864 #endif /* GLYPH_DEBUG */
22865 }
22866
22867
22868 /* Initialize this module when Emacs starts. */
22869
22870 void
22871 init_xdisp ()
22872 {
22873 Lisp_Object root_window;
22874 struct window *mini_w;
22875
22876 current_header_line_height = current_mode_line_height = -1;
22877
22878 CHARPOS (this_line_start_pos) = 0;
22879
22880 mini_w = XWINDOW (minibuf_window);
22881 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22882
22883 if (!noninteractive)
22884 {
22885 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22886 int i;
22887
22888 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22889 set_window_height (root_window,
22890 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22891 0);
22892 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22893 set_window_height (minibuf_window, 1, 0);
22894
22895 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22896 mini_w->total_cols = make_number (FRAME_COLS (f));
22897
22898 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22899 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22900 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22901
22902 /* The default ellipsis glyphs `...'. */
22903 for (i = 0; i < 3; ++i)
22904 default_invis_vector[i] = make_number ('.');
22905 }
22906
22907 {
22908 /* Allocate the buffer for frame titles.
22909 Also used for `format-mode-line'. */
22910 int size = 100;
22911 frame_title_buf = (char *) xmalloc (size);
22912 frame_title_buf_end = frame_title_buf + size;
22913 frame_title_ptr = NULL;
22914 }
22915
22916 help_echo_showing_p = 0;
22917 }
22918
22919
22920 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22921 (do not change this comment) */