(row_equal_p, update_window_line): Compare fringe bitmaps
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03
3 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
202 Cursor No_Cursor;
203 #endif
204
205 #ifndef FRAME_X_OUTPUT
206 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207 #endif
208
209 #define INFINITY 10000000
210
211 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
212 || defined (USE_GTK)
213 extern void set_frame_menubar P_ ((struct frame *f, int, int));
214 extern int pending_menu_activation;
215 #endif
216
217 extern int interrupt_input;
218 extern int command_loop_level;
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 /* Margin around tool bar buttons in pixels. */
268
269 Lisp_Object Vtool_bar_button_margin;
270
271 /* Thickness of shadow to draw around tool bar buttons. */
272
273 EMACS_INT tool_bar_button_relief;
274
275 /* Non-zero means automatically resize tool-bars so that all tool-bar
276 items are visible, and no blank lines remain. */
277
278 int auto_resize_tool_bars_p;
279
280 /* Non-zero means draw block and hollow cursor as wide as the glyph
281 under it. For example, if a block cursor is over a tab, it will be
282 drawn as wide as that tab on the display. */
283
284 int x_stretch_cursor_p;
285
286 /* Non-nil means don't actually do any redisplay. */
287
288 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
289
290 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
291
292 int inhibit_eval_during_redisplay;
293
294 /* Names of text properties relevant for redisplay. */
295
296 Lisp_Object Qdisplay;
297 extern Lisp_Object Qface, Qinvisible, Qwidth;
298
299 /* Symbols used in text property values. */
300
301 Lisp_Object Vdisplay_pixels_per_inch;
302 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
303 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
304 Lisp_Object Qmargin, Qpointer;
305 extern Lisp_Object Qheight;
306 extern Lisp_Object QCwidth, QCheight, QCascent;
307 extern Lisp_Object Qscroll_bar;
308
309 /* Non-nil means highlight trailing whitespace. */
310
311 Lisp_Object Vshow_trailing_whitespace;
312
313 /* Non-nil means show the text cursor in void text areas
314 i.e. in blank areas after eol and eob. This used to be
315 the default in 21.3. */
316
317 Lisp_Object Vvoid_text_area_pointer;
318
319 /* Name of the face used to highlight trailing whitespace. */
320
321 Lisp_Object Qtrailing_whitespace;
322
323 /* The symbol `image' which is the car of the lists used to represent
324 images in Lisp. */
325
326 Lisp_Object Qimage;
327
328 /* The image map types. */
329 Lisp_Object QCmap, QCpointer;
330 Lisp_Object Qrect, Qcircle, Qpoly;
331
332 /* Non-zero means print newline to stdout before next mini-buffer
333 message. */
334
335 int noninteractive_need_newline;
336
337 /* Non-zero means print newline to message log before next message. */
338
339 static int message_log_need_newline;
340
341 /* Three markers that message_dolog uses.
342 It could allocate them itself, but that causes trouble
343 in handling memory-full errors. */
344 static Lisp_Object message_dolog_marker1;
345 static Lisp_Object message_dolog_marker2;
346 static Lisp_Object message_dolog_marker3;
347 \f
348 /* The buffer position of the first character appearing entirely or
349 partially on the line of the selected window which contains the
350 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
351 redisplay optimization in redisplay_internal. */
352
353 static struct text_pos this_line_start_pos;
354
355 /* Number of characters past the end of the line above, including the
356 terminating newline. */
357
358 static struct text_pos this_line_end_pos;
359
360 /* The vertical positions and the height of this line. */
361
362 static int this_line_vpos;
363 static int this_line_y;
364 static int this_line_pixel_height;
365
366 /* X position at which this display line starts. Usually zero;
367 negative if first character is partially visible. */
368
369 static int this_line_start_x;
370
371 /* Buffer that this_line_.* variables are referring to. */
372
373 static struct buffer *this_line_buffer;
374
375 /* Nonzero means truncate lines in all windows less wide than the
376 frame. */
377
378 int truncate_partial_width_windows;
379
380 /* A flag to control how to display unibyte 8-bit character. */
381
382 int unibyte_display_via_language_environment;
383
384 /* Nonzero means we have more than one non-mini-buffer-only frame.
385 Not guaranteed to be accurate except while parsing
386 frame-title-format. */
387
388 int multiple_frames;
389
390 Lisp_Object Vglobal_mode_string;
391
392 /* Marker for where to display an arrow on top of the buffer text. */
393
394 Lisp_Object Voverlay_arrow_position;
395
396 /* String to display for the arrow. Only used on terminal frames. */
397
398 Lisp_Object Voverlay_arrow_string;
399
400 /* Values of those variables at last redisplay. However, if
401 Voverlay_arrow_position is a marker, last_arrow_position is its
402 numerical position. */
403
404 static Lisp_Object last_arrow_position, last_arrow_string;
405
406 /* Like mode-line-format, but for the title bar on a visible frame. */
407
408 Lisp_Object Vframe_title_format;
409
410 /* Like mode-line-format, but for the title bar on an iconified frame. */
411
412 Lisp_Object Vicon_title_format;
413
414 /* List of functions to call when a window's size changes. These
415 functions get one arg, a frame on which one or more windows' sizes
416 have changed. */
417
418 static Lisp_Object Vwindow_size_change_functions;
419
420 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
421
422 /* Nonzero if overlay arrow has been displayed once in this window. */
423
424 static int overlay_arrow_seen;
425
426 /* Nonzero means highlight the region even in nonselected windows. */
427
428 int highlight_nonselected_windows;
429
430 /* If cursor motion alone moves point off frame, try scrolling this
431 many lines up or down if that will bring it back. */
432
433 static EMACS_INT scroll_step;
434
435 /* Nonzero means scroll just far enough to bring point back on the
436 screen, when appropriate. */
437
438 static EMACS_INT scroll_conservatively;
439
440 /* Recenter the window whenever point gets within this many lines of
441 the top or bottom of the window. This value is translated into a
442 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
443 that there is really a fixed pixel height scroll margin. */
444
445 EMACS_INT scroll_margin;
446
447 /* Number of windows showing the buffer of the selected window (or
448 another buffer with the same base buffer). keyboard.c refers to
449 this. */
450
451 int buffer_shared;
452
453 /* Vector containing glyphs for an ellipsis `...'. */
454
455 static Lisp_Object default_invis_vector[3];
456
457 /* Zero means display the mode-line/header-line/menu-bar in the default face
458 (this slightly odd definition is for compatibility with previous versions
459 of emacs), non-zero means display them using their respective faces.
460
461 This variable is deprecated. */
462
463 int mode_line_inverse_video;
464
465 /* Prompt to display in front of the mini-buffer contents. */
466
467 Lisp_Object minibuf_prompt;
468
469 /* Width of current mini-buffer prompt. Only set after display_line
470 of the line that contains the prompt. */
471
472 int minibuf_prompt_width;
473
474 /* This is the window where the echo area message was displayed. It
475 is always a mini-buffer window, but it may not be the same window
476 currently active as a mini-buffer. */
477
478 Lisp_Object echo_area_window;
479
480 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
481 pushes the current message and the value of
482 message_enable_multibyte on the stack, the function restore_message
483 pops the stack and displays MESSAGE again. */
484
485 Lisp_Object Vmessage_stack;
486
487 /* Nonzero means multibyte characters were enabled when the echo area
488 message was specified. */
489
490 int message_enable_multibyte;
491
492 /* Nonzero if we should redraw the mode lines on the next redisplay. */
493
494 int update_mode_lines;
495
496 /* Nonzero if window sizes or contents have changed since last
497 redisplay that finished. */
498
499 int windows_or_buffers_changed;
500
501 /* Nonzero means a frame's cursor type has been changed. */
502
503 int cursor_type_changed;
504
505 /* Nonzero after display_mode_line if %l was used and it displayed a
506 line number. */
507
508 int line_number_displayed;
509
510 /* Maximum buffer size for which to display line numbers. */
511
512 Lisp_Object Vline_number_display_limit;
513
514 /* Line width to consider when repositioning for line number display. */
515
516 static EMACS_INT line_number_display_limit_width;
517
518 /* Number of lines to keep in the message log buffer. t means
519 infinite. nil means don't log at all. */
520
521 Lisp_Object Vmessage_log_max;
522
523 /* The name of the *Messages* buffer, a string. */
524
525 static Lisp_Object Vmessages_buffer_name;
526
527 /* Current, index 0, and last displayed echo area message. Either
528 buffers from echo_buffers, or nil to indicate no message. */
529
530 Lisp_Object echo_area_buffer[2];
531
532 /* The buffers referenced from echo_area_buffer. */
533
534 static Lisp_Object echo_buffer[2];
535
536 /* A vector saved used in with_area_buffer to reduce consing. */
537
538 static Lisp_Object Vwith_echo_area_save_vector;
539
540 /* Non-zero means display_echo_area should display the last echo area
541 message again. Set by redisplay_preserve_echo_area. */
542
543 static int display_last_displayed_message_p;
544
545 /* Nonzero if echo area is being used by print; zero if being used by
546 message. */
547
548 int message_buf_print;
549
550 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
551
552 Lisp_Object Qinhibit_menubar_update;
553 int inhibit_menubar_update;
554
555 /* Maximum height for resizing mini-windows. Either a float
556 specifying a fraction of the available height, or an integer
557 specifying a number of lines. */
558
559 Lisp_Object Vmax_mini_window_height;
560
561 /* Non-zero means messages should be displayed with truncated
562 lines instead of being continued. */
563
564 int message_truncate_lines;
565 Lisp_Object Qmessage_truncate_lines;
566
567 /* Set to 1 in clear_message to make redisplay_internal aware
568 of an emptied echo area. */
569
570 static int message_cleared_p;
571
572 /* Non-zero means we want a hollow cursor in windows that are not
573 selected. Zero means there's no cursor in such windows. */
574
575 Lisp_Object Vcursor_in_non_selected_windows;
576 Lisp_Object Qcursor_in_non_selected_windows;
577
578 /* How to blink the default frame cursor off. */
579 Lisp_Object Vblink_cursor_alist;
580
581 /* A scratch glyph row with contents used for generating truncation
582 glyphs. Also used in direct_output_for_insert. */
583
584 #define MAX_SCRATCH_GLYPHS 100
585 struct glyph_row scratch_glyph_row;
586 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
587
588 /* Ascent and height of the last line processed by move_it_to. */
589
590 static int last_max_ascent, last_height;
591
592 /* Non-zero if there's a help-echo in the echo area. */
593
594 int help_echo_showing_p;
595
596 /* If >= 0, computed, exact values of mode-line and header-line height
597 to use in the macros CURRENT_MODE_LINE_HEIGHT and
598 CURRENT_HEADER_LINE_HEIGHT. */
599
600 int current_mode_line_height, current_header_line_height;
601
602 /* The maximum distance to look ahead for text properties. Values
603 that are too small let us call compute_char_face and similar
604 functions too often which is expensive. Values that are too large
605 let us call compute_char_face and alike too often because we
606 might not be interested in text properties that far away. */
607
608 #define TEXT_PROP_DISTANCE_LIMIT 100
609
610 #if GLYPH_DEBUG
611
612 /* Variables to turn off display optimizations from Lisp. */
613
614 int inhibit_try_window_id, inhibit_try_window_reusing;
615 int inhibit_try_cursor_movement;
616
617 /* Non-zero means print traces of redisplay if compiled with
618 GLYPH_DEBUG != 0. */
619
620 int trace_redisplay_p;
621
622 #endif /* GLYPH_DEBUG */
623
624 #ifdef DEBUG_TRACE_MOVE
625 /* Non-zero means trace with TRACE_MOVE to stderr. */
626 int trace_move;
627
628 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
629 #else
630 #define TRACE_MOVE(x) (void) 0
631 #endif
632
633 /* Non-zero means automatically scroll windows horizontally to make
634 point visible. */
635
636 int automatic_hscrolling_p;
637
638 /* How close to the margin can point get before the window is scrolled
639 horizontally. */
640 EMACS_INT hscroll_margin;
641
642 /* How much to scroll horizontally when point is inside the above margin. */
643 Lisp_Object Vhscroll_step;
644
645 /* A list of symbols, one for each supported image type. */
646
647 Lisp_Object Vimage_types;
648
649 /* The variable `resize-mini-windows'. If nil, don't resize
650 mini-windows. If t, always resize them to fit the text they
651 display. If `grow-only', let mini-windows grow only until they
652 become empty. */
653
654 Lisp_Object Vresize_mini_windows;
655
656 /* Buffer being redisplayed -- for redisplay_window_error. */
657
658 struct buffer *displayed_buffer;
659
660 /* Value returned from text property handlers (see below). */
661
662 enum prop_handled
663 {
664 HANDLED_NORMALLY,
665 HANDLED_RECOMPUTE_PROPS,
666 HANDLED_OVERLAY_STRING_CONSUMED,
667 HANDLED_RETURN
668 };
669
670 /* A description of text properties that redisplay is interested
671 in. */
672
673 struct props
674 {
675 /* The name of the property. */
676 Lisp_Object *name;
677
678 /* A unique index for the property. */
679 enum prop_idx idx;
680
681 /* A handler function called to set up iterator IT from the property
682 at IT's current position. Value is used to steer handle_stop. */
683 enum prop_handled (*handler) P_ ((struct it *it));
684 };
685
686 static enum prop_handled handle_face_prop P_ ((struct it *));
687 static enum prop_handled handle_invisible_prop P_ ((struct it *));
688 static enum prop_handled handle_display_prop P_ ((struct it *));
689 static enum prop_handled handle_composition_prop P_ ((struct it *));
690 static enum prop_handled handle_overlay_change P_ ((struct it *));
691 static enum prop_handled handle_fontified_prop P_ ((struct it *));
692
693 /* Properties handled by iterators. */
694
695 static struct props it_props[] =
696 {
697 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
698 /* Handle `face' before `display' because some sub-properties of
699 `display' need to know the face. */
700 {&Qface, FACE_PROP_IDX, handle_face_prop},
701 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
702 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
703 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
704 {NULL, 0, NULL}
705 };
706
707 /* Value is the position described by X. If X is a marker, value is
708 the marker_position of X. Otherwise, value is X. */
709
710 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
711
712 /* Enumeration returned by some move_it_.* functions internally. */
713
714 enum move_it_result
715 {
716 /* Not used. Undefined value. */
717 MOVE_UNDEFINED,
718
719 /* Move ended at the requested buffer position or ZV. */
720 MOVE_POS_MATCH_OR_ZV,
721
722 /* Move ended at the requested X pixel position. */
723 MOVE_X_REACHED,
724
725 /* Move within a line ended at the end of a line that must be
726 continued. */
727 MOVE_LINE_CONTINUED,
728
729 /* Move within a line ended at the end of a line that would
730 be displayed truncated. */
731 MOVE_LINE_TRUNCATED,
732
733 /* Move within a line ended at a line end. */
734 MOVE_NEWLINE_OR_CR
735 };
736
737 /* This counter is used to clear the face cache every once in a while
738 in redisplay_internal. It is incremented for each redisplay.
739 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
740 cleared. */
741
742 #define CLEAR_FACE_CACHE_COUNT 500
743 static int clear_face_cache_count;
744
745 /* Record the previous terminal frame we displayed. */
746
747 static struct frame *previous_terminal_frame;
748
749 /* Non-zero while redisplay_internal is in progress. */
750
751 int redisplaying_p;
752
753 /* Non-zero means don't free realized faces. Bound while freeing
754 realized faces is dangerous because glyph matrices might still
755 reference them. */
756
757 int inhibit_free_realized_faces;
758 Lisp_Object Qinhibit_free_realized_faces;
759
760 /* If a string, XTread_socket generates an event to display that string.
761 (The display is done in read_char.) */
762
763 Lisp_Object help_echo_string;
764 Lisp_Object help_echo_window;
765 Lisp_Object help_echo_object;
766 int help_echo_pos;
767
768 /* Temporary variable for XTread_socket. */
769
770 Lisp_Object previous_help_echo_string;
771
772
773 \f
774 /* Function prototypes. */
775
776 static void setup_for_ellipsis P_ ((struct it *));
777 static void mark_window_display_accurate_1 P_ ((struct window *, int));
778 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
779 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
780 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
781 static int redisplay_mode_lines P_ ((Lisp_Object, int));
782 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
783
784 #if 0
785 static int invisible_text_between_p P_ ((struct it *, int, int));
786 #endif
787
788 static int next_element_from_ellipsis P_ ((struct it *));
789 static void pint2str P_ ((char *, int, int));
790 static void pint2hrstr P_ ((char *, int, int));
791 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
792 struct text_pos));
793 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
794 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
795 static void store_frame_title_char P_ ((char));
796 static int store_frame_title P_ ((const unsigned char *, int, int));
797 static void x_consider_frame_title P_ ((Lisp_Object));
798 static void handle_stop P_ ((struct it *));
799 static int tool_bar_lines_needed P_ ((struct frame *));
800 static int single_display_prop_intangible_p P_ ((Lisp_Object));
801 static void ensure_echo_area_buffers P_ ((void));
802 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
803 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
804 static int with_echo_area_buffer P_ ((struct window *, int,
805 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
806 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
807 static void clear_garbaged_frames P_ ((void));
808 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
809 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
810 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
811 static int display_echo_area P_ ((struct window *));
812 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
813 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
814 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
815 static int string_char_and_length P_ ((const unsigned char *, int, int *));
816 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
817 struct text_pos));
818 static int compute_window_start_on_continuation_line P_ ((struct window *));
819 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
820 static void insert_left_trunc_glyphs P_ ((struct it *));
821 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
822 static void extend_face_to_end_of_line P_ ((struct it *));
823 static int append_space P_ ((struct it *, int));
824 static int make_cursor_line_fully_visible P_ ((struct window *));
825 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
826 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
827 static int trailing_whitespace_p P_ ((int));
828 static int message_log_check_duplicate P_ ((int, int, int, int));
829 static void push_it P_ ((struct it *));
830 static void pop_it P_ ((struct it *));
831 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
832 static void select_frame_for_redisplay P_ ((Lisp_Object));
833 static void redisplay_internal P_ ((int));
834 static int echo_area_display P_ ((int));
835 static void redisplay_windows P_ ((Lisp_Object));
836 static void redisplay_window P_ ((Lisp_Object, int));
837 static Lisp_Object redisplay_window_error ();
838 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
839 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
840 static void update_menu_bar P_ ((struct frame *, int));
841 static int try_window_reusing_current_matrix P_ ((struct window *));
842 static int try_window_id P_ ((struct window *));
843 static int display_line P_ ((struct it *));
844 static int display_mode_lines P_ ((struct window *));
845 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
846 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
847 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
848 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
849 static void display_menu_bar P_ ((struct window *));
850 static int display_count_lines P_ ((int, int, int, int, int *));
851 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
852 int, int, struct it *, int, int, int, int));
853 static void compute_line_metrics P_ ((struct it *));
854 static void run_redisplay_end_trigger_hook P_ ((struct it *));
855 static int get_overlay_strings P_ ((struct it *, int));
856 static void next_overlay_string P_ ((struct it *));
857 static void reseat P_ ((struct it *, struct text_pos, int));
858 static void reseat_1 P_ ((struct it *, struct text_pos, int));
859 static void back_to_previous_visible_line_start P_ ((struct it *));
860 static void reseat_at_previous_visible_line_start P_ ((struct it *));
861 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
862 static int next_element_from_display_vector P_ ((struct it *));
863 static int next_element_from_string P_ ((struct it *));
864 static int next_element_from_c_string P_ ((struct it *));
865 static int next_element_from_buffer P_ ((struct it *));
866 static int next_element_from_composition P_ ((struct it *));
867 static int next_element_from_image P_ ((struct it *));
868 static int next_element_from_stretch P_ ((struct it *));
869 static void load_overlay_strings P_ ((struct it *, int));
870 static int init_from_display_pos P_ ((struct it *, struct window *,
871 struct display_pos *));
872 static void reseat_to_string P_ ((struct it *, unsigned char *,
873 Lisp_Object, int, int, int, int));
874 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
875 int, int, int));
876 void move_it_vertically_backward P_ ((struct it *, int));
877 static void init_to_row_start P_ ((struct it *, struct window *,
878 struct glyph_row *));
879 static int init_to_row_end P_ ((struct it *, struct window *,
880 struct glyph_row *));
881 static void back_to_previous_line_start P_ ((struct it *));
882 static int forward_to_next_line_start P_ ((struct it *, int *));
883 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
884 Lisp_Object, int));
885 static struct text_pos string_pos P_ ((int, Lisp_Object));
886 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
887 static int number_of_chars P_ ((unsigned char *, int));
888 static void compute_stop_pos P_ ((struct it *));
889 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
890 Lisp_Object));
891 static int face_before_or_after_it_pos P_ ((struct it *, int));
892 static int next_overlay_change P_ ((int));
893 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
894 Lisp_Object, struct text_pos *,
895 int));
896 static int underlying_face_id P_ ((struct it *));
897 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
898 struct window *));
899
900 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
901 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
902
903 #ifdef HAVE_WINDOW_SYSTEM
904
905 static void update_tool_bar P_ ((struct frame *, int));
906 static void build_desired_tool_bar_string P_ ((struct frame *f));
907 static int redisplay_tool_bar P_ ((struct frame *));
908 static void display_tool_bar_line P_ ((struct it *));
909 static void notice_overwritten_cursor P_ ((struct window *,
910 enum glyph_row_area,
911 int, int, int, int));
912
913
914
915 #endif /* HAVE_WINDOW_SYSTEM */
916
917 \f
918 /***********************************************************************
919 Window display dimensions
920 ***********************************************************************/
921
922 /* Return the bottom boundary y-position for text lines in window W.
923 This is the first y position at which a line cannot start.
924 It is relative to the top of the window.
925
926 This is the height of W minus the height of a mode line, if any. */
927
928 INLINE int
929 window_text_bottom_y (w)
930 struct window *w;
931 {
932 int height = WINDOW_TOTAL_HEIGHT (w);
933
934 if (WINDOW_WANTS_MODELINE_P (w))
935 height -= CURRENT_MODE_LINE_HEIGHT (w);
936 return height;
937 }
938
939 /* Return the pixel width of display area AREA of window W. AREA < 0
940 means return the total width of W, not including fringes to
941 the left and right of the window. */
942
943 INLINE int
944 window_box_width (w, area)
945 struct window *w;
946 int area;
947 {
948 int cols = XFASTINT (w->total_cols);
949 int pixels = 0;
950
951 if (!w->pseudo_window_p)
952 {
953 cols -= WINDOW_SCROLL_BAR_COLS (w);
954
955 if (area == TEXT_AREA)
956 {
957 if (INTEGERP (w->left_margin_cols))
958 cols -= XFASTINT (w->left_margin_cols);
959 if (INTEGERP (w->right_margin_cols))
960 cols -= XFASTINT (w->right_margin_cols);
961 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
962 }
963 else if (area == LEFT_MARGIN_AREA)
964 {
965 cols = (INTEGERP (w->left_margin_cols)
966 ? XFASTINT (w->left_margin_cols) : 0);
967 pixels = 0;
968 }
969 else if (area == RIGHT_MARGIN_AREA)
970 {
971 cols = (INTEGERP (w->right_margin_cols)
972 ? XFASTINT (w->right_margin_cols) : 0);
973 pixels = 0;
974 }
975 }
976
977 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
978 }
979
980
981 /* Return the pixel height of the display area of window W, not
982 including mode lines of W, if any. */
983
984 INLINE int
985 window_box_height (w)
986 struct window *w;
987 {
988 struct frame *f = XFRAME (w->frame);
989 int height = WINDOW_TOTAL_HEIGHT (w);
990
991 xassert (height >= 0);
992
993 /* Note: the code below that determines the mode-line/header-line
994 height is essentially the same as that contained in the macro
995 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
996 the appropriate glyph row has its `mode_line_p' flag set,
997 and if it doesn't, uses estimate_mode_line_height instead. */
998
999 if (WINDOW_WANTS_MODELINE_P (w))
1000 {
1001 struct glyph_row *ml_row
1002 = (w->current_matrix && w->current_matrix->rows
1003 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1004 : 0);
1005 if (ml_row && ml_row->mode_line_p)
1006 height -= ml_row->height;
1007 else
1008 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1009 }
1010
1011 if (WINDOW_WANTS_HEADER_LINE_P (w))
1012 {
1013 struct glyph_row *hl_row
1014 = (w->current_matrix && w->current_matrix->rows
1015 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1016 : 0);
1017 if (hl_row && hl_row->mode_line_p)
1018 height -= hl_row->height;
1019 else
1020 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1021 }
1022
1023 /* With a very small font and a mode-line that's taller than
1024 default, we might end up with a negative height. */
1025 return max (0, height);
1026 }
1027
1028 /* Return the window-relative coordinate of the left edge of display
1029 area AREA of window W. AREA < 0 means return the left edge of the
1030 whole window, to the right of the left fringe of W. */
1031
1032 INLINE int
1033 window_box_left_offset (w, area)
1034 struct window *w;
1035 int area;
1036 {
1037 int x;
1038
1039 if (w->pseudo_window_p)
1040 return 0;
1041
1042 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1043
1044 if (area == TEXT_AREA)
1045 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1046 + window_box_width (w, LEFT_MARGIN_AREA));
1047 else if (area == RIGHT_MARGIN_AREA)
1048 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1049 + window_box_width (w, LEFT_MARGIN_AREA)
1050 + window_box_width (w, TEXT_AREA)
1051 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1052 ? 0
1053 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1054 else if (area == LEFT_MARGIN_AREA
1055 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1056 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1057
1058 return x;
1059 }
1060
1061
1062 /* Return the window-relative coordinate of the right edge of display
1063 area AREA of window W. AREA < 0 means return the left edge of the
1064 whole window, to the left of the right fringe of W. */
1065
1066 INLINE int
1067 window_box_right_offset (w, area)
1068 struct window *w;
1069 int area;
1070 {
1071 return window_box_left_offset (w, area) + window_box_width (w, area);
1072 }
1073
1074 /* Return the frame-relative coordinate of the left edge of display
1075 area AREA of window W. AREA < 0 means return the left edge of the
1076 whole window, to the right of the left fringe of W. */
1077
1078 INLINE int
1079 window_box_left (w, area)
1080 struct window *w;
1081 int area;
1082 {
1083 struct frame *f = XFRAME (w->frame);
1084 int x;
1085
1086 if (w->pseudo_window_p)
1087 return FRAME_INTERNAL_BORDER_WIDTH (f);
1088
1089 x = (WINDOW_LEFT_EDGE_X (w)
1090 + window_box_left_offset (w, area));
1091
1092 return x;
1093 }
1094
1095
1096 /* Return the frame-relative coordinate of the right edge of display
1097 area AREA of window W. AREA < 0 means return the left edge of the
1098 whole window, to the left of the right fringe of W. */
1099
1100 INLINE int
1101 window_box_right (w, area)
1102 struct window *w;
1103 int area;
1104 {
1105 return window_box_left (w, area) + window_box_width (w, area);
1106 }
1107
1108 /* Get the bounding box of the display area AREA of window W, without
1109 mode lines, in frame-relative coordinates. AREA < 0 means the
1110 whole window, not including the left and right fringes of
1111 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1112 coordinates of the upper-left corner of the box. Return in
1113 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1114
1115 INLINE void
1116 window_box (w, area, box_x, box_y, box_width, box_height)
1117 struct window *w;
1118 int area;
1119 int *box_x, *box_y, *box_width, *box_height;
1120 {
1121 if (box_width)
1122 *box_width = window_box_width (w, area);
1123 if (box_height)
1124 *box_height = window_box_height (w);
1125 if (box_x)
1126 *box_x = window_box_left (w, area);
1127 if (box_y)
1128 {
1129 *box_y = WINDOW_TOP_EDGE_Y (w);
1130 if (WINDOW_WANTS_HEADER_LINE_P (w))
1131 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1132 }
1133 }
1134
1135
1136 /* Get the bounding box of the display area AREA of window W, without
1137 mode lines. AREA < 0 means the whole window, not including the
1138 left and right fringe of the window. Return in *TOP_LEFT_X
1139 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1140 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1141 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1142 box. */
1143
1144 INLINE void
1145 window_box_edges (w, area, top_left_x, top_left_y,
1146 bottom_right_x, bottom_right_y)
1147 struct window *w;
1148 int area;
1149 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1150 {
1151 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1152 bottom_right_y);
1153 *bottom_right_x += *top_left_x;
1154 *bottom_right_y += *top_left_y;
1155 }
1156
1157
1158 \f
1159 /***********************************************************************
1160 Utilities
1161 ***********************************************************************/
1162
1163 /* Return the bottom y-position of the line the iterator IT is in.
1164 This can modify IT's settings. */
1165
1166 int
1167 line_bottom_y (it)
1168 struct it *it;
1169 {
1170 int line_height = it->max_ascent + it->max_descent;
1171 int line_top_y = it->current_y;
1172
1173 if (line_height == 0)
1174 {
1175 if (last_height)
1176 line_height = last_height;
1177 else if (IT_CHARPOS (*it) < ZV)
1178 {
1179 move_it_by_lines (it, 1, 1);
1180 line_height = (it->max_ascent || it->max_descent
1181 ? it->max_ascent + it->max_descent
1182 : last_height);
1183 }
1184 else
1185 {
1186 struct glyph_row *row = it->glyph_row;
1187
1188 /* Use the default character height. */
1189 it->glyph_row = NULL;
1190 it->what = IT_CHARACTER;
1191 it->c = ' ';
1192 it->len = 1;
1193 PRODUCE_GLYPHS (it);
1194 line_height = it->ascent + it->descent;
1195 it->glyph_row = row;
1196 }
1197 }
1198
1199 return line_top_y + line_height;
1200 }
1201
1202
1203 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1204 1 if POS is visible and the line containing POS is fully visible.
1205 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1206 and header-lines heights. */
1207
1208 int
1209 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1210 struct window *w;
1211 int charpos, *fully, exact_mode_line_heights_p;
1212 {
1213 struct it it;
1214 struct text_pos top;
1215 int visible_p;
1216 struct buffer *old_buffer = NULL;
1217
1218 if (XBUFFER (w->buffer) != current_buffer)
1219 {
1220 old_buffer = current_buffer;
1221 set_buffer_internal_1 (XBUFFER (w->buffer));
1222 }
1223
1224 *fully = visible_p = 0;
1225 SET_TEXT_POS_FROM_MARKER (top, w->start);
1226
1227 /* Compute exact mode line heights, if requested. */
1228 if (exact_mode_line_heights_p)
1229 {
1230 if (WINDOW_WANTS_MODELINE_P (w))
1231 current_mode_line_height
1232 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1233 current_buffer->mode_line_format);
1234
1235 if (WINDOW_WANTS_HEADER_LINE_P (w))
1236 current_header_line_height
1237 = display_mode_line (w, HEADER_LINE_FACE_ID,
1238 current_buffer->header_line_format);
1239 }
1240
1241 start_display (&it, w, top);
1242 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1243 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1244
1245 /* Note that we may overshoot because of invisible text. */
1246 if (IT_CHARPOS (it) >= charpos)
1247 {
1248 int top_y = it.current_y;
1249 int bottom_y = line_bottom_y (&it);
1250 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1251
1252 if (top_y < window_top_y)
1253 visible_p = bottom_y > window_top_y;
1254 else if (top_y < it.last_visible_y)
1255 {
1256 visible_p = 1;
1257 *fully = bottom_y <= it.last_visible_y;
1258 }
1259 }
1260 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1261 {
1262 move_it_by_lines (&it, 1, 0);
1263 if (charpos < IT_CHARPOS (it))
1264 {
1265 visible_p = 1;
1266 *fully = 0;
1267 }
1268 }
1269
1270 if (old_buffer)
1271 set_buffer_internal_1 (old_buffer);
1272
1273 current_header_line_height = current_mode_line_height = -1;
1274 return visible_p;
1275 }
1276
1277
1278 /* Return the next character from STR which is MAXLEN bytes long.
1279 Return in *LEN the length of the character. This is like
1280 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1281 we find one, we return a `?', but with the length of the invalid
1282 character. */
1283
1284 static INLINE int
1285 string_char_and_length (str, maxlen, len)
1286 const unsigned char *str;
1287 int maxlen, *len;
1288 {
1289 int c;
1290
1291 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1292 if (!CHAR_VALID_P (c, 1))
1293 /* We may not change the length here because other places in Emacs
1294 don't use this function, i.e. they silently accept invalid
1295 characters. */
1296 c = '?';
1297
1298 return c;
1299 }
1300
1301
1302
1303 /* Given a position POS containing a valid character and byte position
1304 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1305
1306 static struct text_pos
1307 string_pos_nchars_ahead (pos, string, nchars)
1308 struct text_pos pos;
1309 Lisp_Object string;
1310 int nchars;
1311 {
1312 xassert (STRINGP (string) && nchars >= 0);
1313
1314 if (STRING_MULTIBYTE (string))
1315 {
1316 int rest = SBYTES (string) - BYTEPOS (pos);
1317 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1318 int len;
1319
1320 while (nchars--)
1321 {
1322 string_char_and_length (p, rest, &len);
1323 p += len, rest -= len;
1324 xassert (rest >= 0);
1325 CHARPOS (pos) += 1;
1326 BYTEPOS (pos) += len;
1327 }
1328 }
1329 else
1330 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1331
1332 return pos;
1333 }
1334
1335
1336 /* Value is the text position, i.e. character and byte position,
1337 for character position CHARPOS in STRING. */
1338
1339 static INLINE struct text_pos
1340 string_pos (charpos, string)
1341 int charpos;
1342 Lisp_Object string;
1343 {
1344 struct text_pos pos;
1345 xassert (STRINGP (string));
1346 xassert (charpos >= 0);
1347 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1348 return pos;
1349 }
1350
1351
1352 /* Value is a text position, i.e. character and byte position, for
1353 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1354 means recognize multibyte characters. */
1355
1356 static struct text_pos
1357 c_string_pos (charpos, s, multibyte_p)
1358 int charpos;
1359 unsigned char *s;
1360 int multibyte_p;
1361 {
1362 struct text_pos pos;
1363
1364 xassert (s != NULL);
1365 xassert (charpos >= 0);
1366
1367 if (multibyte_p)
1368 {
1369 int rest = strlen (s), len;
1370
1371 SET_TEXT_POS (pos, 0, 0);
1372 while (charpos--)
1373 {
1374 string_char_and_length (s, rest, &len);
1375 s += len, rest -= len;
1376 xassert (rest >= 0);
1377 CHARPOS (pos) += 1;
1378 BYTEPOS (pos) += len;
1379 }
1380 }
1381 else
1382 SET_TEXT_POS (pos, charpos, charpos);
1383
1384 return pos;
1385 }
1386
1387
1388 /* Value is the number of characters in C string S. MULTIBYTE_P
1389 non-zero means recognize multibyte characters. */
1390
1391 static int
1392 number_of_chars (s, multibyte_p)
1393 unsigned char *s;
1394 int multibyte_p;
1395 {
1396 int nchars;
1397
1398 if (multibyte_p)
1399 {
1400 int rest = strlen (s), len;
1401 unsigned char *p = (unsigned char *) s;
1402
1403 for (nchars = 0; rest > 0; ++nchars)
1404 {
1405 string_char_and_length (p, rest, &len);
1406 rest -= len, p += len;
1407 }
1408 }
1409 else
1410 nchars = strlen (s);
1411
1412 return nchars;
1413 }
1414
1415
1416 /* Compute byte position NEWPOS->bytepos corresponding to
1417 NEWPOS->charpos. POS is a known position in string STRING.
1418 NEWPOS->charpos must be >= POS.charpos. */
1419
1420 static void
1421 compute_string_pos (newpos, pos, string)
1422 struct text_pos *newpos, pos;
1423 Lisp_Object string;
1424 {
1425 xassert (STRINGP (string));
1426 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1427
1428 if (STRING_MULTIBYTE (string))
1429 *newpos = string_pos_nchars_ahead (pos, string,
1430 CHARPOS (*newpos) - CHARPOS (pos));
1431 else
1432 BYTEPOS (*newpos) = CHARPOS (*newpos);
1433 }
1434
1435 /* EXPORT:
1436 Return an estimation of the pixel height of mode or top lines on
1437 frame F. FACE_ID specifies what line's height to estimate. */
1438
1439 int
1440 estimate_mode_line_height (f, face_id)
1441 struct frame *f;
1442 enum face_id face_id;
1443 {
1444 #ifdef HAVE_WINDOW_SYSTEM
1445 if (FRAME_WINDOW_P (f))
1446 {
1447 int height = FONT_HEIGHT (FRAME_FONT (f));
1448
1449 /* This function is called so early when Emacs starts that the face
1450 cache and mode line face are not yet initialized. */
1451 if (FRAME_FACE_CACHE (f))
1452 {
1453 struct face *face = FACE_FROM_ID (f, face_id);
1454 if (face)
1455 {
1456 if (face->font)
1457 height = FONT_HEIGHT (face->font);
1458 if (face->box_line_width > 0)
1459 height += 2 * face->box_line_width;
1460 }
1461 }
1462
1463 return height;
1464 }
1465 #endif
1466
1467 return 1;
1468 }
1469
1470 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1471 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1472 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1473 not force the value into range. */
1474
1475 void
1476 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1477 FRAME_PTR f;
1478 register int pix_x, pix_y;
1479 int *x, *y;
1480 NativeRectangle *bounds;
1481 int noclip;
1482 {
1483
1484 #ifdef HAVE_WINDOW_SYSTEM
1485 if (FRAME_WINDOW_P (f))
1486 {
1487 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1488 even for negative values. */
1489 if (pix_x < 0)
1490 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1491 if (pix_y < 0)
1492 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1493
1494 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1495 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1496
1497 if (bounds)
1498 STORE_NATIVE_RECT (*bounds,
1499 FRAME_COL_TO_PIXEL_X (f, pix_x),
1500 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1501 FRAME_COLUMN_WIDTH (f) - 1,
1502 FRAME_LINE_HEIGHT (f) - 1);
1503
1504 if (!noclip)
1505 {
1506 if (pix_x < 0)
1507 pix_x = 0;
1508 else if (pix_x > FRAME_TOTAL_COLS (f))
1509 pix_x = FRAME_TOTAL_COLS (f);
1510
1511 if (pix_y < 0)
1512 pix_y = 0;
1513 else if (pix_y > FRAME_LINES (f))
1514 pix_y = FRAME_LINES (f);
1515 }
1516 }
1517 #endif
1518
1519 *x = pix_x;
1520 *y = pix_y;
1521 }
1522
1523
1524 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1525 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1526 can't tell the positions because W's display is not up to date,
1527 return 0. */
1528
1529 int
1530 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1531 struct window *w;
1532 int hpos, vpos;
1533 int *frame_x, *frame_y;
1534 {
1535 #ifdef HAVE_WINDOW_SYSTEM
1536 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1537 {
1538 int success_p;
1539
1540 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1541 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1542
1543 if (display_completed)
1544 {
1545 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1546 struct glyph *glyph = row->glyphs[TEXT_AREA];
1547 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1548
1549 hpos = row->x;
1550 vpos = row->y;
1551 while (glyph < end)
1552 {
1553 hpos += glyph->pixel_width;
1554 ++glyph;
1555 }
1556
1557 /* If first glyph is partially visible, its first visible position is still 0. */
1558 if (hpos < 0)
1559 hpos = 0;
1560
1561 success_p = 1;
1562 }
1563 else
1564 {
1565 hpos = vpos = 0;
1566 success_p = 0;
1567 }
1568
1569 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1570 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1571 return success_p;
1572 }
1573 #endif
1574
1575 *frame_x = hpos;
1576 *frame_y = vpos;
1577 return 1;
1578 }
1579
1580
1581 #ifdef HAVE_WINDOW_SYSTEM
1582
1583 /* Find the glyph under window-relative coordinates X/Y in window W.
1584 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1585 strings. Return in *HPOS and *VPOS the row and column number of
1586 the glyph found. Return in *AREA the glyph area containing X.
1587 Value is a pointer to the glyph found or null if X/Y is not on
1588 text, or we can't tell because W's current matrix is not up to
1589 date. */
1590
1591 static struct glyph *
1592 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1593 struct window *w;
1594 int x, y;
1595 int *hpos, *vpos, *dx, *dy, *area;
1596 {
1597 struct glyph *glyph, *end;
1598 struct glyph_row *row = NULL;
1599 int x0, i;
1600
1601 /* Find row containing Y. Give up if some row is not enabled. */
1602 for (i = 0; i < w->current_matrix->nrows; ++i)
1603 {
1604 row = MATRIX_ROW (w->current_matrix, i);
1605 if (!row->enabled_p)
1606 return NULL;
1607 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1608 break;
1609 }
1610
1611 *vpos = i;
1612 *hpos = 0;
1613
1614 /* Give up if Y is not in the window. */
1615 if (i == w->current_matrix->nrows)
1616 return NULL;
1617
1618 /* Get the glyph area containing X. */
1619 if (w->pseudo_window_p)
1620 {
1621 *area = TEXT_AREA;
1622 x0 = 0;
1623 }
1624 else
1625 {
1626 if (x < window_box_left_offset (w, TEXT_AREA))
1627 {
1628 *area = LEFT_MARGIN_AREA;
1629 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1630 }
1631 else if (x < window_box_right_offset (w, TEXT_AREA))
1632 {
1633 *area = TEXT_AREA;
1634 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1635 }
1636 else
1637 {
1638 *area = RIGHT_MARGIN_AREA;
1639 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1640 }
1641 }
1642
1643 /* Find glyph containing X. */
1644 glyph = row->glyphs[*area];
1645 end = glyph + row->used[*area];
1646 x -= x0;
1647 while (glyph < end && x >= glyph->pixel_width)
1648 {
1649 x -= glyph->pixel_width;
1650 ++glyph;
1651 }
1652
1653 if (glyph == end)
1654 return NULL;
1655
1656 if (dx)
1657 {
1658 *dx = x;
1659 *dy = y - (row->y + row->ascent - glyph->ascent);
1660 }
1661
1662 *hpos = glyph - row->glyphs[*area];
1663 return glyph;
1664 }
1665
1666
1667 /* EXPORT:
1668 Convert frame-relative x/y to coordinates relative to window W.
1669 Takes pseudo-windows into account. */
1670
1671 void
1672 frame_to_window_pixel_xy (w, x, y)
1673 struct window *w;
1674 int *x, *y;
1675 {
1676 if (w->pseudo_window_p)
1677 {
1678 /* A pseudo-window is always full-width, and starts at the
1679 left edge of the frame, plus a frame border. */
1680 struct frame *f = XFRAME (w->frame);
1681 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1682 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1683 }
1684 else
1685 {
1686 *x -= WINDOW_LEFT_EDGE_X (w);
1687 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1688 }
1689 }
1690
1691 /* EXPORT:
1692 Return in *R the clipping rectangle for glyph string S. */
1693
1694 void
1695 get_glyph_string_clip_rect (s, nr)
1696 struct glyph_string *s;
1697 NativeRectangle *nr;
1698 {
1699 XRectangle r;
1700
1701 if (s->row->full_width_p)
1702 {
1703 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1704 r.x = WINDOW_LEFT_EDGE_X (s->w);
1705 r.width = WINDOW_TOTAL_WIDTH (s->w);
1706
1707 /* Unless displaying a mode or menu bar line, which are always
1708 fully visible, clip to the visible part of the row. */
1709 if (s->w->pseudo_window_p)
1710 r.height = s->row->visible_height;
1711 else
1712 r.height = s->height;
1713 }
1714 else
1715 {
1716 /* This is a text line that may be partially visible. */
1717 r.x = window_box_left (s->w, s->area);
1718 r.width = window_box_width (s->w, s->area);
1719 r.height = s->row->visible_height;
1720 }
1721
1722 /* If S draws overlapping rows, it's sufficient to use the top and
1723 bottom of the window for clipping because this glyph string
1724 intentionally draws over other lines. */
1725 if (s->for_overlaps_p)
1726 {
1727 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1728 r.height = window_text_bottom_y (s->w) - r.y;
1729 }
1730 else
1731 {
1732 /* Don't use S->y for clipping because it doesn't take partially
1733 visible lines into account. For example, it can be negative for
1734 partially visible lines at the top of a window. */
1735 if (!s->row->full_width_p
1736 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1737 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1738 else
1739 r.y = max (0, s->row->y);
1740
1741 /* If drawing a tool-bar window, draw it over the internal border
1742 at the top of the window. */
1743 if (s->w == XWINDOW (s->f->tool_bar_window))
1744 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1745 }
1746
1747 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1748
1749 /* If drawing the cursor, don't let glyph draw outside its
1750 advertised boundaries. Cleartype does this under some circumstances. */
1751 if (s->hl == DRAW_CURSOR)
1752 {
1753 struct glyph *glyph = s->first_glyph;
1754 int height;
1755
1756 if (s->x > r.x)
1757 {
1758 r.width -= s->x - r.x;
1759 r.x = s->x;
1760 }
1761 r.width = min (r.width, glyph->pixel_width);
1762
1763 /* Don't draw cursor glyph taller than our actual glyph. */
1764 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1765 if (height < r.height)
1766 {
1767 r.y = s->ybase + glyph->descent - height;
1768 r.height = height;
1769 }
1770 }
1771
1772 #ifdef CONVERT_FROM_XRECT
1773 CONVERT_FROM_XRECT (r, *nr);
1774 #else
1775 *nr = r;
1776 #endif
1777 }
1778
1779 #endif /* HAVE_WINDOW_SYSTEM */
1780
1781 \f
1782 /***********************************************************************
1783 Lisp form evaluation
1784 ***********************************************************************/
1785
1786 /* Error handler for safe_eval and safe_call. */
1787
1788 static Lisp_Object
1789 safe_eval_handler (arg)
1790 Lisp_Object arg;
1791 {
1792 add_to_log ("Error during redisplay: %s", arg, Qnil);
1793 return Qnil;
1794 }
1795
1796
1797 /* Evaluate SEXPR and return the result, or nil if something went
1798 wrong. Prevent redisplay during the evaluation. */
1799
1800 Lisp_Object
1801 safe_eval (sexpr)
1802 Lisp_Object sexpr;
1803 {
1804 Lisp_Object val;
1805
1806 if (inhibit_eval_during_redisplay)
1807 val = Qnil;
1808 else
1809 {
1810 int count = SPECPDL_INDEX ();
1811 struct gcpro gcpro1;
1812
1813 GCPRO1 (sexpr);
1814 specbind (Qinhibit_redisplay, Qt);
1815 /* Use Qt to ensure debugger does not run,
1816 so there is no possibility of wanting to redisplay. */
1817 val = internal_condition_case_1 (Feval, sexpr, Qt,
1818 safe_eval_handler);
1819 UNGCPRO;
1820 val = unbind_to (count, val);
1821 }
1822
1823 return val;
1824 }
1825
1826
1827 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1828 Return the result, or nil if something went wrong. Prevent
1829 redisplay during the evaluation. */
1830
1831 Lisp_Object
1832 safe_call (nargs, args)
1833 int nargs;
1834 Lisp_Object *args;
1835 {
1836 Lisp_Object val;
1837
1838 if (inhibit_eval_during_redisplay)
1839 val = Qnil;
1840 else
1841 {
1842 int count = SPECPDL_INDEX ();
1843 struct gcpro gcpro1;
1844
1845 GCPRO1 (args[0]);
1846 gcpro1.nvars = nargs;
1847 specbind (Qinhibit_redisplay, Qt);
1848 /* Use Qt to ensure debugger does not run,
1849 so there is no possibility of wanting to redisplay. */
1850 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1851 safe_eval_handler);
1852 UNGCPRO;
1853 val = unbind_to (count, val);
1854 }
1855
1856 return val;
1857 }
1858
1859
1860 /* Call function FN with one argument ARG.
1861 Return the result, or nil if something went wrong. */
1862
1863 Lisp_Object
1864 safe_call1 (fn, arg)
1865 Lisp_Object fn, arg;
1866 {
1867 Lisp_Object args[2];
1868 args[0] = fn;
1869 args[1] = arg;
1870 return safe_call (2, args);
1871 }
1872
1873
1874 \f
1875 /***********************************************************************
1876 Debugging
1877 ***********************************************************************/
1878
1879 #if 0
1880
1881 /* Define CHECK_IT to perform sanity checks on iterators.
1882 This is for debugging. It is too slow to do unconditionally. */
1883
1884 static void
1885 check_it (it)
1886 struct it *it;
1887 {
1888 if (it->method == next_element_from_string)
1889 {
1890 xassert (STRINGP (it->string));
1891 xassert (IT_STRING_CHARPOS (*it) >= 0);
1892 }
1893 else if (it->method == next_element_from_buffer)
1894 {
1895 /* Check that character and byte positions agree. */
1896 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1897 }
1898
1899 if (it->dpvec)
1900 xassert (it->current.dpvec_index >= 0);
1901 else
1902 xassert (it->current.dpvec_index < 0);
1903 }
1904
1905 #define CHECK_IT(IT) check_it ((IT))
1906
1907 #else /* not 0 */
1908
1909 #define CHECK_IT(IT) (void) 0
1910
1911 #endif /* not 0 */
1912
1913
1914 #if GLYPH_DEBUG
1915
1916 /* Check that the window end of window W is what we expect it
1917 to be---the last row in the current matrix displaying text. */
1918
1919 static void
1920 check_window_end (w)
1921 struct window *w;
1922 {
1923 if (!MINI_WINDOW_P (w)
1924 && !NILP (w->window_end_valid))
1925 {
1926 struct glyph_row *row;
1927 xassert ((row = MATRIX_ROW (w->current_matrix,
1928 XFASTINT (w->window_end_vpos)),
1929 !row->enabled_p
1930 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1931 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1932 }
1933 }
1934
1935 #define CHECK_WINDOW_END(W) check_window_end ((W))
1936
1937 #else /* not GLYPH_DEBUG */
1938
1939 #define CHECK_WINDOW_END(W) (void) 0
1940
1941 #endif /* not GLYPH_DEBUG */
1942
1943
1944 \f
1945 /***********************************************************************
1946 Iterator initialization
1947 ***********************************************************************/
1948
1949 /* Initialize IT for displaying current_buffer in window W, starting
1950 at character position CHARPOS. CHARPOS < 0 means that no buffer
1951 position is specified which is useful when the iterator is assigned
1952 a position later. BYTEPOS is the byte position corresponding to
1953 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1954
1955 If ROW is not null, calls to produce_glyphs with IT as parameter
1956 will produce glyphs in that row.
1957
1958 BASE_FACE_ID is the id of a base face to use. It must be one of
1959 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1960 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1961 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1962
1963 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1964 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1965 will be initialized to use the corresponding mode line glyph row of
1966 the desired matrix of W. */
1967
1968 void
1969 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1970 struct it *it;
1971 struct window *w;
1972 int charpos, bytepos;
1973 struct glyph_row *row;
1974 enum face_id base_face_id;
1975 {
1976 int highlight_region_p;
1977
1978 /* Some precondition checks. */
1979 xassert (w != NULL && it != NULL);
1980 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
1981 && charpos <= ZV));
1982
1983 /* If face attributes have been changed since the last redisplay,
1984 free realized faces now because they depend on face definitions
1985 that might have changed. Don't free faces while there might be
1986 desired matrices pending which reference these faces. */
1987 if (face_change_count && !inhibit_free_realized_faces)
1988 {
1989 face_change_count = 0;
1990 free_all_realized_faces (Qnil);
1991 }
1992
1993 /* Use one of the mode line rows of W's desired matrix if
1994 appropriate. */
1995 if (row == NULL)
1996 {
1997 if (base_face_id == MODE_LINE_FACE_ID
1998 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
1999 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2000 else if (base_face_id == HEADER_LINE_FACE_ID)
2001 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2002 }
2003
2004 /* Clear IT. */
2005 bzero (it, sizeof *it);
2006 it->current.overlay_string_index = -1;
2007 it->current.dpvec_index = -1;
2008 it->base_face_id = base_face_id;
2009
2010 /* The window in which we iterate over current_buffer: */
2011 XSETWINDOW (it->window, w);
2012 it->w = w;
2013 it->f = XFRAME (w->frame);
2014
2015 /* Extra space between lines (on window systems only). */
2016 if (base_face_id == DEFAULT_FACE_ID
2017 && FRAME_WINDOW_P (it->f))
2018 {
2019 if (NATNUMP (current_buffer->extra_line_spacing))
2020 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2021 else if (it->f->extra_line_spacing > 0)
2022 it->extra_line_spacing = it->f->extra_line_spacing;
2023 }
2024
2025 /* If realized faces have been removed, e.g. because of face
2026 attribute changes of named faces, recompute them. When running
2027 in batch mode, the face cache of Vterminal_frame is null. If
2028 we happen to get called, make a dummy face cache. */
2029 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2030 init_frame_faces (it->f);
2031 if (FRAME_FACE_CACHE (it->f)->used == 0)
2032 recompute_basic_faces (it->f);
2033
2034 /* Current value of the `space-width', and 'height' properties. */
2035 it->space_width = Qnil;
2036 it->font_height = Qnil;
2037
2038 /* Are control characters displayed as `^C'? */
2039 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2040
2041 /* -1 means everything between a CR and the following line end
2042 is invisible. >0 means lines indented more than this value are
2043 invisible. */
2044 it->selective = (INTEGERP (current_buffer->selective_display)
2045 ? XFASTINT (current_buffer->selective_display)
2046 : (!NILP (current_buffer->selective_display)
2047 ? -1 : 0));
2048 it->selective_display_ellipsis_p
2049 = !NILP (current_buffer->selective_display_ellipses);
2050
2051 /* Display table to use. */
2052 it->dp = window_display_table (w);
2053
2054 /* Are multibyte characters enabled in current_buffer? */
2055 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2056
2057 /* Non-zero if we should highlight the region. */
2058 highlight_region_p
2059 = (!NILP (Vtransient_mark_mode)
2060 && !NILP (current_buffer->mark_active)
2061 && XMARKER (current_buffer->mark)->buffer != 0);
2062
2063 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2064 start and end of a visible region in window IT->w. Set both to
2065 -1 to indicate no region. */
2066 if (highlight_region_p
2067 /* Maybe highlight only in selected window. */
2068 && (/* Either show region everywhere. */
2069 highlight_nonselected_windows
2070 /* Or show region in the selected window. */
2071 || w == XWINDOW (selected_window)
2072 /* Or show the region if we are in the mini-buffer and W is
2073 the window the mini-buffer refers to. */
2074 || (MINI_WINDOW_P (XWINDOW (selected_window))
2075 && WINDOWP (minibuf_selected_window)
2076 && w == XWINDOW (minibuf_selected_window))))
2077 {
2078 int charpos = marker_position (current_buffer->mark);
2079 it->region_beg_charpos = min (PT, charpos);
2080 it->region_end_charpos = max (PT, charpos);
2081 }
2082 else
2083 it->region_beg_charpos = it->region_end_charpos = -1;
2084
2085 /* Get the position at which the redisplay_end_trigger hook should
2086 be run, if it is to be run at all. */
2087 if (MARKERP (w->redisplay_end_trigger)
2088 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2089 it->redisplay_end_trigger_charpos
2090 = marker_position (w->redisplay_end_trigger);
2091 else if (INTEGERP (w->redisplay_end_trigger))
2092 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2093
2094 /* Correct bogus values of tab_width. */
2095 it->tab_width = XINT (current_buffer->tab_width);
2096 if (it->tab_width <= 0 || it->tab_width > 1000)
2097 it->tab_width = 8;
2098
2099 /* Are lines in the display truncated? */
2100 it->truncate_lines_p
2101 = (base_face_id != DEFAULT_FACE_ID
2102 || XINT (it->w->hscroll)
2103 || (truncate_partial_width_windows
2104 && !WINDOW_FULL_WIDTH_P (it->w))
2105 || !NILP (current_buffer->truncate_lines));
2106
2107 /* Get dimensions of truncation and continuation glyphs. These are
2108 displayed as fringe bitmaps under X, so we don't need them for such
2109 frames. */
2110 if (!FRAME_WINDOW_P (it->f))
2111 {
2112 if (it->truncate_lines_p)
2113 {
2114 /* We will need the truncation glyph. */
2115 xassert (it->glyph_row == NULL);
2116 produce_special_glyphs (it, IT_TRUNCATION);
2117 it->truncation_pixel_width = it->pixel_width;
2118 }
2119 else
2120 {
2121 /* We will need the continuation glyph. */
2122 xassert (it->glyph_row == NULL);
2123 produce_special_glyphs (it, IT_CONTINUATION);
2124 it->continuation_pixel_width = it->pixel_width;
2125 }
2126
2127 /* Reset these values to zero because the produce_special_glyphs
2128 above has changed them. */
2129 it->pixel_width = it->ascent = it->descent = 0;
2130 it->phys_ascent = it->phys_descent = 0;
2131 }
2132
2133 /* Set this after getting the dimensions of truncation and
2134 continuation glyphs, so that we don't produce glyphs when calling
2135 produce_special_glyphs, above. */
2136 it->glyph_row = row;
2137 it->area = TEXT_AREA;
2138
2139 /* Get the dimensions of the display area. The display area
2140 consists of the visible window area plus a horizontally scrolled
2141 part to the left of the window. All x-values are relative to the
2142 start of this total display area. */
2143 if (base_face_id != DEFAULT_FACE_ID)
2144 {
2145 /* Mode lines, menu bar in terminal frames. */
2146 it->first_visible_x = 0;
2147 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2148 }
2149 else
2150 {
2151 it->first_visible_x
2152 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2153 it->last_visible_x = (it->first_visible_x
2154 + window_box_width (w, TEXT_AREA));
2155
2156 /* If we truncate lines, leave room for the truncator glyph(s) at
2157 the right margin. Otherwise, leave room for the continuation
2158 glyph(s). Truncation and continuation glyphs are not inserted
2159 for window-based redisplay. */
2160 if (!FRAME_WINDOW_P (it->f))
2161 {
2162 if (it->truncate_lines_p)
2163 it->last_visible_x -= it->truncation_pixel_width;
2164 else
2165 it->last_visible_x -= it->continuation_pixel_width;
2166 }
2167
2168 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2169 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2170 }
2171
2172 /* Leave room for a border glyph. */
2173 if (!FRAME_WINDOW_P (it->f)
2174 && !WINDOW_RIGHTMOST_P (it->w))
2175 it->last_visible_x -= 1;
2176
2177 it->last_visible_y = window_text_bottom_y (w);
2178
2179 /* For mode lines and alike, arrange for the first glyph having a
2180 left box line if the face specifies a box. */
2181 if (base_face_id != DEFAULT_FACE_ID)
2182 {
2183 struct face *face;
2184
2185 it->face_id = base_face_id;
2186
2187 /* If we have a boxed mode line, make the first character appear
2188 with a left box line. */
2189 face = FACE_FROM_ID (it->f, base_face_id);
2190 if (face->box != FACE_NO_BOX)
2191 it->start_of_box_run_p = 1;
2192 }
2193
2194 /* If a buffer position was specified, set the iterator there,
2195 getting overlays and face properties from that position. */
2196 if (charpos >= BUF_BEG (current_buffer))
2197 {
2198 it->end_charpos = ZV;
2199 it->face_id = -1;
2200 IT_CHARPOS (*it) = charpos;
2201
2202 /* Compute byte position if not specified. */
2203 if (bytepos < charpos)
2204 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2205 else
2206 IT_BYTEPOS (*it) = bytepos;
2207
2208 it->start = it->current;
2209
2210 /* Compute faces etc. */
2211 reseat (it, it->current.pos, 1);
2212 }
2213
2214 CHECK_IT (it);
2215 }
2216
2217
2218 /* Initialize IT for the display of window W with window start POS. */
2219
2220 void
2221 start_display (it, w, pos)
2222 struct it *it;
2223 struct window *w;
2224 struct text_pos pos;
2225 {
2226 struct glyph_row *row;
2227 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2228
2229 row = w->desired_matrix->rows + first_vpos;
2230 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2231 it->first_vpos = first_vpos;
2232
2233 if (!it->truncate_lines_p)
2234 {
2235 int start_at_line_beg_p;
2236 int first_y = it->current_y;
2237
2238 /* If window start is not at a line start, skip forward to POS to
2239 get the correct continuation lines width. */
2240 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2241 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2242 if (!start_at_line_beg_p)
2243 {
2244 int new_x;
2245
2246 reseat_at_previous_visible_line_start (it);
2247 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2248
2249 new_x = it->current_x + it->pixel_width;
2250
2251 /* If lines are continued, this line may end in the middle
2252 of a multi-glyph character (e.g. a control character
2253 displayed as \003, or in the middle of an overlay
2254 string). In this case move_it_to above will not have
2255 taken us to the start of the continuation line but to the
2256 end of the continued line. */
2257 if (it->current_x > 0
2258 && !it->truncate_lines_p /* Lines are continued. */
2259 && (/* And glyph doesn't fit on the line. */
2260 new_x > it->last_visible_x
2261 /* Or it fits exactly and we're on a window
2262 system frame. */
2263 || (new_x == it->last_visible_x
2264 && FRAME_WINDOW_P (it->f))))
2265 {
2266 if (it->current.dpvec_index >= 0
2267 || it->current.overlay_string_index >= 0)
2268 {
2269 set_iterator_to_next (it, 1);
2270 move_it_in_display_line_to (it, -1, -1, 0);
2271 }
2272
2273 it->continuation_lines_width += it->current_x;
2274 }
2275
2276 /* We're starting a new display line, not affected by the
2277 height of the continued line, so clear the appropriate
2278 fields in the iterator structure. */
2279 it->max_ascent = it->max_descent = 0;
2280 it->max_phys_ascent = it->max_phys_descent = 0;
2281
2282 it->current_y = first_y;
2283 it->vpos = 0;
2284 it->current_x = it->hpos = 0;
2285 }
2286 }
2287
2288 #if 0 /* Don't assert the following because start_display is sometimes
2289 called intentionally with a window start that is not at a
2290 line start. Please leave this code in as a comment. */
2291
2292 /* Window start should be on a line start, now. */
2293 xassert (it->continuation_lines_width
2294 || IT_CHARPOS (it) == BEGV
2295 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2296 #endif /* 0 */
2297 }
2298
2299
2300 /* Return 1 if POS is a position in ellipses displayed for invisible
2301 text. W is the window we display, for text property lookup. */
2302
2303 static int
2304 in_ellipses_for_invisible_text_p (pos, w)
2305 struct display_pos *pos;
2306 struct window *w;
2307 {
2308 Lisp_Object prop, window;
2309 int ellipses_p = 0;
2310 int charpos = CHARPOS (pos->pos);
2311
2312 /* If POS specifies a position in a display vector, this might
2313 be for an ellipsis displayed for invisible text. We won't
2314 get the iterator set up for delivering that ellipsis unless
2315 we make sure that it gets aware of the invisible text. */
2316 if (pos->dpvec_index >= 0
2317 && pos->overlay_string_index < 0
2318 && CHARPOS (pos->string_pos) < 0
2319 && charpos > BEGV
2320 && (XSETWINDOW (window, w),
2321 prop = Fget_char_property (make_number (charpos),
2322 Qinvisible, window),
2323 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2324 {
2325 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2326 window);
2327 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2328 }
2329
2330 return ellipses_p;
2331 }
2332
2333
2334 /* Initialize IT for stepping through current_buffer in window W,
2335 starting at position POS that includes overlay string and display
2336 vector/ control character translation position information. Value
2337 is zero if there are overlay strings with newlines at POS. */
2338
2339 static int
2340 init_from_display_pos (it, w, pos)
2341 struct it *it;
2342 struct window *w;
2343 struct display_pos *pos;
2344 {
2345 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2346 int i, overlay_strings_with_newlines = 0;
2347
2348 /* If POS specifies a position in a display vector, this might
2349 be for an ellipsis displayed for invisible text. We won't
2350 get the iterator set up for delivering that ellipsis unless
2351 we make sure that it gets aware of the invisible text. */
2352 if (in_ellipses_for_invisible_text_p (pos, w))
2353 {
2354 --charpos;
2355 bytepos = 0;
2356 }
2357
2358 /* Keep in mind: the call to reseat in init_iterator skips invisible
2359 text, so we might end up at a position different from POS. This
2360 is only a problem when POS is a row start after a newline and an
2361 overlay starts there with an after-string, and the overlay has an
2362 invisible property. Since we don't skip invisible text in
2363 display_line and elsewhere immediately after consuming the
2364 newline before the row start, such a POS will not be in a string,
2365 but the call to init_iterator below will move us to the
2366 after-string. */
2367 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2368
2369 for (i = 0; i < it->n_overlay_strings; ++i)
2370 {
2371 const char *s = SDATA (it->overlay_strings[i]);
2372 const char *e = s + SBYTES (it->overlay_strings[i]);
2373
2374 while (s < e && *s != '\n')
2375 ++s;
2376
2377 if (s < e)
2378 {
2379 overlay_strings_with_newlines = 1;
2380 break;
2381 }
2382 }
2383
2384 /* If position is within an overlay string, set up IT to the right
2385 overlay string. */
2386 if (pos->overlay_string_index >= 0)
2387 {
2388 int relative_index;
2389
2390 /* If the first overlay string happens to have a `display'
2391 property for an image, the iterator will be set up for that
2392 image, and we have to undo that setup first before we can
2393 correct the overlay string index. */
2394 if (it->method == next_element_from_image)
2395 pop_it (it);
2396
2397 /* We already have the first chunk of overlay strings in
2398 IT->overlay_strings. Load more until the one for
2399 pos->overlay_string_index is in IT->overlay_strings. */
2400 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2401 {
2402 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2403 it->current.overlay_string_index = 0;
2404 while (n--)
2405 {
2406 load_overlay_strings (it, 0);
2407 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2408 }
2409 }
2410
2411 it->current.overlay_string_index = pos->overlay_string_index;
2412 relative_index = (it->current.overlay_string_index
2413 % OVERLAY_STRING_CHUNK_SIZE);
2414 it->string = it->overlay_strings[relative_index];
2415 xassert (STRINGP (it->string));
2416 it->current.string_pos = pos->string_pos;
2417 it->method = next_element_from_string;
2418 }
2419
2420 #if 0 /* This is bogus because POS not having an overlay string
2421 position does not mean it's after the string. Example: A
2422 line starting with a before-string and initialization of IT
2423 to the previous row's end position. */
2424 else if (it->current.overlay_string_index >= 0)
2425 {
2426 /* If POS says we're already after an overlay string ending at
2427 POS, make sure to pop the iterator because it will be in
2428 front of that overlay string. When POS is ZV, we've thereby
2429 also ``processed'' overlay strings at ZV. */
2430 while (it->sp)
2431 pop_it (it);
2432 it->current.overlay_string_index = -1;
2433 it->method = next_element_from_buffer;
2434 if (CHARPOS (pos->pos) == ZV)
2435 it->overlay_strings_at_end_processed_p = 1;
2436 }
2437 #endif /* 0 */
2438
2439 if (CHARPOS (pos->string_pos) >= 0)
2440 {
2441 /* Recorded position is not in an overlay string, but in another
2442 string. This can only be a string from a `display' property.
2443 IT should already be filled with that string. */
2444 it->current.string_pos = pos->string_pos;
2445 xassert (STRINGP (it->string));
2446 }
2447
2448 /* Restore position in display vector translations, control
2449 character translations or ellipses. */
2450 if (pos->dpvec_index >= 0)
2451 {
2452 if (it->dpvec == NULL)
2453 get_next_display_element (it);
2454 xassert (it->dpvec && it->current.dpvec_index == 0);
2455 it->current.dpvec_index = pos->dpvec_index;
2456 }
2457
2458 CHECK_IT (it);
2459 return !overlay_strings_with_newlines;
2460 }
2461
2462
2463 /* Initialize IT for stepping through current_buffer in window W
2464 starting at ROW->start. */
2465
2466 static void
2467 init_to_row_start (it, w, row)
2468 struct it *it;
2469 struct window *w;
2470 struct glyph_row *row;
2471 {
2472 init_from_display_pos (it, w, &row->start);
2473 it->start = row->start;
2474 it->continuation_lines_width = row->continuation_lines_width;
2475 CHECK_IT (it);
2476 }
2477
2478
2479 /* Initialize IT for stepping through current_buffer in window W
2480 starting in the line following ROW, i.e. starting at ROW->end.
2481 Value is zero if there are overlay strings with newlines at ROW's
2482 end position. */
2483
2484 static int
2485 init_to_row_end (it, w, row)
2486 struct it *it;
2487 struct window *w;
2488 struct glyph_row *row;
2489 {
2490 int success = 0;
2491
2492 if (init_from_display_pos (it, w, &row->end))
2493 {
2494 if (row->continued_p)
2495 it->continuation_lines_width
2496 = row->continuation_lines_width + row->pixel_width;
2497 CHECK_IT (it);
2498 success = 1;
2499 }
2500
2501 return success;
2502 }
2503
2504
2505
2506 \f
2507 /***********************************************************************
2508 Text properties
2509 ***********************************************************************/
2510
2511 /* Called when IT reaches IT->stop_charpos. Handle text property and
2512 overlay changes. Set IT->stop_charpos to the next position where
2513 to stop. */
2514
2515 static void
2516 handle_stop (it)
2517 struct it *it;
2518 {
2519 enum prop_handled handled;
2520 int handle_overlay_change_p = 1;
2521 struct props *p;
2522
2523 it->dpvec = NULL;
2524 it->current.dpvec_index = -1;
2525
2526 do
2527 {
2528 handled = HANDLED_NORMALLY;
2529
2530 /* Call text property handlers. */
2531 for (p = it_props; p->handler; ++p)
2532 {
2533 handled = p->handler (it);
2534
2535 if (handled == HANDLED_RECOMPUTE_PROPS)
2536 break;
2537 else if (handled == HANDLED_RETURN)
2538 return;
2539 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2540 handle_overlay_change_p = 0;
2541 }
2542
2543 if (handled != HANDLED_RECOMPUTE_PROPS)
2544 {
2545 /* Don't check for overlay strings below when set to deliver
2546 characters from a display vector. */
2547 if (it->method == next_element_from_display_vector)
2548 handle_overlay_change_p = 0;
2549
2550 /* Handle overlay changes. */
2551 if (handle_overlay_change_p)
2552 handled = handle_overlay_change (it);
2553
2554 /* Determine where to stop next. */
2555 if (handled == HANDLED_NORMALLY)
2556 compute_stop_pos (it);
2557 }
2558 }
2559 while (handled == HANDLED_RECOMPUTE_PROPS);
2560 }
2561
2562
2563 /* Compute IT->stop_charpos from text property and overlay change
2564 information for IT's current position. */
2565
2566 static void
2567 compute_stop_pos (it)
2568 struct it *it;
2569 {
2570 register INTERVAL iv, next_iv;
2571 Lisp_Object object, limit, position;
2572
2573 /* If nowhere else, stop at the end. */
2574 it->stop_charpos = it->end_charpos;
2575
2576 if (STRINGP (it->string))
2577 {
2578 /* Strings are usually short, so don't limit the search for
2579 properties. */
2580 object = it->string;
2581 limit = Qnil;
2582 position = make_number (IT_STRING_CHARPOS (*it));
2583 }
2584 else
2585 {
2586 int charpos;
2587
2588 /* If next overlay change is in front of the current stop pos
2589 (which is IT->end_charpos), stop there. Note: value of
2590 next_overlay_change is point-max if no overlay change
2591 follows. */
2592 charpos = next_overlay_change (IT_CHARPOS (*it));
2593 if (charpos < it->stop_charpos)
2594 it->stop_charpos = charpos;
2595
2596 /* If showing the region, we have to stop at the region
2597 start or end because the face might change there. */
2598 if (it->region_beg_charpos > 0)
2599 {
2600 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2601 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2602 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2603 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2604 }
2605
2606 /* Set up variables for computing the stop position from text
2607 property changes. */
2608 XSETBUFFER (object, current_buffer);
2609 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2610 position = make_number (IT_CHARPOS (*it));
2611
2612 }
2613
2614 /* Get the interval containing IT's position. Value is a null
2615 interval if there isn't such an interval. */
2616 iv = validate_interval_range (object, &position, &position, 0);
2617 if (!NULL_INTERVAL_P (iv))
2618 {
2619 Lisp_Object values_here[LAST_PROP_IDX];
2620 struct props *p;
2621
2622 /* Get properties here. */
2623 for (p = it_props; p->handler; ++p)
2624 values_here[p->idx] = textget (iv->plist, *p->name);
2625
2626 /* Look for an interval following iv that has different
2627 properties. */
2628 for (next_iv = next_interval (iv);
2629 (!NULL_INTERVAL_P (next_iv)
2630 && (NILP (limit)
2631 || XFASTINT (limit) > next_iv->position));
2632 next_iv = next_interval (next_iv))
2633 {
2634 for (p = it_props; p->handler; ++p)
2635 {
2636 Lisp_Object new_value;
2637
2638 new_value = textget (next_iv->plist, *p->name);
2639 if (!EQ (values_here[p->idx], new_value))
2640 break;
2641 }
2642
2643 if (p->handler)
2644 break;
2645 }
2646
2647 if (!NULL_INTERVAL_P (next_iv))
2648 {
2649 if (INTEGERP (limit)
2650 && next_iv->position >= XFASTINT (limit))
2651 /* No text property change up to limit. */
2652 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2653 else
2654 /* Text properties change in next_iv. */
2655 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2656 }
2657 }
2658
2659 xassert (STRINGP (it->string)
2660 || (it->stop_charpos >= BEGV
2661 && it->stop_charpos >= IT_CHARPOS (*it)));
2662 }
2663
2664
2665 /* Return the position of the next overlay change after POS in
2666 current_buffer. Value is point-max if no overlay change
2667 follows. This is like `next-overlay-change' but doesn't use
2668 xmalloc. */
2669
2670 static int
2671 next_overlay_change (pos)
2672 int pos;
2673 {
2674 int noverlays;
2675 int endpos;
2676 Lisp_Object *overlays;
2677 int len;
2678 int i;
2679
2680 /* Get all overlays at the given position. */
2681 len = 10;
2682 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2683 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2684 if (noverlays > len)
2685 {
2686 len = noverlays;
2687 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2688 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2689 }
2690
2691 /* If any of these overlays ends before endpos,
2692 use its ending point instead. */
2693 for (i = 0; i < noverlays; ++i)
2694 {
2695 Lisp_Object oend;
2696 int oendpos;
2697
2698 oend = OVERLAY_END (overlays[i]);
2699 oendpos = OVERLAY_POSITION (oend);
2700 endpos = min (endpos, oendpos);
2701 }
2702
2703 return endpos;
2704 }
2705
2706
2707 \f
2708 /***********************************************************************
2709 Fontification
2710 ***********************************************************************/
2711
2712 /* Handle changes in the `fontified' property of the current buffer by
2713 calling hook functions from Qfontification_functions to fontify
2714 regions of text. */
2715
2716 static enum prop_handled
2717 handle_fontified_prop (it)
2718 struct it *it;
2719 {
2720 Lisp_Object prop, pos;
2721 enum prop_handled handled = HANDLED_NORMALLY;
2722
2723 /* Get the value of the `fontified' property at IT's current buffer
2724 position. (The `fontified' property doesn't have a special
2725 meaning in strings.) If the value is nil, call functions from
2726 Qfontification_functions. */
2727 if (!STRINGP (it->string)
2728 && it->s == NULL
2729 && !NILP (Vfontification_functions)
2730 && !NILP (Vrun_hooks)
2731 && (pos = make_number (IT_CHARPOS (*it)),
2732 prop = Fget_char_property (pos, Qfontified, Qnil),
2733 NILP (prop)))
2734 {
2735 int count = SPECPDL_INDEX ();
2736 Lisp_Object val;
2737
2738 val = Vfontification_functions;
2739 specbind (Qfontification_functions, Qnil);
2740
2741 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2742 safe_call1 (val, pos);
2743 else
2744 {
2745 Lisp_Object globals, fn;
2746 struct gcpro gcpro1, gcpro2;
2747
2748 globals = Qnil;
2749 GCPRO2 (val, globals);
2750
2751 for (; CONSP (val); val = XCDR (val))
2752 {
2753 fn = XCAR (val);
2754
2755 if (EQ (fn, Qt))
2756 {
2757 /* A value of t indicates this hook has a local
2758 binding; it means to run the global binding too.
2759 In a global value, t should not occur. If it
2760 does, we must ignore it to avoid an endless
2761 loop. */
2762 for (globals = Fdefault_value (Qfontification_functions);
2763 CONSP (globals);
2764 globals = XCDR (globals))
2765 {
2766 fn = XCAR (globals);
2767 if (!EQ (fn, Qt))
2768 safe_call1 (fn, pos);
2769 }
2770 }
2771 else
2772 safe_call1 (fn, pos);
2773 }
2774
2775 UNGCPRO;
2776 }
2777
2778 unbind_to (count, Qnil);
2779
2780 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2781 something. This avoids an endless loop if they failed to
2782 fontify the text for which reason ever. */
2783 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2784 handled = HANDLED_RECOMPUTE_PROPS;
2785 }
2786
2787 return handled;
2788 }
2789
2790
2791 \f
2792 /***********************************************************************
2793 Faces
2794 ***********************************************************************/
2795
2796 /* Set up iterator IT from face properties at its current position.
2797 Called from handle_stop. */
2798
2799 static enum prop_handled
2800 handle_face_prop (it)
2801 struct it *it;
2802 {
2803 int new_face_id, next_stop;
2804
2805 if (!STRINGP (it->string))
2806 {
2807 new_face_id
2808 = face_at_buffer_position (it->w,
2809 IT_CHARPOS (*it),
2810 it->region_beg_charpos,
2811 it->region_end_charpos,
2812 &next_stop,
2813 (IT_CHARPOS (*it)
2814 + TEXT_PROP_DISTANCE_LIMIT),
2815 0);
2816
2817 /* Is this a start of a run of characters with box face?
2818 Caveat: this can be called for a freshly initialized
2819 iterator; face_id is -1 in this case. We know that the new
2820 face will not change until limit, i.e. if the new face has a
2821 box, all characters up to limit will have one. But, as
2822 usual, we don't know whether limit is really the end. */
2823 if (new_face_id != it->face_id)
2824 {
2825 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2826
2827 /* If new face has a box but old face has not, this is
2828 the start of a run of characters with box, i.e. it has
2829 a shadow on the left side. The value of face_id of the
2830 iterator will be -1 if this is the initial call that gets
2831 the face. In this case, we have to look in front of IT's
2832 position and see whether there is a face != new_face_id. */
2833 it->start_of_box_run_p
2834 = (new_face->box != FACE_NO_BOX
2835 && (it->face_id >= 0
2836 || IT_CHARPOS (*it) == BEG
2837 || new_face_id != face_before_it_pos (it)));
2838 it->face_box_p = new_face->box != FACE_NO_BOX;
2839 }
2840 }
2841 else
2842 {
2843 int base_face_id, bufpos;
2844
2845 if (it->current.overlay_string_index >= 0)
2846 bufpos = IT_CHARPOS (*it);
2847 else
2848 bufpos = 0;
2849
2850 /* For strings from a buffer, i.e. overlay strings or strings
2851 from a `display' property, use the face at IT's current
2852 buffer position as the base face to merge with, so that
2853 overlay strings appear in the same face as surrounding
2854 text, unless they specify their own faces. */
2855 base_face_id = underlying_face_id (it);
2856
2857 new_face_id = face_at_string_position (it->w,
2858 it->string,
2859 IT_STRING_CHARPOS (*it),
2860 bufpos,
2861 it->region_beg_charpos,
2862 it->region_end_charpos,
2863 &next_stop,
2864 base_face_id, 0);
2865
2866 #if 0 /* This shouldn't be neccessary. Let's check it. */
2867 /* If IT is used to display a mode line we would really like to
2868 use the mode line face instead of the frame's default face. */
2869 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2870 && new_face_id == DEFAULT_FACE_ID)
2871 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2872 #endif
2873
2874 /* Is this a start of a run of characters with box? Caveat:
2875 this can be called for a freshly allocated iterator; face_id
2876 is -1 is this case. We know that the new face will not
2877 change until the next check pos, i.e. if the new face has a
2878 box, all characters up to that position will have a
2879 box. But, as usual, we don't know whether that position
2880 is really the end. */
2881 if (new_face_id != it->face_id)
2882 {
2883 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2884 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2885
2886 /* If new face has a box but old face hasn't, this is the
2887 start of a run of characters with box, i.e. it has a
2888 shadow on the left side. */
2889 it->start_of_box_run_p
2890 = new_face->box && (old_face == NULL || !old_face->box);
2891 it->face_box_p = new_face->box != FACE_NO_BOX;
2892 }
2893 }
2894
2895 it->face_id = new_face_id;
2896 return HANDLED_NORMALLY;
2897 }
2898
2899
2900 /* Return the ID of the face ``underlying'' IT's current position,
2901 which is in a string. If the iterator is associated with a
2902 buffer, return the face at IT's current buffer position.
2903 Otherwise, use the iterator's base_face_id. */
2904
2905 static int
2906 underlying_face_id (it)
2907 struct it *it;
2908 {
2909 int face_id = it->base_face_id, i;
2910
2911 xassert (STRINGP (it->string));
2912
2913 for (i = it->sp - 1; i >= 0; --i)
2914 if (NILP (it->stack[i].string))
2915 face_id = it->stack[i].face_id;
2916
2917 return face_id;
2918 }
2919
2920
2921 /* Compute the face one character before or after the current position
2922 of IT. BEFORE_P non-zero means get the face in front of IT's
2923 position. Value is the id of the face. */
2924
2925 static int
2926 face_before_or_after_it_pos (it, before_p)
2927 struct it *it;
2928 int before_p;
2929 {
2930 int face_id, limit;
2931 int next_check_charpos;
2932 struct text_pos pos;
2933
2934 xassert (it->s == NULL);
2935
2936 if (STRINGP (it->string))
2937 {
2938 int bufpos, base_face_id;
2939
2940 /* No face change past the end of the string (for the case
2941 we are padding with spaces). No face change before the
2942 string start. */
2943 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2944 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2945 return it->face_id;
2946
2947 /* Set pos to the position before or after IT's current position. */
2948 if (before_p)
2949 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2950 else
2951 /* For composition, we must check the character after the
2952 composition. */
2953 pos = (it->what == IT_COMPOSITION
2954 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2955 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2956
2957 if (it->current.overlay_string_index >= 0)
2958 bufpos = IT_CHARPOS (*it);
2959 else
2960 bufpos = 0;
2961
2962 base_face_id = underlying_face_id (it);
2963
2964 /* Get the face for ASCII, or unibyte. */
2965 face_id = face_at_string_position (it->w,
2966 it->string,
2967 CHARPOS (pos),
2968 bufpos,
2969 it->region_beg_charpos,
2970 it->region_end_charpos,
2971 &next_check_charpos,
2972 base_face_id, 0);
2973
2974 /* Correct the face for charsets different from ASCII. Do it
2975 for the multibyte case only. The face returned above is
2976 suitable for unibyte text if IT->string is unibyte. */
2977 if (STRING_MULTIBYTE (it->string))
2978 {
2979 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
2980 int rest = SBYTES (it->string) - BYTEPOS (pos);
2981 int c, len;
2982 struct face *face = FACE_FROM_ID (it->f, face_id);
2983
2984 c = string_char_and_length (p, rest, &len);
2985 face_id = FACE_FOR_CHAR (it->f, face, c);
2986 }
2987 }
2988 else
2989 {
2990 if ((IT_CHARPOS (*it) >= ZV && !before_p)
2991 || (IT_CHARPOS (*it) <= BEGV && before_p))
2992 return it->face_id;
2993
2994 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
2995 pos = it->current.pos;
2996
2997 if (before_p)
2998 DEC_TEXT_POS (pos, it->multibyte_p);
2999 else
3000 {
3001 if (it->what == IT_COMPOSITION)
3002 /* For composition, we must check the position after the
3003 composition. */
3004 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3005 else
3006 INC_TEXT_POS (pos, it->multibyte_p);
3007 }
3008
3009 /* Determine face for CHARSET_ASCII, or unibyte. */
3010 face_id = face_at_buffer_position (it->w,
3011 CHARPOS (pos),
3012 it->region_beg_charpos,
3013 it->region_end_charpos,
3014 &next_check_charpos,
3015 limit, 0);
3016
3017 /* Correct the face for charsets different from ASCII. Do it
3018 for the multibyte case only. The face returned above is
3019 suitable for unibyte text if current_buffer is unibyte. */
3020 if (it->multibyte_p)
3021 {
3022 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3023 struct face *face = FACE_FROM_ID (it->f, face_id);
3024 face_id = FACE_FOR_CHAR (it->f, face, c);
3025 }
3026 }
3027
3028 return face_id;
3029 }
3030
3031
3032 \f
3033 /***********************************************************************
3034 Invisible text
3035 ***********************************************************************/
3036
3037 /* Set up iterator IT from invisible properties at its current
3038 position. Called from handle_stop. */
3039
3040 static enum prop_handled
3041 handle_invisible_prop (it)
3042 struct it *it;
3043 {
3044 enum prop_handled handled = HANDLED_NORMALLY;
3045
3046 if (STRINGP (it->string))
3047 {
3048 extern Lisp_Object Qinvisible;
3049 Lisp_Object prop, end_charpos, limit, charpos;
3050
3051 /* Get the value of the invisible text property at the
3052 current position. Value will be nil if there is no such
3053 property. */
3054 charpos = make_number (IT_STRING_CHARPOS (*it));
3055 prop = Fget_text_property (charpos, Qinvisible, it->string);
3056
3057 if (!NILP (prop)
3058 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3059 {
3060 handled = HANDLED_RECOMPUTE_PROPS;
3061
3062 /* Get the position at which the next change of the
3063 invisible text property can be found in IT->string.
3064 Value will be nil if the property value is the same for
3065 all the rest of IT->string. */
3066 XSETINT (limit, SCHARS (it->string));
3067 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3068 it->string, limit);
3069
3070 /* Text at current position is invisible. The next
3071 change in the property is at position end_charpos.
3072 Move IT's current position to that position. */
3073 if (INTEGERP (end_charpos)
3074 && XFASTINT (end_charpos) < XFASTINT (limit))
3075 {
3076 struct text_pos old;
3077 old = it->current.string_pos;
3078 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3079 compute_string_pos (&it->current.string_pos, old, it->string);
3080 }
3081 else
3082 {
3083 /* The rest of the string is invisible. If this is an
3084 overlay string, proceed with the next overlay string
3085 or whatever comes and return a character from there. */
3086 if (it->current.overlay_string_index >= 0)
3087 {
3088 next_overlay_string (it);
3089 /* Don't check for overlay strings when we just
3090 finished processing them. */
3091 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3092 }
3093 else
3094 {
3095 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3096 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3097 }
3098 }
3099 }
3100 }
3101 else
3102 {
3103 int invis_p, newpos, next_stop, start_charpos;
3104 Lisp_Object pos, prop, overlay;
3105
3106 /* First of all, is there invisible text at this position? */
3107 start_charpos = IT_CHARPOS (*it);
3108 pos = make_number (IT_CHARPOS (*it));
3109 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3110 &overlay);
3111 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3112
3113 /* If we are on invisible text, skip over it. */
3114 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3115 {
3116 /* Record whether we have to display an ellipsis for the
3117 invisible text. */
3118 int display_ellipsis_p = invis_p == 2;
3119
3120 handled = HANDLED_RECOMPUTE_PROPS;
3121
3122 /* Loop skipping over invisible text. The loop is left at
3123 ZV or with IT on the first char being visible again. */
3124 do
3125 {
3126 /* Try to skip some invisible text. Return value is the
3127 position reached which can be equal to IT's position
3128 if there is nothing invisible here. This skips both
3129 over invisible text properties and overlays with
3130 invisible property. */
3131 newpos = skip_invisible (IT_CHARPOS (*it),
3132 &next_stop, ZV, it->window);
3133
3134 /* If we skipped nothing at all we weren't at invisible
3135 text in the first place. If everything to the end of
3136 the buffer was skipped, end the loop. */
3137 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3138 invis_p = 0;
3139 else
3140 {
3141 /* We skipped some characters but not necessarily
3142 all there are. Check if we ended up on visible
3143 text. Fget_char_property returns the property of
3144 the char before the given position, i.e. if we
3145 get invis_p = 0, this means that the char at
3146 newpos is visible. */
3147 pos = make_number (newpos);
3148 prop = Fget_char_property (pos, Qinvisible, it->window);
3149 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3150 }
3151
3152 /* If we ended up on invisible text, proceed to
3153 skip starting with next_stop. */
3154 if (invis_p)
3155 IT_CHARPOS (*it) = next_stop;
3156 }
3157 while (invis_p);
3158
3159 /* The position newpos is now either ZV or on visible text. */
3160 IT_CHARPOS (*it) = newpos;
3161 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3162
3163 /* If there are before-strings at the start of invisible
3164 text, and the text is invisible because of a text
3165 property, arrange to show before-strings because 20.x did
3166 it that way. (If the text is invisible because of an
3167 overlay property instead of a text property, this is
3168 already handled in the overlay code.) */
3169 if (NILP (overlay)
3170 && get_overlay_strings (it, start_charpos))
3171 {
3172 handled = HANDLED_RECOMPUTE_PROPS;
3173 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3174 }
3175 else if (display_ellipsis_p)
3176 setup_for_ellipsis (it);
3177 }
3178 }
3179
3180 return handled;
3181 }
3182
3183
3184 /* Make iterator IT return `...' next. */
3185
3186 static void
3187 setup_for_ellipsis (it)
3188 struct it *it;
3189 {
3190 if (it->dp
3191 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3192 {
3193 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3194 it->dpvec = v->contents;
3195 it->dpend = v->contents + v->size;
3196 }
3197 else
3198 {
3199 /* Default `...'. */
3200 it->dpvec = default_invis_vector;
3201 it->dpend = default_invis_vector + 3;
3202 }
3203
3204 /* The ellipsis display does not replace the display of the
3205 character at the new position. Indicate this by setting
3206 IT->dpvec_char_len to zero. */
3207 it->dpvec_char_len = 0;
3208
3209 it->current.dpvec_index = 0;
3210 it->method = next_element_from_display_vector;
3211 }
3212
3213
3214 \f
3215 /***********************************************************************
3216 'display' property
3217 ***********************************************************************/
3218
3219 /* Set up iterator IT from `display' property at its current position.
3220 Called from handle_stop. */
3221
3222 static enum prop_handled
3223 handle_display_prop (it)
3224 struct it *it;
3225 {
3226 Lisp_Object prop, object;
3227 struct text_pos *position;
3228 int display_replaced_p = 0;
3229
3230 if (STRINGP (it->string))
3231 {
3232 object = it->string;
3233 position = &it->current.string_pos;
3234 }
3235 else
3236 {
3237 object = it->w->buffer;
3238 position = &it->current.pos;
3239 }
3240
3241 /* Reset those iterator values set from display property values. */
3242 it->font_height = Qnil;
3243 it->space_width = Qnil;
3244 it->voffset = 0;
3245
3246 /* We don't support recursive `display' properties, i.e. string
3247 values that have a string `display' property, that have a string
3248 `display' property etc. */
3249 if (!it->string_from_display_prop_p)
3250 it->area = TEXT_AREA;
3251
3252 prop = Fget_char_property (make_number (position->charpos),
3253 Qdisplay, object);
3254 if (NILP (prop))
3255 return HANDLED_NORMALLY;
3256
3257 if (CONSP (prop)
3258 /* Simple properties. */
3259 && !EQ (XCAR (prop), Qimage)
3260 && !EQ (XCAR (prop), Qspace)
3261 && !EQ (XCAR (prop), Qwhen)
3262 && !EQ (XCAR (prop), Qspace_width)
3263 && !EQ (XCAR (prop), Qheight)
3264 && !EQ (XCAR (prop), Qraise)
3265 /* Marginal area specifications. */
3266 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3267 && !NILP (XCAR (prop)))
3268 {
3269 for (; CONSP (prop); prop = XCDR (prop))
3270 {
3271 if (handle_single_display_prop (it, XCAR (prop), object,
3272 position, display_replaced_p))
3273 display_replaced_p = 1;
3274 }
3275 }
3276 else if (VECTORP (prop))
3277 {
3278 int i;
3279 for (i = 0; i < ASIZE (prop); ++i)
3280 if (handle_single_display_prop (it, AREF (prop, i), object,
3281 position, display_replaced_p))
3282 display_replaced_p = 1;
3283 }
3284 else
3285 {
3286 if (handle_single_display_prop (it, prop, object, position, 0))
3287 display_replaced_p = 1;
3288 }
3289
3290 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3291 }
3292
3293
3294 /* Value is the position of the end of the `display' property starting
3295 at START_POS in OBJECT. */
3296
3297 static struct text_pos
3298 display_prop_end (it, object, start_pos)
3299 struct it *it;
3300 Lisp_Object object;
3301 struct text_pos start_pos;
3302 {
3303 Lisp_Object end;
3304 struct text_pos end_pos;
3305
3306 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3307 Qdisplay, object, Qnil);
3308 CHARPOS (end_pos) = XFASTINT (end);
3309 if (STRINGP (object))
3310 compute_string_pos (&end_pos, start_pos, it->string);
3311 else
3312 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3313
3314 return end_pos;
3315 }
3316
3317
3318 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3319 is the object in which the `display' property was found. *POSITION
3320 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3321 means that we previously saw a display sub-property which already
3322 replaced text display with something else, for example an image;
3323 ignore such properties after the first one has been processed.
3324
3325 If PROP is a `space' or `image' sub-property, set *POSITION to the
3326 end position of the `display' property.
3327
3328 Value is non-zero if something was found which replaces the display
3329 of buffer or string text. */
3330
3331 static int
3332 handle_single_display_prop (it, prop, object, position,
3333 display_replaced_before_p)
3334 struct it *it;
3335 Lisp_Object prop;
3336 Lisp_Object object;
3337 struct text_pos *position;
3338 int display_replaced_before_p;
3339 {
3340 Lisp_Object value;
3341 int replaces_text_display_p = 0;
3342 Lisp_Object form;
3343
3344 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3345 evaluated. If the result is nil, VALUE is ignored. */
3346 form = Qt;
3347 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3348 {
3349 prop = XCDR (prop);
3350 if (!CONSP (prop))
3351 return 0;
3352 form = XCAR (prop);
3353 prop = XCDR (prop);
3354 }
3355
3356 if (!NILP (form) && !EQ (form, Qt))
3357 {
3358 int count = SPECPDL_INDEX ();
3359 struct gcpro gcpro1;
3360
3361 /* Bind `object' to the object having the `display' property, a
3362 buffer or string. Bind `position' to the position in the
3363 object where the property was found, and `buffer-position'
3364 to the current position in the buffer. */
3365 specbind (Qobject, object);
3366 specbind (Qposition, make_number (CHARPOS (*position)));
3367 specbind (Qbuffer_position,
3368 make_number (STRINGP (object)
3369 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3370 GCPRO1 (form);
3371 form = safe_eval (form);
3372 UNGCPRO;
3373 unbind_to (count, Qnil);
3374 }
3375
3376 if (NILP (form))
3377 return 0;
3378
3379 if (CONSP (prop)
3380 && EQ (XCAR (prop), Qheight)
3381 && CONSP (XCDR (prop)))
3382 {
3383 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3384 return 0;
3385
3386 /* `(height HEIGHT)'. */
3387 it->font_height = XCAR (XCDR (prop));
3388 if (!NILP (it->font_height))
3389 {
3390 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3391 int new_height = -1;
3392
3393 if (CONSP (it->font_height)
3394 && (EQ (XCAR (it->font_height), Qplus)
3395 || EQ (XCAR (it->font_height), Qminus))
3396 && CONSP (XCDR (it->font_height))
3397 && INTEGERP (XCAR (XCDR (it->font_height))))
3398 {
3399 /* `(+ N)' or `(- N)' where N is an integer. */
3400 int steps = XINT (XCAR (XCDR (it->font_height)));
3401 if (EQ (XCAR (it->font_height), Qplus))
3402 steps = - steps;
3403 it->face_id = smaller_face (it->f, it->face_id, steps);
3404 }
3405 else if (FUNCTIONP (it->font_height))
3406 {
3407 /* Call function with current height as argument.
3408 Value is the new height. */
3409 Lisp_Object height;
3410 height = safe_call1 (it->font_height,
3411 face->lface[LFACE_HEIGHT_INDEX]);
3412 if (NUMBERP (height))
3413 new_height = XFLOATINT (height);
3414 }
3415 else if (NUMBERP (it->font_height))
3416 {
3417 /* Value is a multiple of the canonical char height. */
3418 struct face *face;
3419
3420 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3421 new_height = (XFLOATINT (it->font_height)
3422 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3423 }
3424 else
3425 {
3426 /* Evaluate IT->font_height with `height' bound to the
3427 current specified height to get the new height. */
3428 Lisp_Object value;
3429 int count = SPECPDL_INDEX ();
3430
3431 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3432 value = safe_eval (it->font_height);
3433 unbind_to (count, Qnil);
3434
3435 if (NUMBERP (value))
3436 new_height = XFLOATINT (value);
3437 }
3438
3439 if (new_height > 0)
3440 it->face_id = face_with_height (it->f, it->face_id, new_height);
3441 }
3442 }
3443 else if (CONSP (prop)
3444 && EQ (XCAR (prop), Qspace_width)
3445 && CONSP (XCDR (prop)))
3446 {
3447 /* `(space_width WIDTH)'. */
3448 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3449 return 0;
3450
3451 value = XCAR (XCDR (prop));
3452 if (NUMBERP (value) && XFLOATINT (value) > 0)
3453 it->space_width = value;
3454 }
3455 else if (CONSP (prop)
3456 && EQ (XCAR (prop), Qraise)
3457 && CONSP (XCDR (prop)))
3458 {
3459 /* `(raise FACTOR)'. */
3460 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3461 return 0;
3462
3463 #ifdef HAVE_WINDOW_SYSTEM
3464 value = XCAR (XCDR (prop));
3465 if (NUMBERP (value))
3466 {
3467 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3468 it->voffset = - (XFLOATINT (value)
3469 * (FONT_HEIGHT (face->font)));
3470 }
3471 #endif /* HAVE_WINDOW_SYSTEM */
3472 }
3473 else if (!it->string_from_display_prop_p)
3474 {
3475 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3476 VALUE) or `((margin nil) VALUE)' or VALUE. */
3477 Lisp_Object location, value;
3478 struct text_pos start_pos;
3479 int valid_p;
3480
3481 /* Characters having this form of property are not displayed, so
3482 we have to find the end of the property. */
3483 start_pos = *position;
3484 *position = display_prop_end (it, object, start_pos);
3485 value = Qnil;
3486
3487 /* Let's stop at the new position and assume that all
3488 text properties change there. */
3489 it->stop_charpos = position->charpos;
3490
3491 location = Qunbound;
3492 if (CONSP (prop) && CONSP (XCAR (prop)))
3493 {
3494 Lisp_Object tem;
3495
3496 value = XCDR (prop);
3497 if (CONSP (value))
3498 value = XCAR (value);
3499
3500 tem = XCAR (prop);
3501 if (EQ (XCAR (tem), Qmargin)
3502 && (tem = XCDR (tem),
3503 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3504 (NILP (tem)
3505 || EQ (tem, Qleft_margin)
3506 || EQ (tem, Qright_margin))))
3507 location = tem;
3508 }
3509
3510 if (EQ (location, Qunbound))
3511 {
3512 location = Qnil;
3513 value = prop;
3514 }
3515
3516 #ifdef HAVE_WINDOW_SYSTEM
3517 if (FRAME_TERMCAP_P (it->f))
3518 valid_p = STRINGP (value);
3519 else
3520 valid_p = (STRINGP (value)
3521 || (CONSP (value) && EQ (XCAR (value), Qspace))
3522 || valid_image_p (value));
3523 #else /* not HAVE_WINDOW_SYSTEM */
3524 valid_p = STRINGP (value);
3525 #endif /* not HAVE_WINDOW_SYSTEM */
3526
3527 if ((EQ (location, Qleft_margin)
3528 || EQ (location, Qright_margin)
3529 || NILP (location))
3530 && valid_p
3531 && !display_replaced_before_p)
3532 {
3533 replaces_text_display_p = 1;
3534
3535 /* Save current settings of IT so that we can restore them
3536 when we are finished with the glyph property value. */
3537 push_it (it);
3538
3539 if (NILP (location))
3540 it->area = TEXT_AREA;
3541 else if (EQ (location, Qleft_margin))
3542 it->area = LEFT_MARGIN_AREA;
3543 else
3544 it->area = RIGHT_MARGIN_AREA;
3545
3546 if (STRINGP (value))
3547 {
3548 it->string = value;
3549 it->multibyte_p = STRING_MULTIBYTE (it->string);
3550 it->current.overlay_string_index = -1;
3551 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3552 it->end_charpos = it->string_nchars = SCHARS (it->string);
3553 it->method = next_element_from_string;
3554 it->stop_charpos = 0;
3555 it->string_from_display_prop_p = 1;
3556 /* Say that we haven't consumed the characters with
3557 `display' property yet. The call to pop_it in
3558 set_iterator_to_next will clean this up. */
3559 *position = start_pos;
3560 }
3561 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3562 {
3563 it->method = next_element_from_stretch;
3564 it->object = value;
3565 it->current.pos = it->position = start_pos;
3566 }
3567 #ifdef HAVE_WINDOW_SYSTEM
3568 else
3569 {
3570 it->what = IT_IMAGE;
3571 it->image_id = lookup_image (it->f, value);
3572 it->position = start_pos;
3573 it->object = NILP (object) ? it->w->buffer : object;
3574 it->method = next_element_from_image;
3575
3576 /* Say that we haven't consumed the characters with
3577 `display' property yet. The call to pop_it in
3578 set_iterator_to_next will clean this up. */
3579 *position = start_pos;
3580 }
3581 #endif /* HAVE_WINDOW_SYSTEM */
3582 }
3583 else
3584 /* Invalid property or property not supported. Restore
3585 the position to what it was before. */
3586 *position = start_pos;
3587 }
3588
3589 return replaces_text_display_p;
3590 }
3591
3592
3593 /* Check if PROP is a display sub-property value whose text should be
3594 treated as intangible. */
3595
3596 static int
3597 single_display_prop_intangible_p (prop)
3598 Lisp_Object prop;
3599 {
3600 /* Skip over `when FORM'. */
3601 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3602 {
3603 prop = XCDR (prop);
3604 if (!CONSP (prop))
3605 return 0;
3606 prop = XCDR (prop);
3607 }
3608
3609 if (STRINGP (prop))
3610 return 1;
3611
3612 if (!CONSP (prop))
3613 return 0;
3614
3615 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3616 we don't need to treat text as intangible. */
3617 if (EQ (XCAR (prop), Qmargin))
3618 {
3619 prop = XCDR (prop);
3620 if (!CONSP (prop))
3621 return 0;
3622
3623 prop = XCDR (prop);
3624 if (!CONSP (prop)
3625 || EQ (XCAR (prop), Qleft_margin)
3626 || EQ (XCAR (prop), Qright_margin))
3627 return 0;
3628 }
3629
3630 return (CONSP (prop)
3631 && (EQ (XCAR (prop), Qimage)
3632 || EQ (XCAR (prop), Qspace)));
3633 }
3634
3635
3636 /* Check if PROP is a display property value whose text should be
3637 treated as intangible. */
3638
3639 int
3640 display_prop_intangible_p (prop)
3641 Lisp_Object prop;
3642 {
3643 if (CONSP (prop)
3644 && CONSP (XCAR (prop))
3645 && !EQ (Qmargin, XCAR (XCAR (prop))))
3646 {
3647 /* A list of sub-properties. */
3648 while (CONSP (prop))
3649 {
3650 if (single_display_prop_intangible_p (XCAR (prop)))
3651 return 1;
3652 prop = XCDR (prop);
3653 }
3654 }
3655 else if (VECTORP (prop))
3656 {
3657 /* A vector of sub-properties. */
3658 int i;
3659 for (i = 0; i < ASIZE (prop); ++i)
3660 if (single_display_prop_intangible_p (AREF (prop, i)))
3661 return 1;
3662 }
3663 else
3664 return single_display_prop_intangible_p (prop);
3665
3666 return 0;
3667 }
3668
3669
3670 /* Return 1 if PROP is a display sub-property value containing STRING. */
3671
3672 static int
3673 single_display_prop_string_p (prop, string)
3674 Lisp_Object prop, string;
3675 {
3676 if (EQ (string, prop))
3677 return 1;
3678
3679 /* Skip over `when FORM'. */
3680 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3681 {
3682 prop = XCDR (prop);
3683 if (!CONSP (prop))
3684 return 0;
3685 prop = XCDR (prop);
3686 }
3687
3688 if (CONSP (prop))
3689 /* Skip over `margin LOCATION'. */
3690 if (EQ (XCAR (prop), Qmargin))
3691 {
3692 prop = XCDR (prop);
3693 if (!CONSP (prop))
3694 return 0;
3695
3696 prop = XCDR (prop);
3697 if (!CONSP (prop))
3698 return 0;
3699 }
3700
3701 return CONSP (prop) && EQ (XCAR (prop), string);
3702 }
3703
3704
3705 /* Return 1 if STRING appears in the `display' property PROP. */
3706
3707 static int
3708 display_prop_string_p (prop, string)
3709 Lisp_Object prop, string;
3710 {
3711 if (CONSP (prop)
3712 && CONSP (XCAR (prop))
3713 && !EQ (Qmargin, XCAR (XCAR (prop))))
3714 {
3715 /* A list of sub-properties. */
3716 while (CONSP (prop))
3717 {
3718 if (single_display_prop_string_p (XCAR (prop), string))
3719 return 1;
3720 prop = XCDR (prop);
3721 }
3722 }
3723 else if (VECTORP (prop))
3724 {
3725 /* A vector of sub-properties. */
3726 int i;
3727 for (i = 0; i < ASIZE (prop); ++i)
3728 if (single_display_prop_string_p (AREF (prop, i), string))
3729 return 1;
3730 }
3731 else
3732 return single_display_prop_string_p (prop, string);
3733
3734 return 0;
3735 }
3736
3737
3738 /* Determine from which buffer position in W's buffer STRING comes
3739 from. AROUND_CHARPOS is an approximate position where it could
3740 be from. Value is the buffer position or 0 if it couldn't be
3741 determined.
3742
3743 W's buffer must be current.
3744
3745 This function is necessary because we don't record buffer positions
3746 in glyphs generated from strings (to keep struct glyph small).
3747 This function may only use code that doesn't eval because it is
3748 called asynchronously from note_mouse_highlight. */
3749
3750 int
3751 string_buffer_position (w, string, around_charpos)
3752 struct window *w;
3753 Lisp_Object string;
3754 int around_charpos;
3755 {
3756 Lisp_Object limit, prop, pos;
3757 const int MAX_DISTANCE = 1000;
3758 int found = 0;
3759
3760 pos = make_number (around_charpos);
3761 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3762 while (!found && !EQ (pos, limit))
3763 {
3764 prop = Fget_char_property (pos, Qdisplay, Qnil);
3765 if (!NILP (prop) && display_prop_string_p (prop, string))
3766 found = 1;
3767 else
3768 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3769 }
3770
3771 if (!found)
3772 {
3773 pos = make_number (around_charpos);
3774 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3775 while (!found && !EQ (pos, limit))
3776 {
3777 prop = Fget_char_property (pos, Qdisplay, Qnil);
3778 if (!NILP (prop) && display_prop_string_p (prop, string))
3779 found = 1;
3780 else
3781 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3782 limit);
3783 }
3784 }
3785
3786 return found ? XINT (pos) : 0;
3787 }
3788
3789
3790 \f
3791 /***********************************************************************
3792 `composition' property
3793 ***********************************************************************/
3794
3795 /* Set up iterator IT from `composition' property at its current
3796 position. Called from handle_stop. */
3797
3798 static enum prop_handled
3799 handle_composition_prop (it)
3800 struct it *it;
3801 {
3802 Lisp_Object prop, string;
3803 int pos, pos_byte, end;
3804 enum prop_handled handled = HANDLED_NORMALLY;
3805
3806 if (STRINGP (it->string))
3807 {
3808 pos = IT_STRING_CHARPOS (*it);
3809 pos_byte = IT_STRING_BYTEPOS (*it);
3810 string = it->string;
3811 }
3812 else
3813 {
3814 pos = IT_CHARPOS (*it);
3815 pos_byte = IT_BYTEPOS (*it);
3816 string = Qnil;
3817 }
3818
3819 /* If there's a valid composition and point is not inside of the
3820 composition (in the case that the composition is from the current
3821 buffer), draw a glyph composed from the composition components. */
3822 if (find_composition (pos, -1, &pos, &end, &prop, string)
3823 && COMPOSITION_VALID_P (pos, end, prop)
3824 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3825 {
3826 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3827
3828 if (id >= 0)
3829 {
3830 it->method = next_element_from_composition;
3831 it->cmp_id = id;
3832 it->cmp_len = COMPOSITION_LENGTH (prop);
3833 /* For a terminal, draw only the first character of the
3834 components. */
3835 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3836 it->len = (STRINGP (it->string)
3837 ? string_char_to_byte (it->string, end)
3838 : CHAR_TO_BYTE (end)) - pos_byte;
3839 it->stop_charpos = end;
3840 handled = HANDLED_RETURN;
3841 }
3842 }
3843
3844 return handled;
3845 }
3846
3847
3848 \f
3849 /***********************************************************************
3850 Overlay strings
3851 ***********************************************************************/
3852
3853 /* The following structure is used to record overlay strings for
3854 later sorting in load_overlay_strings. */
3855
3856 struct overlay_entry
3857 {
3858 Lisp_Object overlay;
3859 Lisp_Object string;
3860 int priority;
3861 int after_string_p;
3862 };
3863
3864
3865 /* Set up iterator IT from overlay strings at its current position.
3866 Called from handle_stop. */
3867
3868 static enum prop_handled
3869 handle_overlay_change (it)
3870 struct it *it;
3871 {
3872 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
3873 return HANDLED_RECOMPUTE_PROPS;
3874 else
3875 return HANDLED_NORMALLY;
3876 }
3877
3878
3879 /* Set up the next overlay string for delivery by IT, if there is an
3880 overlay string to deliver. Called by set_iterator_to_next when the
3881 end of the current overlay string is reached. If there are more
3882 overlay strings to display, IT->string and
3883 IT->current.overlay_string_index are set appropriately here.
3884 Otherwise IT->string is set to nil. */
3885
3886 static void
3887 next_overlay_string (it)
3888 struct it *it;
3889 {
3890 ++it->current.overlay_string_index;
3891 if (it->current.overlay_string_index == it->n_overlay_strings)
3892 {
3893 /* No more overlay strings. Restore IT's settings to what
3894 they were before overlay strings were processed, and
3895 continue to deliver from current_buffer. */
3896 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
3897
3898 pop_it (it);
3899 xassert (it->stop_charpos >= BEGV
3900 && it->stop_charpos <= it->end_charpos);
3901 it->string = Qnil;
3902 it->current.overlay_string_index = -1;
3903 SET_TEXT_POS (it->current.string_pos, -1, -1);
3904 it->n_overlay_strings = 0;
3905 it->method = next_element_from_buffer;
3906
3907 /* If we're at the end of the buffer, record that we have
3908 processed the overlay strings there already, so that
3909 next_element_from_buffer doesn't try it again. */
3910 if (IT_CHARPOS (*it) >= it->end_charpos)
3911 it->overlay_strings_at_end_processed_p = 1;
3912
3913 /* If we have to display `...' for invisible text, set
3914 the iterator up for that. */
3915 if (display_ellipsis_p)
3916 setup_for_ellipsis (it);
3917 }
3918 else
3919 {
3920 /* There are more overlay strings to process. If
3921 IT->current.overlay_string_index has advanced to a position
3922 where we must load IT->overlay_strings with more strings, do
3923 it. */
3924 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
3925
3926 if (it->current.overlay_string_index && i == 0)
3927 load_overlay_strings (it, 0);
3928
3929 /* Initialize IT to deliver display elements from the overlay
3930 string. */
3931 it->string = it->overlay_strings[i];
3932 it->multibyte_p = STRING_MULTIBYTE (it->string);
3933 SET_TEXT_POS (it->current.string_pos, 0, 0);
3934 it->method = next_element_from_string;
3935 it->stop_charpos = 0;
3936 }
3937
3938 CHECK_IT (it);
3939 }
3940
3941
3942 /* Compare two overlay_entry structures E1 and E2. Used as a
3943 comparison function for qsort in load_overlay_strings. Overlay
3944 strings for the same position are sorted so that
3945
3946 1. All after-strings come in front of before-strings, except
3947 when they come from the same overlay.
3948
3949 2. Within after-strings, strings are sorted so that overlay strings
3950 from overlays with higher priorities come first.
3951
3952 2. Within before-strings, strings are sorted so that overlay
3953 strings from overlays with higher priorities come last.
3954
3955 Value is analogous to strcmp. */
3956
3957
3958 static int
3959 compare_overlay_entries (e1, e2)
3960 void *e1, *e2;
3961 {
3962 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
3963 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
3964 int result;
3965
3966 if (entry1->after_string_p != entry2->after_string_p)
3967 {
3968 /* Let after-strings appear in front of before-strings if
3969 they come from different overlays. */
3970 if (EQ (entry1->overlay, entry2->overlay))
3971 result = entry1->after_string_p ? 1 : -1;
3972 else
3973 result = entry1->after_string_p ? -1 : 1;
3974 }
3975 else if (entry1->after_string_p)
3976 /* After-strings sorted in order of decreasing priority. */
3977 result = entry2->priority - entry1->priority;
3978 else
3979 /* Before-strings sorted in order of increasing priority. */
3980 result = entry1->priority - entry2->priority;
3981
3982 return result;
3983 }
3984
3985
3986 /* Load the vector IT->overlay_strings with overlay strings from IT's
3987 current buffer position, or from CHARPOS if that is > 0. Set
3988 IT->n_overlays to the total number of overlay strings found.
3989
3990 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
3991 a time. On entry into load_overlay_strings,
3992 IT->current.overlay_string_index gives the number of overlay
3993 strings that have already been loaded by previous calls to this
3994 function.
3995
3996 IT->add_overlay_start contains an additional overlay start
3997 position to consider for taking overlay strings from, if non-zero.
3998 This position comes into play when the overlay has an `invisible'
3999 property, and both before and after-strings. When we've skipped to
4000 the end of the overlay, because of its `invisible' property, we
4001 nevertheless want its before-string to appear.
4002 IT->add_overlay_start will contain the overlay start position
4003 in this case.
4004
4005 Overlay strings are sorted so that after-string strings come in
4006 front of before-string strings. Within before and after-strings,
4007 strings are sorted by overlay priority. See also function
4008 compare_overlay_entries. */
4009
4010 static void
4011 load_overlay_strings (it, charpos)
4012 struct it *it;
4013 int charpos;
4014 {
4015 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4016 Lisp_Object overlay, window, str, invisible;
4017 struct Lisp_Overlay *ov;
4018 int start, end;
4019 int size = 20;
4020 int n = 0, i, j, invis_p;
4021 struct overlay_entry *entries
4022 = (struct overlay_entry *) alloca (size * sizeof *entries);
4023
4024 if (charpos <= 0)
4025 charpos = IT_CHARPOS (*it);
4026
4027 /* Append the overlay string STRING of overlay OVERLAY to vector
4028 `entries' which has size `size' and currently contains `n'
4029 elements. AFTER_P non-zero means STRING is an after-string of
4030 OVERLAY. */
4031 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4032 do \
4033 { \
4034 Lisp_Object priority; \
4035 \
4036 if (n == size) \
4037 { \
4038 int new_size = 2 * size; \
4039 struct overlay_entry *old = entries; \
4040 entries = \
4041 (struct overlay_entry *) alloca (new_size \
4042 * sizeof *entries); \
4043 bcopy (old, entries, size * sizeof *entries); \
4044 size = new_size; \
4045 } \
4046 \
4047 entries[n].string = (STRING); \
4048 entries[n].overlay = (OVERLAY); \
4049 priority = Foverlay_get ((OVERLAY), Qpriority); \
4050 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4051 entries[n].after_string_p = (AFTER_P); \
4052 ++n; \
4053 } \
4054 while (0)
4055
4056 /* Process overlay before the overlay center. */
4057 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4058 {
4059 XSETMISC (overlay, ov);
4060 xassert (OVERLAYP (overlay));
4061 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4062 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4063
4064 if (end < charpos)
4065 break;
4066
4067 /* Skip this overlay if it doesn't start or end at IT's current
4068 position. */
4069 if (end != charpos && start != charpos)
4070 continue;
4071
4072 /* Skip this overlay if it doesn't apply to IT->w. */
4073 window = Foverlay_get (overlay, Qwindow);
4074 if (WINDOWP (window) && XWINDOW (window) != it->w)
4075 continue;
4076
4077 /* If the text ``under'' the overlay is invisible, both before-
4078 and after-strings from this overlay are visible; start and
4079 end position are indistinguishable. */
4080 invisible = Foverlay_get (overlay, Qinvisible);
4081 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4082
4083 /* If overlay has a non-empty before-string, record it. */
4084 if ((start == charpos || (end == charpos && invis_p))
4085 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4086 && SCHARS (str))
4087 RECORD_OVERLAY_STRING (overlay, str, 0);
4088
4089 /* If overlay has a non-empty after-string, record it. */
4090 if ((end == charpos || (start == charpos && invis_p))
4091 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4092 && SCHARS (str))
4093 RECORD_OVERLAY_STRING (overlay, str, 1);
4094 }
4095
4096 /* Process overlays after the overlay center. */
4097 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4098 {
4099 XSETMISC (overlay, ov);
4100 xassert (OVERLAYP (overlay));
4101 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4102 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4103
4104 if (start > charpos)
4105 break;
4106
4107 /* Skip this overlay if it doesn't start or end at IT's current
4108 position. */
4109 if (end != charpos && start != charpos)
4110 continue;
4111
4112 /* Skip this overlay if it doesn't apply to IT->w. */
4113 window = Foverlay_get (overlay, Qwindow);
4114 if (WINDOWP (window) && XWINDOW (window) != it->w)
4115 continue;
4116
4117 /* If the text ``under'' the overlay is invisible, it has a zero
4118 dimension, and both before- and after-strings apply. */
4119 invisible = Foverlay_get (overlay, Qinvisible);
4120 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4121
4122 /* If overlay has a non-empty before-string, record it. */
4123 if ((start == charpos || (end == charpos && invis_p))
4124 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4125 && SCHARS (str))
4126 RECORD_OVERLAY_STRING (overlay, str, 0);
4127
4128 /* If overlay has a non-empty after-string, record it. */
4129 if ((end == charpos || (start == charpos && invis_p))
4130 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4131 && SCHARS (str))
4132 RECORD_OVERLAY_STRING (overlay, str, 1);
4133 }
4134
4135 #undef RECORD_OVERLAY_STRING
4136
4137 /* Sort entries. */
4138 if (n > 1)
4139 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4140
4141 /* Record the total number of strings to process. */
4142 it->n_overlay_strings = n;
4143
4144 /* IT->current.overlay_string_index is the number of overlay strings
4145 that have already been consumed by IT. Copy some of the
4146 remaining overlay strings to IT->overlay_strings. */
4147 i = 0;
4148 j = it->current.overlay_string_index;
4149 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4150 it->overlay_strings[i++] = entries[j++].string;
4151
4152 CHECK_IT (it);
4153 }
4154
4155
4156 /* Get the first chunk of overlay strings at IT's current buffer
4157 position, or at CHARPOS if that is > 0. Value is non-zero if at
4158 least one overlay string was found. */
4159
4160 static int
4161 get_overlay_strings (it, charpos)
4162 struct it *it;
4163 int charpos;
4164 {
4165 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4166 process. This fills IT->overlay_strings with strings, and sets
4167 IT->n_overlay_strings to the total number of strings to process.
4168 IT->pos.overlay_string_index has to be set temporarily to zero
4169 because load_overlay_strings needs this; it must be set to -1
4170 when no overlay strings are found because a zero value would
4171 indicate a position in the first overlay string. */
4172 it->current.overlay_string_index = 0;
4173 load_overlay_strings (it, charpos);
4174
4175 /* If we found overlay strings, set up IT to deliver display
4176 elements from the first one. Otherwise set up IT to deliver
4177 from current_buffer. */
4178 if (it->n_overlay_strings)
4179 {
4180 /* Make sure we know settings in current_buffer, so that we can
4181 restore meaningful values when we're done with the overlay
4182 strings. */
4183 compute_stop_pos (it);
4184 xassert (it->face_id >= 0);
4185
4186 /* Save IT's settings. They are restored after all overlay
4187 strings have been processed. */
4188 xassert (it->sp == 0);
4189 push_it (it);
4190
4191 /* Set up IT to deliver display elements from the first overlay
4192 string. */
4193 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4194 it->string = it->overlay_strings[0];
4195 it->stop_charpos = 0;
4196 xassert (STRINGP (it->string));
4197 it->end_charpos = SCHARS (it->string);
4198 it->multibyte_p = STRING_MULTIBYTE (it->string);
4199 it->method = next_element_from_string;
4200 }
4201 else
4202 {
4203 it->string = Qnil;
4204 it->current.overlay_string_index = -1;
4205 it->method = next_element_from_buffer;
4206 }
4207
4208 CHECK_IT (it);
4209
4210 /* Value is non-zero if we found at least one overlay string. */
4211 return STRINGP (it->string);
4212 }
4213
4214
4215 \f
4216 /***********************************************************************
4217 Saving and restoring state
4218 ***********************************************************************/
4219
4220 /* Save current settings of IT on IT->stack. Called, for example,
4221 before setting up IT for an overlay string, to be able to restore
4222 IT's settings to what they were after the overlay string has been
4223 processed. */
4224
4225 static void
4226 push_it (it)
4227 struct it *it;
4228 {
4229 struct iterator_stack_entry *p;
4230
4231 xassert (it->sp < 2);
4232 p = it->stack + it->sp;
4233
4234 p->stop_charpos = it->stop_charpos;
4235 xassert (it->face_id >= 0);
4236 p->face_id = it->face_id;
4237 p->string = it->string;
4238 p->pos = it->current;
4239 p->end_charpos = it->end_charpos;
4240 p->string_nchars = it->string_nchars;
4241 p->area = it->area;
4242 p->multibyte_p = it->multibyte_p;
4243 p->space_width = it->space_width;
4244 p->font_height = it->font_height;
4245 p->voffset = it->voffset;
4246 p->string_from_display_prop_p = it->string_from_display_prop_p;
4247 p->display_ellipsis_p = 0;
4248 ++it->sp;
4249 }
4250
4251
4252 /* Restore IT's settings from IT->stack. Called, for example, when no
4253 more overlay strings must be processed, and we return to delivering
4254 display elements from a buffer, or when the end of a string from a
4255 `display' property is reached and we return to delivering display
4256 elements from an overlay string, or from a buffer. */
4257
4258 static void
4259 pop_it (it)
4260 struct it *it;
4261 {
4262 struct iterator_stack_entry *p;
4263
4264 xassert (it->sp > 0);
4265 --it->sp;
4266 p = it->stack + it->sp;
4267 it->stop_charpos = p->stop_charpos;
4268 it->face_id = p->face_id;
4269 it->string = p->string;
4270 it->current = p->pos;
4271 it->end_charpos = p->end_charpos;
4272 it->string_nchars = p->string_nchars;
4273 it->area = p->area;
4274 it->multibyte_p = p->multibyte_p;
4275 it->space_width = p->space_width;
4276 it->font_height = p->font_height;
4277 it->voffset = p->voffset;
4278 it->string_from_display_prop_p = p->string_from_display_prop_p;
4279 }
4280
4281
4282 \f
4283 /***********************************************************************
4284 Moving over lines
4285 ***********************************************************************/
4286
4287 /* Set IT's current position to the previous line start. */
4288
4289 static void
4290 back_to_previous_line_start (it)
4291 struct it *it;
4292 {
4293 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4294 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4295 }
4296
4297
4298 /* Move IT to the next line start.
4299
4300 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4301 we skipped over part of the text (as opposed to moving the iterator
4302 continuously over the text). Otherwise, don't change the value
4303 of *SKIPPED_P.
4304
4305 Newlines may come from buffer text, overlay strings, or strings
4306 displayed via the `display' property. That's the reason we can't
4307 simply use find_next_newline_no_quit.
4308
4309 Note that this function may not skip over invisible text that is so
4310 because of text properties and immediately follows a newline. If
4311 it would, function reseat_at_next_visible_line_start, when called
4312 from set_iterator_to_next, would effectively make invisible
4313 characters following a newline part of the wrong glyph row, which
4314 leads to wrong cursor motion. */
4315
4316 static int
4317 forward_to_next_line_start (it, skipped_p)
4318 struct it *it;
4319 int *skipped_p;
4320 {
4321 int old_selective, newline_found_p, n;
4322 const int MAX_NEWLINE_DISTANCE = 500;
4323
4324 /* If already on a newline, just consume it to avoid unintended
4325 skipping over invisible text below. */
4326 if (it->what == IT_CHARACTER
4327 && it->c == '\n'
4328 && CHARPOS (it->position) == IT_CHARPOS (*it))
4329 {
4330 set_iterator_to_next (it, 0);
4331 it->c = 0;
4332 return 1;
4333 }
4334
4335 /* Don't handle selective display in the following. It's (a)
4336 unnecessary because it's done by the caller, and (b) leads to an
4337 infinite recursion because next_element_from_ellipsis indirectly
4338 calls this function. */
4339 old_selective = it->selective;
4340 it->selective = 0;
4341
4342 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4343 from buffer text. */
4344 for (n = newline_found_p = 0;
4345 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4346 n += STRINGP (it->string) ? 0 : 1)
4347 {
4348 if (!get_next_display_element (it))
4349 return 0;
4350 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4351 set_iterator_to_next (it, 0);
4352 }
4353
4354 /* If we didn't find a newline near enough, see if we can use a
4355 short-cut. */
4356 if (!newline_found_p)
4357 {
4358 int start = IT_CHARPOS (*it);
4359 int limit = find_next_newline_no_quit (start, 1);
4360 Lisp_Object pos;
4361
4362 xassert (!STRINGP (it->string));
4363
4364 /* If there isn't any `display' property in sight, and no
4365 overlays, we can just use the position of the newline in
4366 buffer text. */
4367 if (it->stop_charpos >= limit
4368 || ((pos = Fnext_single_property_change (make_number (start),
4369 Qdisplay,
4370 Qnil, make_number (limit)),
4371 NILP (pos))
4372 && next_overlay_change (start) == ZV))
4373 {
4374 IT_CHARPOS (*it) = limit;
4375 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4376 *skipped_p = newline_found_p = 1;
4377 }
4378 else
4379 {
4380 while (get_next_display_element (it)
4381 && !newline_found_p)
4382 {
4383 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4384 set_iterator_to_next (it, 0);
4385 }
4386 }
4387 }
4388
4389 it->selective = old_selective;
4390 return newline_found_p;
4391 }
4392
4393
4394 /* Set IT's current position to the previous visible line start. Skip
4395 invisible text that is so either due to text properties or due to
4396 selective display. Caution: this does not change IT->current_x and
4397 IT->hpos. */
4398
4399 static void
4400 back_to_previous_visible_line_start (it)
4401 struct it *it;
4402 {
4403 int visible_p = 0;
4404
4405 /* Go back one newline if not on BEGV already. */
4406 if (IT_CHARPOS (*it) > BEGV)
4407 back_to_previous_line_start (it);
4408
4409 /* Move over lines that are invisible because of selective display
4410 or text properties. */
4411 while (IT_CHARPOS (*it) > BEGV
4412 && !visible_p)
4413 {
4414 visible_p = 1;
4415
4416 /* If selective > 0, then lines indented more than that values
4417 are invisible. */
4418 if (it->selective > 0
4419 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4420 (double) it->selective)) /* iftc */
4421 visible_p = 0;
4422 else
4423 {
4424 Lisp_Object prop;
4425
4426 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4427 Qinvisible, it->window);
4428 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4429 visible_p = 0;
4430 }
4431
4432 /* Back one more newline if the current one is invisible. */
4433 if (!visible_p)
4434 back_to_previous_line_start (it);
4435 }
4436
4437 xassert (IT_CHARPOS (*it) >= BEGV);
4438 xassert (IT_CHARPOS (*it) == BEGV
4439 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4440 CHECK_IT (it);
4441 }
4442
4443
4444 /* Reseat iterator IT at the previous visible line start. Skip
4445 invisible text that is so either due to text properties or due to
4446 selective display. At the end, update IT's overlay information,
4447 face information etc. */
4448
4449 static void
4450 reseat_at_previous_visible_line_start (it)
4451 struct it *it;
4452 {
4453 back_to_previous_visible_line_start (it);
4454 reseat (it, it->current.pos, 1);
4455 CHECK_IT (it);
4456 }
4457
4458
4459 /* Reseat iterator IT on the next visible line start in the current
4460 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4461 preceding the line start. Skip over invisible text that is so
4462 because of selective display. Compute faces, overlays etc at the
4463 new position. Note that this function does not skip over text that
4464 is invisible because of text properties. */
4465
4466 static void
4467 reseat_at_next_visible_line_start (it, on_newline_p)
4468 struct it *it;
4469 int on_newline_p;
4470 {
4471 int newline_found_p, skipped_p = 0;
4472
4473 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4474
4475 /* Skip over lines that are invisible because they are indented
4476 more than the value of IT->selective. */
4477 if (it->selective > 0)
4478 while (IT_CHARPOS (*it) < ZV
4479 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4480 (double) it->selective)) /* iftc */
4481 {
4482 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4483 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4484 }
4485
4486 /* Position on the newline if that's what's requested. */
4487 if (on_newline_p && newline_found_p)
4488 {
4489 if (STRINGP (it->string))
4490 {
4491 if (IT_STRING_CHARPOS (*it) > 0)
4492 {
4493 --IT_STRING_CHARPOS (*it);
4494 --IT_STRING_BYTEPOS (*it);
4495 }
4496 }
4497 else if (IT_CHARPOS (*it) > BEGV)
4498 {
4499 --IT_CHARPOS (*it);
4500 --IT_BYTEPOS (*it);
4501 reseat (it, it->current.pos, 0);
4502 }
4503 }
4504 else if (skipped_p)
4505 reseat (it, it->current.pos, 0);
4506
4507 CHECK_IT (it);
4508 }
4509
4510
4511 \f
4512 /***********************************************************************
4513 Changing an iterator's position
4514 ***********************************************************************/
4515
4516 /* Change IT's current position to POS in current_buffer. If FORCE_P
4517 is non-zero, always check for text properties at the new position.
4518 Otherwise, text properties are only looked up if POS >=
4519 IT->check_charpos of a property. */
4520
4521 static void
4522 reseat (it, pos, force_p)
4523 struct it *it;
4524 struct text_pos pos;
4525 int force_p;
4526 {
4527 int original_pos = IT_CHARPOS (*it);
4528
4529 reseat_1 (it, pos, 0);
4530
4531 /* Determine where to check text properties. Avoid doing it
4532 where possible because text property lookup is very expensive. */
4533 if (force_p
4534 || CHARPOS (pos) > it->stop_charpos
4535 || CHARPOS (pos) < original_pos)
4536 handle_stop (it);
4537
4538 CHECK_IT (it);
4539 }
4540
4541
4542 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4543 IT->stop_pos to POS, also. */
4544
4545 static void
4546 reseat_1 (it, pos, set_stop_p)
4547 struct it *it;
4548 struct text_pos pos;
4549 int set_stop_p;
4550 {
4551 /* Don't call this function when scanning a C string. */
4552 xassert (it->s == NULL);
4553
4554 /* POS must be a reasonable value. */
4555 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4556
4557 it->current.pos = it->position = pos;
4558 XSETBUFFER (it->object, current_buffer);
4559 it->end_charpos = ZV;
4560 it->dpvec = NULL;
4561 it->current.dpvec_index = -1;
4562 it->current.overlay_string_index = -1;
4563 IT_STRING_CHARPOS (*it) = -1;
4564 IT_STRING_BYTEPOS (*it) = -1;
4565 it->string = Qnil;
4566 it->method = next_element_from_buffer;
4567 /* RMS: I added this to fix a bug in move_it_vertically_backward
4568 where it->area continued to relate to the starting point
4569 for the backward motion. Bug report from
4570 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4571 However, I am not sure whether reseat still does the right thing
4572 in general after this change. */
4573 it->area = TEXT_AREA;
4574 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4575 it->sp = 0;
4576 it->face_before_selective_p = 0;
4577
4578 if (set_stop_p)
4579 it->stop_charpos = CHARPOS (pos);
4580 }
4581
4582
4583 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4584 If S is non-null, it is a C string to iterate over. Otherwise,
4585 STRING gives a Lisp string to iterate over.
4586
4587 If PRECISION > 0, don't return more then PRECISION number of
4588 characters from the string.
4589
4590 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4591 characters have been returned. FIELD_WIDTH < 0 means an infinite
4592 field width.
4593
4594 MULTIBYTE = 0 means disable processing of multibyte characters,
4595 MULTIBYTE > 0 means enable it,
4596 MULTIBYTE < 0 means use IT->multibyte_p.
4597
4598 IT must be initialized via a prior call to init_iterator before
4599 calling this function. */
4600
4601 static void
4602 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4603 struct it *it;
4604 unsigned char *s;
4605 Lisp_Object string;
4606 int charpos;
4607 int precision, field_width, multibyte;
4608 {
4609 /* No region in strings. */
4610 it->region_beg_charpos = it->region_end_charpos = -1;
4611
4612 /* No text property checks performed by default, but see below. */
4613 it->stop_charpos = -1;
4614
4615 /* Set iterator position and end position. */
4616 bzero (&it->current, sizeof it->current);
4617 it->current.overlay_string_index = -1;
4618 it->current.dpvec_index = -1;
4619 xassert (charpos >= 0);
4620
4621 /* If STRING is specified, use its multibyteness, otherwise use the
4622 setting of MULTIBYTE, if specified. */
4623 if (multibyte >= 0)
4624 it->multibyte_p = multibyte > 0;
4625
4626 if (s == NULL)
4627 {
4628 xassert (STRINGP (string));
4629 it->string = string;
4630 it->s = NULL;
4631 it->end_charpos = it->string_nchars = SCHARS (string);
4632 it->method = next_element_from_string;
4633 it->current.string_pos = string_pos (charpos, string);
4634 }
4635 else
4636 {
4637 it->s = s;
4638 it->string = Qnil;
4639
4640 /* Note that we use IT->current.pos, not it->current.string_pos,
4641 for displaying C strings. */
4642 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4643 if (it->multibyte_p)
4644 {
4645 it->current.pos = c_string_pos (charpos, s, 1);
4646 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4647 }
4648 else
4649 {
4650 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4651 it->end_charpos = it->string_nchars = strlen (s);
4652 }
4653
4654 it->method = next_element_from_c_string;
4655 }
4656
4657 /* PRECISION > 0 means don't return more than PRECISION characters
4658 from the string. */
4659 if (precision > 0 && it->end_charpos - charpos > precision)
4660 it->end_charpos = it->string_nchars = charpos + precision;
4661
4662 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4663 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4664 FIELD_WIDTH < 0 means infinite field width. This is useful for
4665 padding with `-' at the end of a mode line. */
4666 if (field_width < 0)
4667 field_width = INFINITY;
4668 if (field_width > it->end_charpos - charpos)
4669 it->end_charpos = charpos + field_width;
4670
4671 /* Use the standard display table for displaying strings. */
4672 if (DISP_TABLE_P (Vstandard_display_table))
4673 it->dp = XCHAR_TABLE (Vstandard_display_table);
4674
4675 it->stop_charpos = charpos;
4676 CHECK_IT (it);
4677 }
4678
4679
4680 \f
4681 /***********************************************************************
4682 Iteration
4683 ***********************************************************************/
4684
4685 /* Load IT's display element fields with information about the next
4686 display element from the current position of IT. Value is zero if
4687 end of buffer (or C string) is reached. */
4688
4689 int
4690 get_next_display_element (it)
4691 struct it *it;
4692 {
4693 /* Non-zero means that we found a display element. Zero means that
4694 we hit the end of what we iterate over. Performance note: the
4695 function pointer `method' used here turns out to be faster than
4696 using a sequence of if-statements. */
4697 int success_p = (*it->method) (it);
4698
4699 if (it->what == IT_CHARACTER)
4700 {
4701 /* Map via display table or translate control characters.
4702 IT->c, IT->len etc. have been set to the next character by
4703 the function call above. If we have a display table, and it
4704 contains an entry for IT->c, translate it. Don't do this if
4705 IT->c itself comes from a display table, otherwise we could
4706 end up in an infinite recursion. (An alternative could be to
4707 count the recursion depth of this function and signal an
4708 error when a certain maximum depth is reached.) Is it worth
4709 it? */
4710 if (success_p && it->dpvec == NULL)
4711 {
4712 Lisp_Object dv;
4713
4714 if (it->dp
4715 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4716 VECTORP (dv)))
4717 {
4718 struct Lisp_Vector *v = XVECTOR (dv);
4719
4720 /* Return the first character from the display table
4721 entry, if not empty. If empty, don't display the
4722 current character. */
4723 if (v->size)
4724 {
4725 it->dpvec_char_len = it->len;
4726 it->dpvec = v->contents;
4727 it->dpend = v->contents + v->size;
4728 it->current.dpvec_index = 0;
4729 it->method = next_element_from_display_vector;
4730 success_p = get_next_display_element (it);
4731 }
4732 else
4733 {
4734 set_iterator_to_next (it, 0);
4735 success_p = get_next_display_element (it);
4736 }
4737 }
4738
4739 /* Translate control characters into `\003' or `^C' form.
4740 Control characters coming from a display table entry are
4741 currently not translated because we use IT->dpvec to hold
4742 the translation. This could easily be changed but I
4743 don't believe that it is worth doing.
4744
4745 If it->multibyte_p is nonzero, eight-bit characters and
4746 non-printable multibyte characters are also translated to
4747 octal form.
4748
4749 If it->multibyte_p is zero, eight-bit characters that
4750 don't have corresponding multibyte char code are also
4751 translated to octal form. */
4752 else if ((it->c < ' '
4753 && (it->area != TEXT_AREA
4754 || (it->c != '\n' && it->c != '\t')))
4755 || (it->multibyte_p
4756 ? ((it->c >= 127
4757 && it->len == 1)
4758 || !CHAR_PRINTABLE_P (it->c))
4759 : (it->c >= 127
4760 && it->c == unibyte_char_to_multibyte (it->c))))
4761 {
4762 /* IT->c is a control character which must be displayed
4763 either as '\003' or as `^C' where the '\\' and '^'
4764 can be defined in the display table. Fill
4765 IT->ctl_chars with glyphs for what we have to
4766 display. Then, set IT->dpvec to these glyphs. */
4767 GLYPH g;
4768
4769 if (it->c < 128 && it->ctl_arrow_p)
4770 {
4771 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4772 if (it->dp
4773 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4774 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4775 g = XINT (DISP_CTRL_GLYPH (it->dp));
4776 else
4777 g = FAST_MAKE_GLYPH ('^', 0);
4778 XSETINT (it->ctl_chars[0], g);
4779
4780 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4781 XSETINT (it->ctl_chars[1], g);
4782
4783 /* Set up IT->dpvec and return first character from it. */
4784 it->dpvec_char_len = it->len;
4785 it->dpvec = it->ctl_chars;
4786 it->dpend = it->dpvec + 2;
4787 it->current.dpvec_index = 0;
4788 it->method = next_element_from_display_vector;
4789 get_next_display_element (it);
4790 }
4791 else
4792 {
4793 unsigned char str[MAX_MULTIBYTE_LENGTH];
4794 int len;
4795 int i;
4796 GLYPH escape_glyph;
4797
4798 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4799 if (it->dp
4800 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4801 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4802 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4803 else
4804 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4805
4806 if (SINGLE_BYTE_CHAR_P (it->c))
4807 str[0] = it->c, len = 1;
4808 else
4809 {
4810 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4811 if (len < 0)
4812 {
4813 /* It's an invalid character, which
4814 shouldn't happen actually, but due to
4815 bugs it may happen. Let's print the char
4816 as is, there's not much meaningful we can
4817 do with it. */
4818 str[0] = it->c;
4819 str[1] = it->c >> 8;
4820 str[2] = it->c >> 16;
4821 str[3] = it->c >> 24;
4822 len = 4;
4823 }
4824 }
4825
4826 for (i = 0; i < len; i++)
4827 {
4828 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4829 /* Insert three more glyphs into IT->ctl_chars for
4830 the octal display of the character. */
4831 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4832 XSETINT (it->ctl_chars[i * 4 + 1], g);
4833 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4834 XSETINT (it->ctl_chars[i * 4 + 2], g);
4835 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4836 XSETINT (it->ctl_chars[i * 4 + 3], g);
4837 }
4838
4839 /* Set up IT->dpvec and return the first character
4840 from it. */
4841 it->dpvec_char_len = it->len;
4842 it->dpvec = it->ctl_chars;
4843 it->dpend = it->dpvec + len * 4;
4844 it->current.dpvec_index = 0;
4845 it->method = next_element_from_display_vector;
4846 get_next_display_element (it);
4847 }
4848 }
4849 }
4850
4851 /* Adjust face id for a multibyte character. There are no
4852 multibyte character in unibyte text. */
4853 if (it->multibyte_p
4854 && success_p
4855 && FRAME_WINDOW_P (it->f))
4856 {
4857 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4858 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4859 }
4860 }
4861
4862 /* Is this character the last one of a run of characters with
4863 box? If yes, set IT->end_of_box_run_p to 1. */
4864 if (it->face_box_p
4865 && it->s == NULL)
4866 {
4867 int face_id;
4868 struct face *face;
4869
4870 it->end_of_box_run_p
4871 = ((face_id = face_after_it_pos (it),
4872 face_id != it->face_id)
4873 && (face = FACE_FROM_ID (it->f, face_id),
4874 face->box == FACE_NO_BOX));
4875 }
4876
4877 /* Value is 0 if end of buffer or string reached. */
4878 return success_p;
4879 }
4880
4881
4882 /* Move IT to the next display element.
4883
4884 RESEAT_P non-zero means if called on a newline in buffer text,
4885 skip to the next visible line start.
4886
4887 Functions get_next_display_element and set_iterator_to_next are
4888 separate because I find this arrangement easier to handle than a
4889 get_next_display_element function that also increments IT's
4890 position. The way it is we can first look at an iterator's current
4891 display element, decide whether it fits on a line, and if it does,
4892 increment the iterator position. The other way around we probably
4893 would either need a flag indicating whether the iterator has to be
4894 incremented the next time, or we would have to implement a
4895 decrement position function which would not be easy to write. */
4896
4897 void
4898 set_iterator_to_next (it, reseat_p)
4899 struct it *it;
4900 int reseat_p;
4901 {
4902 /* Reset flags indicating start and end of a sequence of characters
4903 with box. Reset them at the start of this function because
4904 moving the iterator to a new position might set them. */
4905 it->start_of_box_run_p = it->end_of_box_run_p = 0;
4906
4907 if (it->method == next_element_from_buffer)
4908 {
4909 /* The current display element of IT is a character from
4910 current_buffer. Advance in the buffer, and maybe skip over
4911 invisible lines that are so because of selective display. */
4912 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
4913 reseat_at_next_visible_line_start (it, 0);
4914 else
4915 {
4916 xassert (it->len != 0);
4917 IT_BYTEPOS (*it) += it->len;
4918 IT_CHARPOS (*it) += 1;
4919 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
4920 }
4921 }
4922 else if (it->method == next_element_from_composition)
4923 {
4924 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
4925 if (STRINGP (it->string))
4926 {
4927 IT_STRING_BYTEPOS (*it) += it->len;
4928 IT_STRING_CHARPOS (*it) += it->cmp_len;
4929 it->method = next_element_from_string;
4930 goto consider_string_end;
4931 }
4932 else
4933 {
4934 IT_BYTEPOS (*it) += it->len;
4935 IT_CHARPOS (*it) += it->cmp_len;
4936 it->method = next_element_from_buffer;
4937 }
4938 }
4939 else if (it->method == next_element_from_c_string)
4940 {
4941 /* Current display element of IT is from a C string. */
4942 IT_BYTEPOS (*it) += it->len;
4943 IT_CHARPOS (*it) += 1;
4944 }
4945 else if (it->method == next_element_from_display_vector)
4946 {
4947 /* Current display element of IT is from a display table entry.
4948 Advance in the display table definition. Reset it to null if
4949 end reached, and continue with characters from buffers/
4950 strings. */
4951 ++it->current.dpvec_index;
4952
4953 /* Restore face of the iterator to what they were before the
4954 display vector entry (these entries may contain faces). */
4955 it->face_id = it->saved_face_id;
4956
4957 if (it->dpvec + it->current.dpvec_index == it->dpend)
4958 {
4959 if (it->s)
4960 it->method = next_element_from_c_string;
4961 else if (STRINGP (it->string))
4962 it->method = next_element_from_string;
4963 else
4964 it->method = next_element_from_buffer;
4965
4966 it->dpvec = NULL;
4967 it->current.dpvec_index = -1;
4968
4969 /* Skip over characters which were displayed via IT->dpvec. */
4970 if (it->dpvec_char_len < 0)
4971 reseat_at_next_visible_line_start (it, 1);
4972 else if (it->dpvec_char_len > 0)
4973 {
4974 it->len = it->dpvec_char_len;
4975 set_iterator_to_next (it, reseat_p);
4976 }
4977 }
4978 }
4979 else if (it->method == next_element_from_string)
4980 {
4981 /* Current display element is a character from a Lisp string. */
4982 xassert (it->s == NULL && STRINGP (it->string));
4983 IT_STRING_BYTEPOS (*it) += it->len;
4984 IT_STRING_CHARPOS (*it) += 1;
4985
4986 consider_string_end:
4987
4988 if (it->current.overlay_string_index >= 0)
4989 {
4990 /* IT->string is an overlay string. Advance to the
4991 next, if there is one. */
4992 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
4993 next_overlay_string (it);
4994 }
4995 else
4996 {
4997 /* IT->string is not an overlay string. If we reached
4998 its end, and there is something on IT->stack, proceed
4999 with what is on the stack. This can be either another
5000 string, this time an overlay string, or a buffer. */
5001 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5002 && it->sp > 0)
5003 {
5004 pop_it (it);
5005 if (!STRINGP (it->string))
5006 it->method = next_element_from_buffer;
5007 else
5008 goto consider_string_end;
5009 }
5010 }
5011 }
5012 else if (it->method == next_element_from_image
5013 || it->method == next_element_from_stretch)
5014 {
5015 /* The position etc with which we have to proceed are on
5016 the stack. The position may be at the end of a string,
5017 if the `display' property takes up the whole string. */
5018 pop_it (it);
5019 it->image_id = 0;
5020 if (STRINGP (it->string))
5021 {
5022 it->method = next_element_from_string;
5023 goto consider_string_end;
5024 }
5025 else
5026 it->method = next_element_from_buffer;
5027 }
5028 else
5029 /* There are no other methods defined, so this should be a bug. */
5030 abort ();
5031
5032 xassert (it->method != next_element_from_string
5033 || (STRINGP (it->string)
5034 && IT_STRING_CHARPOS (*it) >= 0));
5035 }
5036
5037
5038 /* Load IT's display element fields with information about the next
5039 display element which comes from a display table entry or from the
5040 result of translating a control character to one of the forms `^C'
5041 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5042
5043 static int
5044 next_element_from_display_vector (it)
5045 struct it *it;
5046 {
5047 /* Precondition. */
5048 xassert (it->dpvec && it->current.dpvec_index >= 0);
5049
5050 /* Remember the current face id in case glyphs specify faces.
5051 IT's face is restored in set_iterator_to_next. */
5052 it->saved_face_id = it->face_id;
5053
5054 if (INTEGERP (*it->dpvec)
5055 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5056 {
5057 int lface_id;
5058 GLYPH g;
5059
5060 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5061 it->c = FAST_GLYPH_CHAR (g);
5062 it->len = CHAR_BYTES (it->c);
5063
5064 /* The entry may contain a face id to use. Such a face id is
5065 the id of a Lisp face, not a realized face. A face id of
5066 zero means no face is specified. */
5067 lface_id = FAST_GLYPH_FACE (g);
5068 if (lface_id)
5069 {
5070 /* The function returns -1 if lface_id is invalid. */
5071 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5072 if (face_id >= 0)
5073 it->face_id = face_id;
5074 }
5075 }
5076 else
5077 /* Display table entry is invalid. Return a space. */
5078 it->c = ' ', it->len = 1;
5079
5080 /* Don't change position and object of the iterator here. They are
5081 still the values of the character that had this display table
5082 entry or was translated, and that's what we want. */
5083 it->what = IT_CHARACTER;
5084 return 1;
5085 }
5086
5087
5088 /* Load IT with the next display element from Lisp string IT->string.
5089 IT->current.string_pos is the current position within the string.
5090 If IT->current.overlay_string_index >= 0, the Lisp string is an
5091 overlay string. */
5092
5093 static int
5094 next_element_from_string (it)
5095 struct it *it;
5096 {
5097 struct text_pos position;
5098
5099 xassert (STRINGP (it->string));
5100 xassert (IT_STRING_CHARPOS (*it) >= 0);
5101 position = it->current.string_pos;
5102
5103 /* Time to check for invisible text? */
5104 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5105 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5106 {
5107 handle_stop (it);
5108
5109 /* Since a handler may have changed IT->method, we must
5110 recurse here. */
5111 return get_next_display_element (it);
5112 }
5113
5114 if (it->current.overlay_string_index >= 0)
5115 {
5116 /* Get the next character from an overlay string. In overlay
5117 strings, There is no field width or padding with spaces to
5118 do. */
5119 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5120 {
5121 it->what = IT_EOB;
5122 return 0;
5123 }
5124 else if (STRING_MULTIBYTE (it->string))
5125 {
5126 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5127 const unsigned char *s = (SDATA (it->string)
5128 + IT_STRING_BYTEPOS (*it));
5129 it->c = string_char_and_length (s, remaining, &it->len);
5130 }
5131 else
5132 {
5133 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5134 it->len = 1;
5135 }
5136 }
5137 else
5138 {
5139 /* Get the next character from a Lisp string that is not an
5140 overlay string. Such strings come from the mode line, for
5141 example. We may have to pad with spaces, or truncate the
5142 string. See also next_element_from_c_string. */
5143 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5144 {
5145 it->what = IT_EOB;
5146 return 0;
5147 }
5148 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5149 {
5150 /* Pad with spaces. */
5151 it->c = ' ', it->len = 1;
5152 CHARPOS (position) = BYTEPOS (position) = -1;
5153 }
5154 else if (STRING_MULTIBYTE (it->string))
5155 {
5156 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5157 const unsigned char *s = (SDATA (it->string)
5158 + IT_STRING_BYTEPOS (*it));
5159 it->c = string_char_and_length (s, maxlen, &it->len);
5160 }
5161 else
5162 {
5163 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5164 it->len = 1;
5165 }
5166 }
5167
5168 /* Record what we have and where it came from. Note that we store a
5169 buffer position in IT->position although it could arguably be a
5170 string position. */
5171 it->what = IT_CHARACTER;
5172 it->object = it->string;
5173 it->position = position;
5174 return 1;
5175 }
5176
5177
5178 /* Load IT with next display element from C string IT->s.
5179 IT->string_nchars is the maximum number of characters to return
5180 from the string. IT->end_charpos may be greater than
5181 IT->string_nchars when this function is called, in which case we
5182 may have to return padding spaces. Value is zero if end of string
5183 reached, including padding spaces. */
5184
5185 static int
5186 next_element_from_c_string (it)
5187 struct it *it;
5188 {
5189 int success_p = 1;
5190
5191 xassert (it->s);
5192 it->what = IT_CHARACTER;
5193 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5194 it->object = Qnil;
5195
5196 /* IT's position can be greater IT->string_nchars in case a field
5197 width or precision has been specified when the iterator was
5198 initialized. */
5199 if (IT_CHARPOS (*it) >= it->end_charpos)
5200 {
5201 /* End of the game. */
5202 it->what = IT_EOB;
5203 success_p = 0;
5204 }
5205 else if (IT_CHARPOS (*it) >= it->string_nchars)
5206 {
5207 /* Pad with spaces. */
5208 it->c = ' ', it->len = 1;
5209 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5210 }
5211 else if (it->multibyte_p)
5212 {
5213 /* Implementation note: The calls to strlen apparently aren't a
5214 performance problem because there is no noticeable performance
5215 difference between Emacs running in unibyte or multibyte mode. */
5216 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5217 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5218 maxlen, &it->len);
5219 }
5220 else
5221 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5222
5223 return success_p;
5224 }
5225
5226
5227 /* Set up IT to return characters from an ellipsis, if appropriate.
5228 The definition of the ellipsis glyphs may come from a display table
5229 entry. This function Fills IT with the first glyph from the
5230 ellipsis if an ellipsis is to be displayed. */
5231
5232 static int
5233 next_element_from_ellipsis (it)
5234 struct it *it;
5235 {
5236 if (it->selective_display_ellipsis_p)
5237 {
5238 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5239 {
5240 /* Use the display table definition for `...'. Invalid glyphs
5241 will be handled by the method returning elements from dpvec. */
5242 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5243 it->dpvec_char_len = it->len;
5244 it->dpvec = v->contents;
5245 it->dpend = v->contents + v->size;
5246 it->current.dpvec_index = 0;
5247 it->method = next_element_from_display_vector;
5248 }
5249 else
5250 {
5251 /* Use default `...' which is stored in default_invis_vector. */
5252 it->dpvec_char_len = it->len;
5253 it->dpvec = default_invis_vector;
5254 it->dpend = default_invis_vector + 3;
5255 it->current.dpvec_index = 0;
5256 it->method = next_element_from_display_vector;
5257 }
5258 }
5259 else
5260 {
5261 /* The face at the current position may be different from the
5262 face we find after the invisible text. Remember what it
5263 was in IT->saved_face_id, and signal that it's there by
5264 setting face_before_selective_p. */
5265 it->saved_face_id = it->face_id;
5266 it->method = next_element_from_buffer;
5267 reseat_at_next_visible_line_start (it, 1);
5268 it->face_before_selective_p = 1;
5269 }
5270
5271 return get_next_display_element (it);
5272 }
5273
5274
5275 /* Deliver an image display element. The iterator IT is already
5276 filled with image information (done in handle_display_prop). Value
5277 is always 1. */
5278
5279
5280 static int
5281 next_element_from_image (it)
5282 struct it *it;
5283 {
5284 it->what = IT_IMAGE;
5285 return 1;
5286 }
5287
5288
5289 /* Fill iterator IT with next display element from a stretch glyph
5290 property. IT->object is the value of the text property. Value is
5291 always 1. */
5292
5293 static int
5294 next_element_from_stretch (it)
5295 struct it *it;
5296 {
5297 it->what = IT_STRETCH;
5298 return 1;
5299 }
5300
5301
5302 /* Load IT with the next display element from current_buffer. Value
5303 is zero if end of buffer reached. IT->stop_charpos is the next
5304 position at which to stop and check for text properties or buffer
5305 end. */
5306
5307 static int
5308 next_element_from_buffer (it)
5309 struct it *it;
5310 {
5311 int success_p = 1;
5312
5313 /* Check this assumption, otherwise, we would never enter the
5314 if-statement, below. */
5315 xassert (IT_CHARPOS (*it) >= BEGV
5316 && IT_CHARPOS (*it) <= it->stop_charpos);
5317
5318 if (IT_CHARPOS (*it) >= it->stop_charpos)
5319 {
5320 if (IT_CHARPOS (*it) >= it->end_charpos)
5321 {
5322 int overlay_strings_follow_p;
5323
5324 /* End of the game, except when overlay strings follow that
5325 haven't been returned yet. */
5326 if (it->overlay_strings_at_end_processed_p)
5327 overlay_strings_follow_p = 0;
5328 else
5329 {
5330 it->overlay_strings_at_end_processed_p = 1;
5331 overlay_strings_follow_p = get_overlay_strings (it, 0);
5332 }
5333
5334 if (overlay_strings_follow_p)
5335 success_p = get_next_display_element (it);
5336 else
5337 {
5338 it->what = IT_EOB;
5339 it->position = it->current.pos;
5340 success_p = 0;
5341 }
5342 }
5343 else
5344 {
5345 handle_stop (it);
5346 return get_next_display_element (it);
5347 }
5348 }
5349 else
5350 {
5351 /* No face changes, overlays etc. in sight, so just return a
5352 character from current_buffer. */
5353 unsigned char *p;
5354
5355 /* Maybe run the redisplay end trigger hook. Performance note:
5356 This doesn't seem to cost measurable time. */
5357 if (it->redisplay_end_trigger_charpos
5358 && it->glyph_row
5359 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5360 run_redisplay_end_trigger_hook (it);
5361
5362 /* Get the next character, maybe multibyte. */
5363 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5364 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5365 {
5366 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5367 - IT_BYTEPOS (*it));
5368 it->c = string_char_and_length (p, maxlen, &it->len);
5369 }
5370 else
5371 it->c = *p, it->len = 1;
5372
5373 /* Record what we have and where it came from. */
5374 it->what = IT_CHARACTER;;
5375 it->object = it->w->buffer;
5376 it->position = it->current.pos;
5377
5378 /* Normally we return the character found above, except when we
5379 really want to return an ellipsis for selective display. */
5380 if (it->selective)
5381 {
5382 if (it->c == '\n')
5383 {
5384 /* A value of selective > 0 means hide lines indented more
5385 than that number of columns. */
5386 if (it->selective > 0
5387 && IT_CHARPOS (*it) + 1 < ZV
5388 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5389 IT_BYTEPOS (*it) + 1,
5390 (double) it->selective)) /* iftc */
5391 {
5392 success_p = next_element_from_ellipsis (it);
5393 it->dpvec_char_len = -1;
5394 }
5395 }
5396 else if (it->c == '\r' && it->selective == -1)
5397 {
5398 /* A value of selective == -1 means that everything from the
5399 CR to the end of the line is invisible, with maybe an
5400 ellipsis displayed for it. */
5401 success_p = next_element_from_ellipsis (it);
5402 it->dpvec_char_len = -1;
5403 }
5404 }
5405 }
5406
5407 /* Value is zero if end of buffer reached. */
5408 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5409 return success_p;
5410 }
5411
5412
5413 /* Run the redisplay end trigger hook for IT. */
5414
5415 static void
5416 run_redisplay_end_trigger_hook (it)
5417 struct it *it;
5418 {
5419 Lisp_Object args[3];
5420
5421 /* IT->glyph_row should be non-null, i.e. we should be actually
5422 displaying something, or otherwise we should not run the hook. */
5423 xassert (it->glyph_row);
5424
5425 /* Set up hook arguments. */
5426 args[0] = Qredisplay_end_trigger_functions;
5427 args[1] = it->window;
5428 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5429 it->redisplay_end_trigger_charpos = 0;
5430
5431 /* Since we are *trying* to run these functions, don't try to run
5432 them again, even if they get an error. */
5433 it->w->redisplay_end_trigger = Qnil;
5434 Frun_hook_with_args (3, args);
5435
5436 /* Notice if it changed the face of the character we are on. */
5437 handle_face_prop (it);
5438 }
5439
5440
5441 /* Deliver a composition display element. The iterator IT is already
5442 filled with composition information (done in
5443 handle_composition_prop). Value is always 1. */
5444
5445 static int
5446 next_element_from_composition (it)
5447 struct it *it;
5448 {
5449 it->what = IT_COMPOSITION;
5450 it->position = (STRINGP (it->string)
5451 ? it->current.string_pos
5452 : it->current.pos);
5453 return 1;
5454 }
5455
5456
5457 \f
5458 /***********************************************************************
5459 Moving an iterator without producing glyphs
5460 ***********************************************************************/
5461
5462 /* Move iterator IT to a specified buffer or X position within one
5463 line on the display without producing glyphs.
5464
5465 OP should be a bit mask including some or all of these bits:
5466 MOVE_TO_X: Stop on reaching x-position TO_X.
5467 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5468 Regardless of OP's value, stop in reaching the end of the display line.
5469
5470 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5471 This means, in particular, that TO_X includes window's horizontal
5472 scroll amount.
5473
5474 The return value has several possible values that
5475 say what condition caused the scan to stop:
5476
5477 MOVE_POS_MATCH_OR_ZV
5478 - when TO_POS or ZV was reached.
5479
5480 MOVE_X_REACHED
5481 -when TO_X was reached before TO_POS or ZV were reached.
5482
5483 MOVE_LINE_CONTINUED
5484 - when we reached the end of the display area and the line must
5485 be continued.
5486
5487 MOVE_LINE_TRUNCATED
5488 - when we reached the end of the display area and the line is
5489 truncated.
5490
5491 MOVE_NEWLINE_OR_CR
5492 - when we stopped at a line end, i.e. a newline or a CR and selective
5493 display is on. */
5494
5495 static enum move_it_result
5496 move_it_in_display_line_to (it, to_charpos, to_x, op)
5497 struct it *it;
5498 int to_charpos, to_x, op;
5499 {
5500 enum move_it_result result = MOVE_UNDEFINED;
5501 struct glyph_row *saved_glyph_row;
5502
5503 /* Don't produce glyphs in produce_glyphs. */
5504 saved_glyph_row = it->glyph_row;
5505 it->glyph_row = NULL;
5506
5507 while (1)
5508 {
5509 int x, i, ascent = 0, descent = 0;
5510
5511 /* Stop when ZV or TO_CHARPOS reached. */
5512 if (!get_next_display_element (it)
5513 || ((op & MOVE_TO_POS) != 0
5514 && BUFFERP (it->object)
5515 && IT_CHARPOS (*it) >= to_charpos))
5516 {
5517 result = MOVE_POS_MATCH_OR_ZV;
5518 break;
5519 }
5520
5521 /* The call to produce_glyphs will get the metrics of the
5522 display element IT is loaded with. We record in x the
5523 x-position before this display element in case it does not
5524 fit on the line. */
5525 x = it->current_x;
5526
5527 /* Remember the line height so far in case the next element doesn't
5528 fit on the line. */
5529 if (!it->truncate_lines_p)
5530 {
5531 ascent = it->max_ascent;
5532 descent = it->max_descent;
5533 }
5534
5535 PRODUCE_GLYPHS (it);
5536
5537 if (it->area != TEXT_AREA)
5538 {
5539 set_iterator_to_next (it, 1);
5540 continue;
5541 }
5542
5543 /* The number of glyphs we get back in IT->nglyphs will normally
5544 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5545 character on a terminal frame, or (iii) a line end. For the
5546 second case, IT->nglyphs - 1 padding glyphs will be present
5547 (on X frames, there is only one glyph produced for a
5548 composite character.
5549
5550 The behavior implemented below means, for continuation lines,
5551 that as many spaces of a TAB as fit on the current line are
5552 displayed there. For terminal frames, as many glyphs of a
5553 multi-glyph character are displayed in the current line, too.
5554 This is what the old redisplay code did, and we keep it that
5555 way. Under X, the whole shape of a complex character must
5556 fit on the line or it will be completely displayed in the
5557 next line.
5558
5559 Note that both for tabs and padding glyphs, all glyphs have
5560 the same width. */
5561 if (it->nglyphs)
5562 {
5563 /* More than one glyph or glyph doesn't fit on line. All
5564 glyphs have the same width. */
5565 int single_glyph_width = it->pixel_width / it->nglyphs;
5566 int new_x;
5567
5568 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5569 {
5570 new_x = x + single_glyph_width;
5571
5572 /* We want to leave anything reaching TO_X to the caller. */
5573 if ((op & MOVE_TO_X) && new_x > to_x)
5574 {
5575 it->current_x = x;
5576 result = MOVE_X_REACHED;
5577 break;
5578 }
5579 else if (/* Lines are continued. */
5580 !it->truncate_lines_p
5581 && (/* And glyph doesn't fit on the line. */
5582 new_x > it->last_visible_x
5583 /* Or it fits exactly and we're on a window
5584 system frame. */
5585 || (new_x == it->last_visible_x
5586 && FRAME_WINDOW_P (it->f))))
5587 {
5588 if (/* IT->hpos == 0 means the very first glyph
5589 doesn't fit on the line, e.g. a wide image. */
5590 it->hpos == 0
5591 || (new_x == it->last_visible_x
5592 && FRAME_WINDOW_P (it->f)))
5593 {
5594 ++it->hpos;
5595 it->current_x = new_x;
5596 if (i == it->nglyphs - 1)
5597 set_iterator_to_next (it, 1);
5598 }
5599 else
5600 {
5601 it->current_x = x;
5602 it->max_ascent = ascent;
5603 it->max_descent = descent;
5604 }
5605
5606 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5607 IT_CHARPOS (*it)));
5608 result = MOVE_LINE_CONTINUED;
5609 break;
5610 }
5611 else if (new_x > it->first_visible_x)
5612 {
5613 /* Glyph is visible. Increment number of glyphs that
5614 would be displayed. */
5615 ++it->hpos;
5616 }
5617 else
5618 {
5619 /* Glyph is completely off the left margin of the display
5620 area. Nothing to do. */
5621 }
5622 }
5623
5624 if (result != MOVE_UNDEFINED)
5625 break;
5626 }
5627 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5628 {
5629 /* Stop when TO_X specified and reached. This check is
5630 necessary here because of lines consisting of a line end,
5631 only. The line end will not produce any glyphs and we
5632 would never get MOVE_X_REACHED. */
5633 xassert (it->nglyphs == 0);
5634 result = MOVE_X_REACHED;
5635 break;
5636 }
5637
5638 /* Is this a line end? If yes, we're done. */
5639 if (ITERATOR_AT_END_OF_LINE_P (it))
5640 {
5641 result = MOVE_NEWLINE_OR_CR;
5642 break;
5643 }
5644
5645 /* The current display element has been consumed. Advance
5646 to the next. */
5647 set_iterator_to_next (it, 1);
5648
5649 /* Stop if lines are truncated and IT's current x-position is
5650 past the right edge of the window now. */
5651 if (it->truncate_lines_p
5652 && it->current_x >= it->last_visible_x)
5653 {
5654 result = MOVE_LINE_TRUNCATED;
5655 break;
5656 }
5657 }
5658
5659 /* Restore the iterator settings altered at the beginning of this
5660 function. */
5661 it->glyph_row = saved_glyph_row;
5662 return result;
5663 }
5664
5665
5666 /* Move IT forward until it satisfies one or more of the criteria in
5667 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5668
5669 OP is a bit-mask that specifies where to stop, and in particular,
5670 which of those four position arguments makes a difference. See the
5671 description of enum move_operation_enum.
5672
5673 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5674 screen line, this function will set IT to the next position >
5675 TO_CHARPOS. */
5676
5677 void
5678 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5679 struct it *it;
5680 int to_charpos, to_x, to_y, to_vpos;
5681 int op;
5682 {
5683 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5684 int line_height;
5685 int reached = 0;
5686
5687 for (;;)
5688 {
5689 if (op & MOVE_TO_VPOS)
5690 {
5691 /* If no TO_CHARPOS and no TO_X specified, stop at the
5692 start of the line TO_VPOS. */
5693 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5694 {
5695 if (it->vpos == to_vpos)
5696 {
5697 reached = 1;
5698 break;
5699 }
5700 else
5701 skip = move_it_in_display_line_to (it, -1, -1, 0);
5702 }
5703 else
5704 {
5705 /* TO_VPOS >= 0 means stop at TO_X in the line at
5706 TO_VPOS, or at TO_POS, whichever comes first. */
5707 if (it->vpos == to_vpos)
5708 {
5709 reached = 2;
5710 break;
5711 }
5712
5713 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5714
5715 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5716 {
5717 reached = 3;
5718 break;
5719 }
5720 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5721 {
5722 /* We have reached TO_X but not in the line we want. */
5723 skip = move_it_in_display_line_to (it, to_charpos,
5724 -1, MOVE_TO_POS);
5725 if (skip == MOVE_POS_MATCH_OR_ZV)
5726 {
5727 reached = 4;
5728 break;
5729 }
5730 }
5731 }
5732 }
5733 else if (op & MOVE_TO_Y)
5734 {
5735 struct it it_backup;
5736
5737 /* TO_Y specified means stop at TO_X in the line containing
5738 TO_Y---or at TO_CHARPOS if this is reached first. The
5739 problem is that we can't really tell whether the line
5740 contains TO_Y before we have completely scanned it, and
5741 this may skip past TO_X. What we do is to first scan to
5742 TO_X.
5743
5744 If TO_X is not specified, use a TO_X of zero. The reason
5745 is to make the outcome of this function more predictable.
5746 If we didn't use TO_X == 0, we would stop at the end of
5747 the line which is probably not what a caller would expect
5748 to happen. */
5749 skip = move_it_in_display_line_to (it, to_charpos,
5750 ((op & MOVE_TO_X)
5751 ? to_x : 0),
5752 (MOVE_TO_X
5753 | (op & MOVE_TO_POS)));
5754
5755 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5756 if (skip == MOVE_POS_MATCH_OR_ZV)
5757 {
5758 reached = 5;
5759 break;
5760 }
5761
5762 /* If TO_X was reached, we would like to know whether TO_Y
5763 is in the line. This can only be said if we know the
5764 total line height which requires us to scan the rest of
5765 the line. */
5766 if (skip == MOVE_X_REACHED)
5767 {
5768 it_backup = *it;
5769 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5770 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5771 op & MOVE_TO_POS);
5772 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5773 }
5774
5775 /* Now, decide whether TO_Y is in this line. */
5776 line_height = it->max_ascent + it->max_descent;
5777 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5778
5779 if (to_y >= it->current_y
5780 && to_y < it->current_y + line_height)
5781 {
5782 if (skip == MOVE_X_REACHED)
5783 /* If TO_Y is in this line and TO_X was reached above,
5784 we scanned too far. We have to restore IT's settings
5785 to the ones before skipping. */
5786 *it = it_backup;
5787 reached = 6;
5788 }
5789 else if (skip == MOVE_X_REACHED)
5790 {
5791 skip = skip2;
5792 if (skip == MOVE_POS_MATCH_OR_ZV)
5793 reached = 7;
5794 }
5795
5796 if (reached)
5797 break;
5798 }
5799 else
5800 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5801
5802 switch (skip)
5803 {
5804 case MOVE_POS_MATCH_OR_ZV:
5805 reached = 8;
5806 goto out;
5807
5808 case MOVE_NEWLINE_OR_CR:
5809 set_iterator_to_next (it, 1);
5810 it->continuation_lines_width = 0;
5811 break;
5812
5813 case MOVE_LINE_TRUNCATED:
5814 it->continuation_lines_width = 0;
5815 reseat_at_next_visible_line_start (it, 0);
5816 if ((op & MOVE_TO_POS) != 0
5817 && IT_CHARPOS (*it) > to_charpos)
5818 {
5819 reached = 9;
5820 goto out;
5821 }
5822 break;
5823
5824 case MOVE_LINE_CONTINUED:
5825 it->continuation_lines_width += it->current_x;
5826 break;
5827
5828 default:
5829 abort ();
5830 }
5831
5832 /* Reset/increment for the next run. */
5833 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
5834 it->current_x = it->hpos = 0;
5835 it->current_y += it->max_ascent + it->max_descent;
5836 ++it->vpos;
5837 last_height = it->max_ascent + it->max_descent;
5838 last_max_ascent = it->max_ascent;
5839 it->max_ascent = it->max_descent = 0;
5840 }
5841
5842 out:
5843
5844 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
5845 }
5846
5847
5848 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5849
5850 If DY > 0, move IT backward at least that many pixels. DY = 0
5851 means move IT backward to the preceding line start or BEGV. This
5852 function may move over more than DY pixels if IT->current_y - DY
5853 ends up in the middle of a line; in this case IT->current_y will be
5854 set to the top of the line moved to. */
5855
5856 void
5857 move_it_vertically_backward (it, dy)
5858 struct it *it;
5859 int dy;
5860 {
5861 int nlines, h;
5862 struct it it2, it3;
5863 int start_pos = IT_CHARPOS (*it);
5864
5865 xassert (dy >= 0);
5866
5867 /* Estimate how many newlines we must move back. */
5868 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
5869
5870 /* Set the iterator's position that many lines back. */
5871 while (nlines-- && IT_CHARPOS (*it) > BEGV)
5872 back_to_previous_visible_line_start (it);
5873
5874 /* Reseat the iterator here. When moving backward, we don't want
5875 reseat to skip forward over invisible text, set up the iterator
5876 to deliver from overlay strings at the new position etc. So,
5877 use reseat_1 here. */
5878 reseat_1 (it, it->current.pos, 1);
5879
5880 /* We are now surely at a line start. */
5881 it->current_x = it->hpos = 0;
5882 it->continuation_lines_width = 0;
5883
5884 /* Move forward and see what y-distance we moved. First move to the
5885 start of the next line so that we get its height. We need this
5886 height to be able to tell whether we reached the specified
5887 y-distance. */
5888 it2 = *it;
5889 it2.max_ascent = it2.max_descent = 0;
5890 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
5891 MOVE_TO_POS | MOVE_TO_VPOS);
5892 xassert (IT_CHARPOS (*it) >= BEGV);
5893 it3 = it2;
5894
5895 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
5896 xassert (IT_CHARPOS (*it) >= BEGV);
5897 /* H is the actual vertical distance from the position in *IT
5898 and the starting position. */
5899 h = it2.current_y - it->current_y;
5900 /* NLINES is the distance in number of lines. */
5901 nlines = it2.vpos - it->vpos;
5902
5903 /* Correct IT's y and vpos position
5904 so that they are relative to the starting point. */
5905 it->vpos -= nlines;
5906 it->current_y -= h;
5907
5908 if (dy == 0)
5909 {
5910 /* DY == 0 means move to the start of the screen line. The
5911 value of nlines is > 0 if continuation lines were involved. */
5912 if (nlines > 0)
5913 move_it_by_lines (it, nlines, 1);
5914 xassert (IT_CHARPOS (*it) <= start_pos);
5915 }
5916 else
5917 {
5918 /* The y-position we try to reach, relative to *IT.
5919 Note that H has been subtracted in front of the if-statement. */
5920 int target_y = it->current_y + h - dy;
5921 int y0 = it3.current_y;
5922 int y1 = line_bottom_y (&it3);
5923 int line_height = y1 - y0;
5924
5925 /* If we did not reach target_y, try to move further backward if
5926 we can. If we moved too far backward, try to move forward. */
5927 if (target_y < it->current_y
5928 /* This is heuristic. In a window that's 3 lines high, with
5929 a line height of 13 pixels each, recentering with point
5930 on the bottom line will try to move -39/2 = 19 pixels
5931 backward. Try to avoid moving into the first line. */
5932 && it->current_y - target_y > line_height / 3 * 2
5933 && IT_CHARPOS (*it) > BEGV)
5934 {
5935 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
5936 target_y - it->current_y));
5937 move_it_vertically (it, target_y - it->current_y);
5938 xassert (IT_CHARPOS (*it) >= BEGV);
5939 }
5940 else if (target_y >= it->current_y + line_height
5941 && IT_CHARPOS (*it) < ZV)
5942 {
5943 /* Should move forward by at least one line, maybe more.
5944
5945 Note: Calling move_it_by_lines can be expensive on
5946 terminal frames, where compute_motion is used (via
5947 vmotion) to do the job, when there are very long lines
5948 and truncate-lines is nil. That's the reason for
5949 treating terminal frames specially here. */
5950
5951 if (!FRAME_WINDOW_P (it->f))
5952 move_it_vertically (it, target_y - (it->current_y + line_height));
5953 else
5954 {
5955 do
5956 {
5957 move_it_by_lines (it, 1, 1);
5958 }
5959 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
5960 }
5961
5962 xassert (IT_CHARPOS (*it) >= BEGV);
5963 }
5964 }
5965 }
5966
5967
5968 /* Move IT by a specified amount of pixel lines DY. DY negative means
5969 move backwards. DY = 0 means move to start of screen line. At the
5970 end, IT will be on the start of a screen line. */
5971
5972 void
5973 move_it_vertically (it, dy)
5974 struct it *it;
5975 int dy;
5976 {
5977 if (dy <= 0)
5978 move_it_vertically_backward (it, -dy);
5979 else if (dy > 0)
5980 {
5981 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
5982 move_it_to (it, ZV, -1, it->current_y + dy, -1,
5983 MOVE_TO_POS | MOVE_TO_Y);
5984 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
5985
5986 /* If buffer ends in ZV without a newline, move to the start of
5987 the line to satisfy the post-condition. */
5988 if (IT_CHARPOS (*it) == ZV
5989 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
5990 move_it_by_lines (it, 0, 0);
5991 }
5992 }
5993
5994
5995 /* Move iterator IT past the end of the text line it is in. */
5996
5997 void
5998 move_it_past_eol (it)
5999 struct it *it;
6000 {
6001 enum move_it_result rc;
6002
6003 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6004 if (rc == MOVE_NEWLINE_OR_CR)
6005 set_iterator_to_next (it, 0);
6006 }
6007
6008
6009 #if 0 /* Currently not used. */
6010
6011 /* Return non-zero if some text between buffer positions START_CHARPOS
6012 and END_CHARPOS is invisible. IT->window is the window for text
6013 property lookup. */
6014
6015 static int
6016 invisible_text_between_p (it, start_charpos, end_charpos)
6017 struct it *it;
6018 int start_charpos, end_charpos;
6019 {
6020 Lisp_Object prop, limit;
6021 int invisible_found_p;
6022
6023 xassert (it != NULL && start_charpos <= end_charpos);
6024
6025 /* Is text at START invisible? */
6026 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6027 it->window);
6028 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6029 invisible_found_p = 1;
6030 else
6031 {
6032 limit = Fnext_single_char_property_change (make_number (start_charpos),
6033 Qinvisible, Qnil,
6034 make_number (end_charpos));
6035 invisible_found_p = XFASTINT (limit) < end_charpos;
6036 }
6037
6038 return invisible_found_p;
6039 }
6040
6041 #endif /* 0 */
6042
6043
6044 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6045 negative means move up. DVPOS == 0 means move to the start of the
6046 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6047 NEED_Y_P is zero, IT->current_y will be left unchanged.
6048
6049 Further optimization ideas: If we would know that IT->f doesn't use
6050 a face with proportional font, we could be faster for
6051 truncate-lines nil. */
6052
6053 void
6054 move_it_by_lines (it, dvpos, need_y_p)
6055 struct it *it;
6056 int dvpos, need_y_p;
6057 {
6058 struct position pos;
6059
6060 if (!FRAME_WINDOW_P (it->f))
6061 {
6062 struct text_pos textpos;
6063
6064 /* We can use vmotion on frames without proportional fonts. */
6065 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6066 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6067 reseat (it, textpos, 1);
6068 it->vpos += pos.vpos;
6069 it->current_y += pos.vpos;
6070 }
6071 else if (dvpos == 0)
6072 {
6073 /* DVPOS == 0 means move to the start of the screen line. */
6074 move_it_vertically_backward (it, 0);
6075 xassert (it->current_x == 0 && it->hpos == 0);
6076 }
6077 else if (dvpos > 0)
6078 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6079 else
6080 {
6081 struct it it2;
6082 int start_charpos, i;
6083
6084 /* Start at the beginning of the screen line containing IT's
6085 position. */
6086 move_it_vertically_backward (it, 0);
6087
6088 /* Go back -DVPOS visible lines and reseat the iterator there. */
6089 start_charpos = IT_CHARPOS (*it);
6090 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6091 back_to_previous_visible_line_start (it);
6092 reseat (it, it->current.pos, 1);
6093 it->current_x = it->hpos = 0;
6094
6095 /* Above call may have moved too far if continuation lines
6096 are involved. Scan forward and see if it did. */
6097 it2 = *it;
6098 it2.vpos = it2.current_y = 0;
6099 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6100 it->vpos -= it2.vpos;
6101 it->current_y -= it2.current_y;
6102 it->current_x = it->hpos = 0;
6103
6104 /* If we moved too far, move IT some lines forward. */
6105 if (it2.vpos > -dvpos)
6106 {
6107 int delta = it2.vpos + dvpos;
6108 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6109 }
6110 }
6111 }
6112
6113 /* Return 1 if IT points into the middle of a display vector. */
6114
6115 int
6116 in_display_vector_p (it)
6117 struct it *it;
6118 {
6119 return (it->method == next_element_from_display_vector
6120 && it->current.dpvec_index > 0
6121 && it->dpvec + it->current.dpvec_index != it->dpend);
6122 }
6123
6124 \f
6125 /***********************************************************************
6126 Messages
6127 ***********************************************************************/
6128
6129
6130 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6131 to *Messages*. */
6132
6133 void
6134 add_to_log (format, arg1, arg2)
6135 char *format;
6136 Lisp_Object arg1, arg2;
6137 {
6138 Lisp_Object args[3];
6139 Lisp_Object msg, fmt;
6140 char *buffer;
6141 int len;
6142 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6143
6144 /* Do nothing if called asynchronously. Inserting text into
6145 a buffer may call after-change-functions and alike and
6146 that would means running Lisp asynchronously. */
6147 if (handling_signal)
6148 return;
6149
6150 fmt = msg = Qnil;
6151 GCPRO4 (fmt, msg, arg1, arg2);
6152
6153 args[0] = fmt = build_string (format);
6154 args[1] = arg1;
6155 args[2] = arg2;
6156 msg = Fformat (3, args);
6157
6158 len = SBYTES (msg) + 1;
6159 buffer = (char *) alloca (len);
6160 bcopy (SDATA (msg), buffer, len);
6161
6162 message_dolog (buffer, len - 1, 1, 0);
6163 UNGCPRO;
6164 }
6165
6166
6167 /* Output a newline in the *Messages* buffer if "needs" one. */
6168
6169 void
6170 message_log_maybe_newline ()
6171 {
6172 if (message_log_need_newline)
6173 message_dolog ("", 0, 1, 0);
6174 }
6175
6176
6177 /* Add a string M of length NBYTES to the message log, optionally
6178 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6179 nonzero, means interpret the contents of M as multibyte. This
6180 function calls low-level routines in order to bypass text property
6181 hooks, etc. which might not be safe to run. */
6182
6183 void
6184 message_dolog (m, nbytes, nlflag, multibyte)
6185 const char *m;
6186 int nbytes, nlflag, multibyte;
6187 {
6188 if (!NILP (Vmemory_full))
6189 return;
6190
6191 if (!NILP (Vmessage_log_max))
6192 {
6193 struct buffer *oldbuf;
6194 Lisp_Object oldpoint, oldbegv, oldzv;
6195 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6196 int point_at_end = 0;
6197 int zv_at_end = 0;
6198 Lisp_Object old_deactivate_mark, tem;
6199 struct gcpro gcpro1;
6200
6201 old_deactivate_mark = Vdeactivate_mark;
6202 oldbuf = current_buffer;
6203 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6204 current_buffer->undo_list = Qt;
6205
6206 oldpoint = message_dolog_marker1;
6207 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6208 oldbegv = message_dolog_marker2;
6209 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6210 oldzv = message_dolog_marker3;
6211 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6212 GCPRO1 (old_deactivate_mark);
6213
6214 if (PT == Z)
6215 point_at_end = 1;
6216 if (ZV == Z)
6217 zv_at_end = 1;
6218
6219 BEGV = BEG;
6220 BEGV_BYTE = BEG_BYTE;
6221 ZV = Z;
6222 ZV_BYTE = Z_BYTE;
6223 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6224
6225 /* Insert the string--maybe converting multibyte to single byte
6226 or vice versa, so that all the text fits the buffer. */
6227 if (multibyte
6228 && NILP (current_buffer->enable_multibyte_characters))
6229 {
6230 int i, c, char_bytes;
6231 unsigned char work[1];
6232
6233 /* Convert a multibyte string to single-byte
6234 for the *Message* buffer. */
6235 for (i = 0; i < nbytes; i += char_bytes)
6236 {
6237 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6238 work[0] = (SINGLE_BYTE_CHAR_P (c)
6239 ? c
6240 : multibyte_char_to_unibyte (c, Qnil));
6241 insert_1_both (work, 1, 1, 1, 0, 0);
6242 }
6243 }
6244 else if (! multibyte
6245 && ! NILP (current_buffer->enable_multibyte_characters))
6246 {
6247 int i, c, char_bytes;
6248 unsigned char *msg = (unsigned char *) m;
6249 unsigned char str[MAX_MULTIBYTE_LENGTH];
6250 /* Convert a single-byte string to multibyte
6251 for the *Message* buffer. */
6252 for (i = 0; i < nbytes; i++)
6253 {
6254 c = unibyte_char_to_multibyte (msg[i]);
6255 char_bytes = CHAR_STRING (c, str);
6256 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6257 }
6258 }
6259 else if (nbytes)
6260 insert_1 (m, nbytes, 1, 0, 0);
6261
6262 if (nlflag)
6263 {
6264 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6265 insert_1 ("\n", 1, 1, 0, 0);
6266
6267 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6268 this_bol = PT;
6269 this_bol_byte = PT_BYTE;
6270
6271 /* See if this line duplicates the previous one.
6272 If so, combine duplicates. */
6273 if (this_bol > BEG)
6274 {
6275 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6276 prev_bol = PT;
6277 prev_bol_byte = PT_BYTE;
6278
6279 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6280 this_bol, this_bol_byte);
6281 if (dup)
6282 {
6283 del_range_both (prev_bol, prev_bol_byte,
6284 this_bol, this_bol_byte, 0);
6285 if (dup > 1)
6286 {
6287 char dupstr[40];
6288 int duplen;
6289
6290 /* If you change this format, don't forget to also
6291 change message_log_check_duplicate. */
6292 sprintf (dupstr, " [%d times]", dup);
6293 duplen = strlen (dupstr);
6294 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6295 insert_1 (dupstr, duplen, 1, 0, 1);
6296 }
6297 }
6298 }
6299
6300 /* If we have more than the desired maximum number of lines
6301 in the *Messages* buffer now, delete the oldest ones.
6302 This is safe because we don't have undo in this buffer. */
6303
6304 if (NATNUMP (Vmessage_log_max))
6305 {
6306 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6307 -XFASTINT (Vmessage_log_max) - 1, 0);
6308 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6309 }
6310 }
6311 BEGV = XMARKER (oldbegv)->charpos;
6312 BEGV_BYTE = marker_byte_position (oldbegv);
6313
6314 if (zv_at_end)
6315 {
6316 ZV = Z;
6317 ZV_BYTE = Z_BYTE;
6318 }
6319 else
6320 {
6321 ZV = XMARKER (oldzv)->charpos;
6322 ZV_BYTE = marker_byte_position (oldzv);
6323 }
6324
6325 if (point_at_end)
6326 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6327 else
6328 /* We can't do Fgoto_char (oldpoint) because it will run some
6329 Lisp code. */
6330 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6331 XMARKER (oldpoint)->bytepos);
6332
6333 UNGCPRO;
6334 unchain_marker (XMARKER (oldpoint));
6335 unchain_marker (XMARKER (oldbegv));
6336 unchain_marker (XMARKER (oldzv));
6337
6338 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6339 set_buffer_internal (oldbuf);
6340 if (NILP (tem))
6341 windows_or_buffers_changed = old_windows_or_buffers_changed;
6342 message_log_need_newline = !nlflag;
6343 Vdeactivate_mark = old_deactivate_mark;
6344 }
6345 }
6346
6347
6348 /* We are at the end of the buffer after just having inserted a newline.
6349 (Note: We depend on the fact we won't be crossing the gap.)
6350 Check to see if the most recent message looks a lot like the previous one.
6351 Return 0 if different, 1 if the new one should just replace it, or a
6352 value N > 1 if we should also append " [N times]". */
6353
6354 static int
6355 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6356 int prev_bol, this_bol;
6357 int prev_bol_byte, this_bol_byte;
6358 {
6359 int i;
6360 int len = Z_BYTE - 1 - this_bol_byte;
6361 int seen_dots = 0;
6362 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6363 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6364
6365 for (i = 0; i < len; i++)
6366 {
6367 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6368 seen_dots = 1;
6369 if (p1[i] != p2[i])
6370 return seen_dots;
6371 }
6372 p1 += len;
6373 if (*p1 == '\n')
6374 return 2;
6375 if (*p1++ == ' ' && *p1++ == '[')
6376 {
6377 int n = 0;
6378 while (*p1 >= '0' && *p1 <= '9')
6379 n = n * 10 + *p1++ - '0';
6380 if (strncmp (p1, " times]\n", 8) == 0)
6381 return n+1;
6382 }
6383 return 0;
6384 }
6385
6386
6387 /* Display an echo area message M with a specified length of NBYTES
6388 bytes. The string may include null characters. If M is 0, clear
6389 out any existing message, and let the mini-buffer text show
6390 through.
6391
6392 The buffer M must continue to exist until after the echo area gets
6393 cleared or some other message gets displayed there. This means do
6394 not pass text that is stored in a Lisp string; do not pass text in
6395 a buffer that was alloca'd. */
6396
6397 void
6398 message2 (m, nbytes, multibyte)
6399 const char *m;
6400 int nbytes;
6401 int multibyte;
6402 {
6403 /* First flush out any partial line written with print. */
6404 message_log_maybe_newline ();
6405 if (m)
6406 message_dolog (m, nbytes, 1, multibyte);
6407 message2_nolog (m, nbytes, multibyte);
6408 }
6409
6410
6411 /* The non-logging counterpart of message2. */
6412
6413 void
6414 message2_nolog (m, nbytes, multibyte)
6415 const char *m;
6416 int nbytes, multibyte;
6417 {
6418 struct frame *sf = SELECTED_FRAME ();
6419 message_enable_multibyte = multibyte;
6420
6421 if (noninteractive)
6422 {
6423 if (noninteractive_need_newline)
6424 putc ('\n', stderr);
6425 noninteractive_need_newline = 0;
6426 if (m)
6427 fwrite (m, nbytes, 1, stderr);
6428 if (cursor_in_echo_area == 0)
6429 fprintf (stderr, "\n");
6430 fflush (stderr);
6431 }
6432 /* A null message buffer means that the frame hasn't really been
6433 initialized yet. Error messages get reported properly by
6434 cmd_error, so this must be just an informative message; toss it. */
6435 else if (INTERACTIVE
6436 && sf->glyphs_initialized_p
6437 && FRAME_MESSAGE_BUF (sf))
6438 {
6439 Lisp_Object mini_window;
6440 struct frame *f;
6441
6442 /* Get the frame containing the mini-buffer
6443 that the selected frame is using. */
6444 mini_window = FRAME_MINIBUF_WINDOW (sf);
6445 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6446
6447 FRAME_SAMPLE_VISIBILITY (f);
6448 if (FRAME_VISIBLE_P (sf)
6449 && ! FRAME_VISIBLE_P (f))
6450 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6451
6452 if (m)
6453 {
6454 set_message (m, Qnil, nbytes, multibyte);
6455 if (minibuffer_auto_raise)
6456 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6457 }
6458 else
6459 clear_message (1, 1);
6460
6461 do_pending_window_change (0);
6462 echo_area_display (1);
6463 do_pending_window_change (0);
6464 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6465 (*frame_up_to_date_hook) (f);
6466 }
6467 }
6468
6469
6470 /* Display an echo area message M with a specified length of NBYTES
6471 bytes. The string may include null characters. If M is not a
6472 string, clear out any existing message, and let the mini-buffer
6473 text show through. */
6474
6475 void
6476 message3 (m, nbytes, multibyte)
6477 Lisp_Object m;
6478 int nbytes;
6479 int multibyte;
6480 {
6481 struct gcpro gcpro1;
6482
6483 GCPRO1 (m);
6484
6485 /* First flush out any partial line written with print. */
6486 message_log_maybe_newline ();
6487 if (STRINGP (m))
6488 message_dolog (SDATA (m), nbytes, 1, multibyte);
6489 message3_nolog (m, nbytes, multibyte);
6490
6491 UNGCPRO;
6492 }
6493
6494
6495 /* The non-logging version of message3. */
6496
6497 void
6498 message3_nolog (m, nbytes, multibyte)
6499 Lisp_Object m;
6500 int nbytes, multibyte;
6501 {
6502 struct frame *sf = SELECTED_FRAME ();
6503 message_enable_multibyte = multibyte;
6504
6505 if (noninteractive)
6506 {
6507 if (noninteractive_need_newline)
6508 putc ('\n', stderr);
6509 noninteractive_need_newline = 0;
6510 if (STRINGP (m))
6511 fwrite (SDATA (m), nbytes, 1, stderr);
6512 if (cursor_in_echo_area == 0)
6513 fprintf (stderr, "\n");
6514 fflush (stderr);
6515 }
6516 /* A null message buffer means that the frame hasn't really been
6517 initialized yet. Error messages get reported properly by
6518 cmd_error, so this must be just an informative message; toss it. */
6519 else if (INTERACTIVE
6520 && sf->glyphs_initialized_p
6521 && FRAME_MESSAGE_BUF (sf))
6522 {
6523 Lisp_Object mini_window;
6524 Lisp_Object frame;
6525 struct frame *f;
6526
6527 /* Get the frame containing the mini-buffer
6528 that the selected frame is using. */
6529 mini_window = FRAME_MINIBUF_WINDOW (sf);
6530 frame = XWINDOW (mini_window)->frame;
6531 f = XFRAME (frame);
6532
6533 FRAME_SAMPLE_VISIBILITY (f);
6534 if (FRAME_VISIBLE_P (sf)
6535 && !FRAME_VISIBLE_P (f))
6536 Fmake_frame_visible (frame);
6537
6538 if (STRINGP (m) && SCHARS (m) > 0)
6539 {
6540 set_message (NULL, m, nbytes, multibyte);
6541 if (minibuffer_auto_raise)
6542 Fraise_frame (frame);
6543 }
6544 else
6545 clear_message (1, 1);
6546
6547 do_pending_window_change (0);
6548 echo_area_display (1);
6549 do_pending_window_change (0);
6550 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6551 (*frame_up_to_date_hook) (f);
6552 }
6553 }
6554
6555
6556 /* Display a null-terminated echo area message M. If M is 0, clear
6557 out any existing message, and let the mini-buffer text show through.
6558
6559 The buffer M must continue to exist until after the echo area gets
6560 cleared or some other message gets displayed there. Do not pass
6561 text that is stored in a Lisp string. Do not pass text in a buffer
6562 that was alloca'd. */
6563
6564 void
6565 message1 (m)
6566 char *m;
6567 {
6568 message2 (m, (m ? strlen (m) : 0), 0);
6569 }
6570
6571
6572 /* The non-logging counterpart of message1. */
6573
6574 void
6575 message1_nolog (m)
6576 char *m;
6577 {
6578 message2_nolog (m, (m ? strlen (m) : 0), 0);
6579 }
6580
6581 /* Display a message M which contains a single %s
6582 which gets replaced with STRING. */
6583
6584 void
6585 message_with_string (m, string, log)
6586 char *m;
6587 Lisp_Object string;
6588 int log;
6589 {
6590 CHECK_STRING (string);
6591
6592 if (noninteractive)
6593 {
6594 if (m)
6595 {
6596 if (noninteractive_need_newline)
6597 putc ('\n', stderr);
6598 noninteractive_need_newline = 0;
6599 fprintf (stderr, m, SDATA (string));
6600 if (cursor_in_echo_area == 0)
6601 fprintf (stderr, "\n");
6602 fflush (stderr);
6603 }
6604 }
6605 else if (INTERACTIVE)
6606 {
6607 /* The frame whose minibuffer we're going to display the message on.
6608 It may be larger than the selected frame, so we need
6609 to use its buffer, not the selected frame's buffer. */
6610 Lisp_Object mini_window;
6611 struct frame *f, *sf = SELECTED_FRAME ();
6612
6613 /* Get the frame containing the minibuffer
6614 that the selected frame is using. */
6615 mini_window = FRAME_MINIBUF_WINDOW (sf);
6616 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6617
6618 /* A null message buffer means that the frame hasn't really been
6619 initialized yet. Error messages get reported properly by
6620 cmd_error, so this must be just an informative message; toss it. */
6621 if (FRAME_MESSAGE_BUF (f))
6622 {
6623 Lisp_Object args[2], message;
6624 struct gcpro gcpro1, gcpro2;
6625
6626 args[0] = build_string (m);
6627 args[1] = message = string;
6628 GCPRO2 (args[0], message);
6629 gcpro1.nvars = 2;
6630
6631 message = Fformat (2, args);
6632
6633 if (log)
6634 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6635 else
6636 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6637
6638 UNGCPRO;
6639
6640 /* Print should start at the beginning of the message
6641 buffer next time. */
6642 message_buf_print = 0;
6643 }
6644 }
6645 }
6646
6647
6648 /* Dump an informative message to the minibuf. If M is 0, clear out
6649 any existing message, and let the mini-buffer text show through. */
6650
6651 /* VARARGS 1 */
6652 void
6653 message (m, a1, a2, a3)
6654 char *m;
6655 EMACS_INT a1, a2, a3;
6656 {
6657 if (noninteractive)
6658 {
6659 if (m)
6660 {
6661 if (noninteractive_need_newline)
6662 putc ('\n', stderr);
6663 noninteractive_need_newline = 0;
6664 fprintf (stderr, m, a1, a2, a3);
6665 if (cursor_in_echo_area == 0)
6666 fprintf (stderr, "\n");
6667 fflush (stderr);
6668 }
6669 }
6670 else if (INTERACTIVE)
6671 {
6672 /* The frame whose mini-buffer we're going to display the message
6673 on. It may be larger than the selected frame, so we need to
6674 use its buffer, not the selected frame's buffer. */
6675 Lisp_Object mini_window;
6676 struct frame *f, *sf = SELECTED_FRAME ();
6677
6678 /* Get the frame containing the mini-buffer
6679 that the selected frame is using. */
6680 mini_window = FRAME_MINIBUF_WINDOW (sf);
6681 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6682
6683 /* A null message buffer means that the frame hasn't really been
6684 initialized yet. Error messages get reported properly by
6685 cmd_error, so this must be just an informative message; toss
6686 it. */
6687 if (FRAME_MESSAGE_BUF (f))
6688 {
6689 if (m)
6690 {
6691 int len;
6692 #ifdef NO_ARG_ARRAY
6693 char *a[3];
6694 a[0] = (char *) a1;
6695 a[1] = (char *) a2;
6696 a[2] = (char *) a3;
6697
6698 len = doprnt (FRAME_MESSAGE_BUF (f),
6699 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6700 #else
6701 len = doprnt (FRAME_MESSAGE_BUF (f),
6702 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6703 (char **) &a1);
6704 #endif /* NO_ARG_ARRAY */
6705
6706 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6707 }
6708 else
6709 message1 (0);
6710
6711 /* Print should start at the beginning of the message
6712 buffer next time. */
6713 message_buf_print = 0;
6714 }
6715 }
6716 }
6717
6718
6719 /* The non-logging version of message. */
6720
6721 void
6722 message_nolog (m, a1, a2, a3)
6723 char *m;
6724 EMACS_INT a1, a2, a3;
6725 {
6726 Lisp_Object old_log_max;
6727 old_log_max = Vmessage_log_max;
6728 Vmessage_log_max = Qnil;
6729 message (m, a1, a2, a3);
6730 Vmessage_log_max = old_log_max;
6731 }
6732
6733
6734 /* Display the current message in the current mini-buffer. This is
6735 only called from error handlers in process.c, and is not time
6736 critical. */
6737
6738 void
6739 update_echo_area ()
6740 {
6741 if (!NILP (echo_area_buffer[0]))
6742 {
6743 Lisp_Object string;
6744 string = Fcurrent_message ();
6745 message3 (string, SBYTES (string),
6746 !NILP (current_buffer->enable_multibyte_characters));
6747 }
6748 }
6749
6750
6751 /* Make sure echo area buffers in `echo_buffers' are live.
6752 If they aren't, make new ones. */
6753
6754 static void
6755 ensure_echo_area_buffers ()
6756 {
6757 int i;
6758
6759 for (i = 0; i < 2; ++i)
6760 if (!BUFFERP (echo_buffer[i])
6761 || NILP (XBUFFER (echo_buffer[i])->name))
6762 {
6763 char name[30];
6764 Lisp_Object old_buffer;
6765 int j;
6766
6767 old_buffer = echo_buffer[i];
6768 sprintf (name, " *Echo Area %d*", i);
6769 echo_buffer[i] = Fget_buffer_create (build_string (name));
6770 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6771
6772 for (j = 0; j < 2; ++j)
6773 if (EQ (old_buffer, echo_area_buffer[j]))
6774 echo_area_buffer[j] = echo_buffer[i];
6775 }
6776 }
6777
6778
6779 /* Call FN with args A1..A4 with either the current or last displayed
6780 echo_area_buffer as current buffer.
6781
6782 WHICH zero means use the current message buffer
6783 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6784 from echo_buffer[] and clear it.
6785
6786 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6787 suitable buffer from echo_buffer[] and clear it.
6788
6789 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6790 that the current message becomes the last displayed one, make
6791 choose a suitable buffer for echo_area_buffer[0], and clear it.
6792
6793 Value is what FN returns. */
6794
6795 static int
6796 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6797 struct window *w;
6798 int which;
6799 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6800 EMACS_INT a1;
6801 Lisp_Object a2;
6802 EMACS_INT a3, a4;
6803 {
6804 Lisp_Object buffer;
6805 int this_one, the_other, clear_buffer_p, rc;
6806 int count = SPECPDL_INDEX ();
6807
6808 /* If buffers aren't live, make new ones. */
6809 ensure_echo_area_buffers ();
6810
6811 clear_buffer_p = 0;
6812
6813 if (which == 0)
6814 this_one = 0, the_other = 1;
6815 else if (which > 0)
6816 this_one = 1, the_other = 0;
6817 else
6818 {
6819 this_one = 0, the_other = 1;
6820 clear_buffer_p = 1;
6821
6822 /* We need a fresh one in case the current echo buffer equals
6823 the one containing the last displayed echo area message. */
6824 if (!NILP (echo_area_buffer[this_one])
6825 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6826 echo_area_buffer[this_one] = Qnil;
6827 }
6828
6829 /* Choose a suitable buffer from echo_buffer[] is we don't
6830 have one. */
6831 if (NILP (echo_area_buffer[this_one]))
6832 {
6833 echo_area_buffer[this_one]
6834 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
6835 ? echo_buffer[the_other]
6836 : echo_buffer[this_one]);
6837 clear_buffer_p = 1;
6838 }
6839
6840 buffer = echo_area_buffer[this_one];
6841
6842 /* Don't get confused by reusing the buffer used for echoing
6843 for a different purpose. */
6844 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
6845 cancel_echoing ();
6846
6847 record_unwind_protect (unwind_with_echo_area_buffer,
6848 with_echo_area_buffer_unwind_data (w));
6849
6850 /* Make the echo area buffer current. Note that for display
6851 purposes, it is not necessary that the displayed window's buffer
6852 == current_buffer, except for text property lookup. So, let's
6853 only set that buffer temporarily here without doing a full
6854 Fset_window_buffer. We must also change w->pointm, though,
6855 because otherwise an assertions in unshow_buffer fails, and Emacs
6856 aborts. */
6857 set_buffer_internal_1 (XBUFFER (buffer));
6858 if (w)
6859 {
6860 w->buffer = buffer;
6861 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
6862 }
6863
6864 current_buffer->undo_list = Qt;
6865 current_buffer->read_only = Qnil;
6866 specbind (Qinhibit_read_only, Qt);
6867 specbind (Qinhibit_modification_hooks, Qt);
6868
6869 if (clear_buffer_p && Z > BEG)
6870 del_range (BEG, Z);
6871
6872 xassert (BEGV >= BEG);
6873 xassert (ZV <= Z && ZV >= BEGV);
6874
6875 rc = fn (a1, a2, a3, a4);
6876
6877 xassert (BEGV >= BEG);
6878 xassert (ZV <= Z && ZV >= BEGV);
6879
6880 unbind_to (count, Qnil);
6881 return rc;
6882 }
6883
6884
6885 /* Save state that should be preserved around the call to the function
6886 FN called in with_echo_area_buffer. */
6887
6888 static Lisp_Object
6889 with_echo_area_buffer_unwind_data (w)
6890 struct window *w;
6891 {
6892 int i = 0;
6893 Lisp_Object vector;
6894
6895 /* Reduce consing by keeping one vector in
6896 Vwith_echo_area_save_vector. */
6897 vector = Vwith_echo_area_save_vector;
6898 Vwith_echo_area_save_vector = Qnil;
6899
6900 if (NILP (vector))
6901 vector = Fmake_vector (make_number (7), Qnil);
6902
6903 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
6904 AREF (vector, i) = Vdeactivate_mark, ++i;
6905 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
6906
6907 if (w)
6908 {
6909 XSETWINDOW (AREF (vector, i), w); ++i;
6910 AREF (vector, i) = w->buffer; ++i;
6911 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
6912 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
6913 }
6914 else
6915 {
6916 int end = i + 4;
6917 for (; i < end; ++i)
6918 AREF (vector, i) = Qnil;
6919 }
6920
6921 xassert (i == ASIZE (vector));
6922 return vector;
6923 }
6924
6925
6926 /* Restore global state from VECTOR which was created by
6927 with_echo_area_buffer_unwind_data. */
6928
6929 static Lisp_Object
6930 unwind_with_echo_area_buffer (vector)
6931 Lisp_Object vector;
6932 {
6933 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
6934 Vdeactivate_mark = AREF (vector, 1);
6935 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
6936
6937 if (WINDOWP (AREF (vector, 3)))
6938 {
6939 struct window *w;
6940 Lisp_Object buffer, charpos, bytepos;
6941
6942 w = XWINDOW (AREF (vector, 3));
6943 buffer = AREF (vector, 4);
6944 charpos = AREF (vector, 5);
6945 bytepos = AREF (vector, 6);
6946
6947 w->buffer = buffer;
6948 set_marker_both (w->pointm, buffer,
6949 XFASTINT (charpos), XFASTINT (bytepos));
6950 }
6951
6952 Vwith_echo_area_save_vector = vector;
6953 return Qnil;
6954 }
6955
6956
6957 /* Set up the echo area for use by print functions. MULTIBYTE_P
6958 non-zero means we will print multibyte. */
6959
6960 void
6961 setup_echo_area_for_printing (multibyte_p)
6962 int multibyte_p;
6963 {
6964 /* If we can't find an echo area any more, exit. */
6965 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
6966 Fkill_emacs (Qnil);
6967
6968 ensure_echo_area_buffers ();
6969
6970 if (!message_buf_print)
6971 {
6972 /* A message has been output since the last time we printed.
6973 Choose a fresh echo area buffer. */
6974 if (EQ (echo_area_buffer[1], echo_buffer[0]))
6975 echo_area_buffer[0] = echo_buffer[1];
6976 else
6977 echo_area_buffer[0] = echo_buffer[0];
6978
6979 /* Switch to that buffer and clear it. */
6980 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
6981 current_buffer->truncate_lines = Qnil;
6982
6983 if (Z > BEG)
6984 {
6985 int count = SPECPDL_INDEX ();
6986 specbind (Qinhibit_read_only, Qt);
6987 /* Note that undo recording is always disabled. */
6988 del_range (BEG, Z);
6989 unbind_to (count, Qnil);
6990 }
6991 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
6992
6993 /* Set up the buffer for the multibyteness we need. */
6994 if (multibyte_p
6995 != !NILP (current_buffer->enable_multibyte_characters))
6996 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
6997
6998 /* Raise the frame containing the echo area. */
6999 if (minibuffer_auto_raise)
7000 {
7001 struct frame *sf = SELECTED_FRAME ();
7002 Lisp_Object mini_window;
7003 mini_window = FRAME_MINIBUF_WINDOW (sf);
7004 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7005 }
7006
7007 message_log_maybe_newline ();
7008 message_buf_print = 1;
7009 }
7010 else
7011 {
7012 if (NILP (echo_area_buffer[0]))
7013 {
7014 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7015 echo_area_buffer[0] = echo_buffer[1];
7016 else
7017 echo_area_buffer[0] = echo_buffer[0];
7018 }
7019
7020 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7021 {
7022 /* Someone switched buffers between print requests. */
7023 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7024 current_buffer->truncate_lines = Qnil;
7025 }
7026 }
7027 }
7028
7029
7030 /* Display an echo area message in window W. Value is non-zero if W's
7031 height is changed. If display_last_displayed_message_p is
7032 non-zero, display the message that was last displayed, otherwise
7033 display the current message. */
7034
7035 static int
7036 display_echo_area (w)
7037 struct window *w;
7038 {
7039 int i, no_message_p, window_height_changed_p, count;
7040
7041 /* Temporarily disable garbage collections while displaying the echo
7042 area. This is done because a GC can print a message itself.
7043 That message would modify the echo area buffer's contents while a
7044 redisplay of the buffer is going on, and seriously confuse
7045 redisplay. */
7046 count = inhibit_garbage_collection ();
7047
7048 /* If there is no message, we must call display_echo_area_1
7049 nevertheless because it resizes the window. But we will have to
7050 reset the echo_area_buffer in question to nil at the end because
7051 with_echo_area_buffer will sets it to an empty buffer. */
7052 i = display_last_displayed_message_p ? 1 : 0;
7053 no_message_p = NILP (echo_area_buffer[i]);
7054
7055 window_height_changed_p
7056 = with_echo_area_buffer (w, display_last_displayed_message_p,
7057 display_echo_area_1,
7058 (EMACS_INT) w, Qnil, 0, 0);
7059
7060 if (no_message_p)
7061 echo_area_buffer[i] = Qnil;
7062
7063 unbind_to (count, Qnil);
7064 return window_height_changed_p;
7065 }
7066
7067
7068 /* Helper for display_echo_area. Display the current buffer which
7069 contains the current echo area message in window W, a mini-window,
7070 a pointer to which is passed in A1. A2..A4 are currently not used.
7071 Change the height of W so that all of the message is displayed.
7072 Value is non-zero if height of W was changed. */
7073
7074 static int
7075 display_echo_area_1 (a1, a2, a3, a4)
7076 EMACS_INT a1;
7077 Lisp_Object a2;
7078 EMACS_INT a3, a4;
7079 {
7080 struct window *w = (struct window *) a1;
7081 Lisp_Object window;
7082 struct text_pos start;
7083 int window_height_changed_p = 0;
7084
7085 /* Do this before displaying, so that we have a large enough glyph
7086 matrix for the display. */
7087 window_height_changed_p = resize_mini_window (w, 0);
7088
7089 /* Display. */
7090 clear_glyph_matrix (w->desired_matrix);
7091 XSETWINDOW (window, w);
7092 SET_TEXT_POS (start, BEG, BEG_BYTE);
7093 try_window (window, start);
7094
7095 return window_height_changed_p;
7096 }
7097
7098
7099 /* Resize the echo area window to exactly the size needed for the
7100 currently displayed message, if there is one. If a mini-buffer
7101 is active, don't shrink it. */
7102
7103 void
7104 resize_echo_area_exactly ()
7105 {
7106 if (BUFFERP (echo_area_buffer[0])
7107 && WINDOWP (echo_area_window))
7108 {
7109 struct window *w = XWINDOW (echo_area_window);
7110 int resized_p;
7111 Lisp_Object resize_exactly;
7112
7113 if (minibuf_level == 0)
7114 resize_exactly = Qt;
7115 else
7116 resize_exactly = Qnil;
7117
7118 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7119 (EMACS_INT) w, resize_exactly, 0, 0);
7120 if (resized_p)
7121 {
7122 ++windows_or_buffers_changed;
7123 ++update_mode_lines;
7124 redisplay_internal (0);
7125 }
7126 }
7127 }
7128
7129
7130 /* Callback function for with_echo_area_buffer, when used from
7131 resize_echo_area_exactly. A1 contains a pointer to the window to
7132 resize, EXACTLY non-nil means resize the mini-window exactly to the
7133 size of the text displayed. A3 and A4 are not used. Value is what
7134 resize_mini_window returns. */
7135
7136 static int
7137 resize_mini_window_1 (a1, exactly, a3, a4)
7138 EMACS_INT a1;
7139 Lisp_Object exactly;
7140 EMACS_INT a3, a4;
7141 {
7142 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7143 }
7144
7145
7146 /* Resize mini-window W to fit the size of its contents. EXACT:P
7147 means size the window exactly to the size needed. Otherwise, it's
7148 only enlarged until W's buffer is empty. Value is non-zero if
7149 the window height has been changed. */
7150
7151 int
7152 resize_mini_window (w, exact_p)
7153 struct window *w;
7154 int exact_p;
7155 {
7156 struct frame *f = XFRAME (w->frame);
7157 int window_height_changed_p = 0;
7158
7159 xassert (MINI_WINDOW_P (w));
7160
7161 /* Don't resize windows while redisplaying a window; it would
7162 confuse redisplay functions when the size of the window they are
7163 displaying changes from under them. Such a resizing can happen,
7164 for instance, when which-func prints a long message while
7165 we are running fontification-functions. We're running these
7166 functions with safe_call which binds inhibit-redisplay to t. */
7167 if (!NILP (Vinhibit_redisplay))
7168 return 0;
7169
7170 /* Nil means don't try to resize. */
7171 if (NILP (Vresize_mini_windows)
7172 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7173 return 0;
7174
7175 if (!FRAME_MINIBUF_ONLY_P (f))
7176 {
7177 struct it it;
7178 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7179 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7180 int height, max_height;
7181 int unit = FRAME_LINE_HEIGHT (f);
7182 struct text_pos start;
7183 struct buffer *old_current_buffer = NULL;
7184
7185 if (current_buffer != XBUFFER (w->buffer))
7186 {
7187 old_current_buffer = current_buffer;
7188 set_buffer_internal (XBUFFER (w->buffer));
7189 }
7190
7191 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7192
7193 /* Compute the max. number of lines specified by the user. */
7194 if (FLOATP (Vmax_mini_window_height))
7195 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7196 else if (INTEGERP (Vmax_mini_window_height))
7197 max_height = XINT (Vmax_mini_window_height);
7198 else
7199 max_height = total_height / 4;
7200
7201 /* Correct that max. height if it's bogus. */
7202 max_height = max (1, max_height);
7203 max_height = min (total_height, max_height);
7204
7205 /* Find out the height of the text in the window. */
7206 if (it.truncate_lines_p)
7207 height = 1;
7208 else
7209 {
7210 last_height = 0;
7211 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7212 if (it.max_ascent == 0 && it.max_descent == 0)
7213 height = it.current_y + last_height;
7214 else
7215 height = it.current_y + it.max_ascent + it.max_descent;
7216 height -= it.extra_line_spacing;
7217 height = (height + unit - 1) / unit;
7218 }
7219
7220 /* Compute a suitable window start. */
7221 if (height > max_height)
7222 {
7223 height = max_height;
7224 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7225 move_it_vertically_backward (&it, (height - 1) * unit);
7226 start = it.current.pos;
7227 }
7228 else
7229 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7230 SET_MARKER_FROM_TEXT_POS (w->start, start);
7231
7232 if (EQ (Vresize_mini_windows, Qgrow_only))
7233 {
7234 /* Let it grow only, until we display an empty message, in which
7235 case the window shrinks again. */
7236 if (height > WINDOW_TOTAL_LINES (w))
7237 {
7238 int old_height = WINDOW_TOTAL_LINES (w);
7239 freeze_window_starts (f, 1);
7240 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7241 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7242 }
7243 else if (height < WINDOW_TOTAL_LINES (w)
7244 && (exact_p || BEGV == ZV))
7245 {
7246 int old_height = WINDOW_TOTAL_LINES (w);
7247 freeze_window_starts (f, 0);
7248 shrink_mini_window (w);
7249 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7250 }
7251 }
7252 else
7253 {
7254 /* Always resize to exact size needed. */
7255 if (height > WINDOW_TOTAL_LINES (w))
7256 {
7257 int old_height = WINDOW_TOTAL_LINES (w);
7258 freeze_window_starts (f, 1);
7259 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7260 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7261 }
7262 else if (height < WINDOW_TOTAL_LINES (w))
7263 {
7264 int old_height = WINDOW_TOTAL_LINES (w);
7265 freeze_window_starts (f, 0);
7266 shrink_mini_window (w);
7267
7268 if (height)
7269 {
7270 freeze_window_starts (f, 1);
7271 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7272 }
7273
7274 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7275 }
7276 }
7277
7278 if (old_current_buffer)
7279 set_buffer_internal (old_current_buffer);
7280 }
7281
7282 return window_height_changed_p;
7283 }
7284
7285
7286 /* Value is the current message, a string, or nil if there is no
7287 current message. */
7288
7289 Lisp_Object
7290 current_message ()
7291 {
7292 Lisp_Object msg;
7293
7294 if (NILP (echo_area_buffer[0]))
7295 msg = Qnil;
7296 else
7297 {
7298 with_echo_area_buffer (0, 0, current_message_1,
7299 (EMACS_INT) &msg, Qnil, 0, 0);
7300 if (NILP (msg))
7301 echo_area_buffer[0] = Qnil;
7302 }
7303
7304 return msg;
7305 }
7306
7307
7308 static int
7309 current_message_1 (a1, a2, a3, a4)
7310 EMACS_INT a1;
7311 Lisp_Object a2;
7312 EMACS_INT a3, a4;
7313 {
7314 Lisp_Object *msg = (Lisp_Object *) a1;
7315
7316 if (Z > BEG)
7317 *msg = make_buffer_string (BEG, Z, 1);
7318 else
7319 *msg = Qnil;
7320 return 0;
7321 }
7322
7323
7324 /* Push the current message on Vmessage_stack for later restauration
7325 by restore_message. Value is non-zero if the current message isn't
7326 empty. This is a relatively infrequent operation, so it's not
7327 worth optimizing. */
7328
7329 int
7330 push_message ()
7331 {
7332 Lisp_Object msg;
7333 msg = current_message ();
7334 Vmessage_stack = Fcons (msg, Vmessage_stack);
7335 return STRINGP (msg);
7336 }
7337
7338
7339 /* Restore message display from the top of Vmessage_stack. */
7340
7341 void
7342 restore_message ()
7343 {
7344 Lisp_Object msg;
7345
7346 xassert (CONSP (Vmessage_stack));
7347 msg = XCAR (Vmessage_stack);
7348 if (STRINGP (msg))
7349 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7350 else
7351 message3_nolog (msg, 0, 0);
7352 }
7353
7354
7355 /* Handler for record_unwind_protect calling pop_message. */
7356
7357 Lisp_Object
7358 pop_message_unwind (dummy)
7359 Lisp_Object dummy;
7360 {
7361 pop_message ();
7362 return Qnil;
7363 }
7364
7365 /* Pop the top-most entry off Vmessage_stack. */
7366
7367 void
7368 pop_message ()
7369 {
7370 xassert (CONSP (Vmessage_stack));
7371 Vmessage_stack = XCDR (Vmessage_stack);
7372 }
7373
7374
7375 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7376 exits. If the stack is not empty, we have a missing pop_message
7377 somewhere. */
7378
7379 void
7380 check_message_stack ()
7381 {
7382 if (!NILP (Vmessage_stack))
7383 abort ();
7384 }
7385
7386
7387 /* Truncate to NCHARS what will be displayed in the echo area the next
7388 time we display it---but don't redisplay it now. */
7389
7390 void
7391 truncate_echo_area (nchars)
7392 int nchars;
7393 {
7394 if (nchars == 0)
7395 echo_area_buffer[0] = Qnil;
7396 /* A null message buffer means that the frame hasn't really been
7397 initialized yet. Error messages get reported properly by
7398 cmd_error, so this must be just an informative message; toss it. */
7399 else if (!noninteractive
7400 && INTERACTIVE
7401 && !NILP (echo_area_buffer[0]))
7402 {
7403 struct frame *sf = SELECTED_FRAME ();
7404 if (FRAME_MESSAGE_BUF (sf))
7405 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7406 }
7407 }
7408
7409
7410 /* Helper function for truncate_echo_area. Truncate the current
7411 message to at most NCHARS characters. */
7412
7413 static int
7414 truncate_message_1 (nchars, a2, a3, a4)
7415 EMACS_INT nchars;
7416 Lisp_Object a2;
7417 EMACS_INT a3, a4;
7418 {
7419 if (BEG + nchars < Z)
7420 del_range (BEG + nchars, Z);
7421 if (Z == BEG)
7422 echo_area_buffer[0] = Qnil;
7423 return 0;
7424 }
7425
7426
7427 /* Set the current message to a substring of S or STRING.
7428
7429 If STRING is a Lisp string, set the message to the first NBYTES
7430 bytes from STRING. NBYTES zero means use the whole string. If
7431 STRING is multibyte, the message will be displayed multibyte.
7432
7433 If S is not null, set the message to the first LEN bytes of S. LEN
7434 zero means use the whole string. MULTIBYTE_P non-zero means S is
7435 multibyte. Display the message multibyte in that case. */
7436
7437 void
7438 set_message (s, string, nbytes, multibyte_p)
7439 const char *s;
7440 Lisp_Object string;
7441 int nbytes, multibyte_p;
7442 {
7443 message_enable_multibyte
7444 = ((s && multibyte_p)
7445 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7446
7447 with_echo_area_buffer (0, -1, set_message_1,
7448 (EMACS_INT) s, string, nbytes, multibyte_p);
7449 message_buf_print = 0;
7450 help_echo_showing_p = 0;
7451 }
7452
7453
7454 /* Helper function for set_message. Arguments have the same meaning
7455 as there, with A1 corresponding to S and A2 corresponding to STRING
7456 This function is called with the echo area buffer being
7457 current. */
7458
7459 static int
7460 set_message_1 (a1, a2, nbytes, multibyte_p)
7461 EMACS_INT a1;
7462 Lisp_Object a2;
7463 EMACS_INT nbytes, multibyte_p;
7464 {
7465 const char *s = (const char *) a1;
7466 Lisp_Object string = a2;
7467
7468 xassert (BEG == Z);
7469
7470 /* Change multibyteness of the echo buffer appropriately. */
7471 if (message_enable_multibyte
7472 != !NILP (current_buffer->enable_multibyte_characters))
7473 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7474
7475 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7476
7477 /* Insert new message at BEG. */
7478 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7479
7480 if (STRINGP (string))
7481 {
7482 int nchars;
7483
7484 if (nbytes == 0)
7485 nbytes = SBYTES (string);
7486 nchars = string_byte_to_char (string, nbytes);
7487
7488 /* This function takes care of single/multibyte conversion. We
7489 just have to ensure that the echo area buffer has the right
7490 setting of enable_multibyte_characters. */
7491 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7492 }
7493 else if (s)
7494 {
7495 if (nbytes == 0)
7496 nbytes = strlen (s);
7497
7498 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7499 {
7500 /* Convert from multi-byte to single-byte. */
7501 int i, c, n;
7502 unsigned char work[1];
7503
7504 /* Convert a multibyte string to single-byte. */
7505 for (i = 0; i < nbytes; i += n)
7506 {
7507 c = string_char_and_length (s + i, nbytes - i, &n);
7508 work[0] = (SINGLE_BYTE_CHAR_P (c)
7509 ? c
7510 : multibyte_char_to_unibyte (c, Qnil));
7511 insert_1_both (work, 1, 1, 1, 0, 0);
7512 }
7513 }
7514 else if (!multibyte_p
7515 && !NILP (current_buffer->enable_multibyte_characters))
7516 {
7517 /* Convert from single-byte to multi-byte. */
7518 int i, c, n;
7519 const unsigned char *msg = (const unsigned char *) s;
7520 unsigned char str[MAX_MULTIBYTE_LENGTH];
7521
7522 /* Convert a single-byte string to multibyte. */
7523 for (i = 0; i < nbytes; i++)
7524 {
7525 c = unibyte_char_to_multibyte (msg[i]);
7526 n = CHAR_STRING (c, str);
7527 insert_1_both (str, 1, n, 1, 0, 0);
7528 }
7529 }
7530 else
7531 insert_1 (s, nbytes, 1, 0, 0);
7532 }
7533
7534 return 0;
7535 }
7536
7537
7538 /* Clear messages. CURRENT_P non-zero means clear the current
7539 message. LAST_DISPLAYED_P non-zero means clear the message
7540 last displayed. */
7541
7542 void
7543 clear_message (current_p, last_displayed_p)
7544 int current_p, last_displayed_p;
7545 {
7546 if (current_p)
7547 {
7548 echo_area_buffer[0] = Qnil;
7549 message_cleared_p = 1;
7550 }
7551
7552 if (last_displayed_p)
7553 echo_area_buffer[1] = Qnil;
7554
7555 message_buf_print = 0;
7556 }
7557
7558 /* Clear garbaged frames.
7559
7560 This function is used where the old redisplay called
7561 redraw_garbaged_frames which in turn called redraw_frame which in
7562 turn called clear_frame. The call to clear_frame was a source of
7563 flickering. I believe a clear_frame is not necessary. It should
7564 suffice in the new redisplay to invalidate all current matrices,
7565 and ensure a complete redisplay of all windows. */
7566
7567 static void
7568 clear_garbaged_frames ()
7569 {
7570 if (frame_garbaged)
7571 {
7572 Lisp_Object tail, frame;
7573 int changed_count = 0;
7574
7575 FOR_EACH_FRAME (tail, frame)
7576 {
7577 struct frame *f = XFRAME (frame);
7578
7579 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7580 {
7581 if (f->resized_p)
7582 Fredraw_frame (frame);
7583 clear_current_matrices (f);
7584 changed_count++;
7585 f->garbaged = 0;
7586 f->resized_p = 0;
7587 }
7588 }
7589
7590 frame_garbaged = 0;
7591 if (changed_count)
7592 ++windows_or_buffers_changed;
7593 }
7594 }
7595
7596
7597 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7598 is non-zero update selected_frame. Value is non-zero if the
7599 mini-windows height has been changed. */
7600
7601 static int
7602 echo_area_display (update_frame_p)
7603 int update_frame_p;
7604 {
7605 Lisp_Object mini_window;
7606 struct window *w;
7607 struct frame *f;
7608 int window_height_changed_p = 0;
7609 struct frame *sf = SELECTED_FRAME ();
7610
7611 mini_window = FRAME_MINIBUF_WINDOW (sf);
7612 w = XWINDOW (mini_window);
7613 f = XFRAME (WINDOW_FRAME (w));
7614
7615 /* Don't display if frame is invisible or not yet initialized. */
7616 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7617 return 0;
7618
7619 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7620 #ifndef MAC_OS8
7621 #ifdef HAVE_WINDOW_SYSTEM
7622 /* When Emacs starts, selected_frame may be a visible terminal
7623 frame, even if we run under a window system. If we let this
7624 through, a message would be displayed on the terminal. */
7625 if (EQ (selected_frame, Vterminal_frame)
7626 && !NILP (Vwindow_system))
7627 return 0;
7628 #endif /* HAVE_WINDOW_SYSTEM */
7629 #endif
7630
7631 /* Redraw garbaged frames. */
7632 if (frame_garbaged)
7633 clear_garbaged_frames ();
7634
7635 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7636 {
7637 echo_area_window = mini_window;
7638 window_height_changed_p = display_echo_area (w);
7639 w->must_be_updated_p = 1;
7640
7641 /* Update the display, unless called from redisplay_internal.
7642 Also don't update the screen during redisplay itself. The
7643 update will happen at the end of redisplay, and an update
7644 here could cause confusion. */
7645 if (update_frame_p && !redisplaying_p)
7646 {
7647 int n = 0;
7648
7649 /* If the display update has been interrupted by pending
7650 input, update mode lines in the frame. Due to the
7651 pending input, it might have been that redisplay hasn't
7652 been called, so that mode lines above the echo area are
7653 garbaged. This looks odd, so we prevent it here. */
7654 if (!display_completed)
7655 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7656
7657 if (window_height_changed_p
7658 /* Don't do this if Emacs is shutting down. Redisplay
7659 needs to run hooks. */
7660 && !NILP (Vrun_hooks))
7661 {
7662 /* Must update other windows. Likewise as in other
7663 cases, don't let this update be interrupted by
7664 pending input. */
7665 int count = SPECPDL_INDEX ();
7666 specbind (Qredisplay_dont_pause, Qt);
7667 windows_or_buffers_changed = 1;
7668 redisplay_internal (0);
7669 unbind_to (count, Qnil);
7670 }
7671 else if (FRAME_WINDOW_P (f) && n == 0)
7672 {
7673 /* Window configuration is the same as before.
7674 Can do with a display update of the echo area,
7675 unless we displayed some mode lines. */
7676 update_single_window (w, 1);
7677 rif->flush_display (f);
7678 }
7679 else
7680 update_frame (f, 1, 1);
7681
7682 /* If cursor is in the echo area, make sure that the next
7683 redisplay displays the minibuffer, so that the cursor will
7684 be replaced with what the minibuffer wants. */
7685 if (cursor_in_echo_area)
7686 ++windows_or_buffers_changed;
7687 }
7688 }
7689 else if (!EQ (mini_window, selected_window))
7690 windows_or_buffers_changed++;
7691
7692 /* Last displayed message is now the current message. */
7693 echo_area_buffer[1] = echo_area_buffer[0];
7694
7695 /* Prevent redisplay optimization in redisplay_internal by resetting
7696 this_line_start_pos. This is done because the mini-buffer now
7697 displays the message instead of its buffer text. */
7698 if (EQ (mini_window, selected_window))
7699 CHARPOS (this_line_start_pos) = 0;
7700
7701 return window_height_changed_p;
7702 }
7703
7704
7705 \f
7706 /***********************************************************************
7707 Frame Titles
7708 ***********************************************************************/
7709
7710
7711 /* The frame title buffering code is also used by Fformat_mode_line.
7712 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7713
7714 /* A buffer for constructing frame titles in it; allocated from the
7715 heap in init_xdisp and resized as needed in store_frame_title_char. */
7716
7717 static char *frame_title_buf;
7718
7719 /* The buffer's end, and a current output position in it. */
7720
7721 static char *frame_title_buf_end;
7722 static char *frame_title_ptr;
7723
7724
7725 /* Store a single character C for the frame title in frame_title_buf.
7726 Re-allocate frame_title_buf if necessary. */
7727
7728 static void
7729 #ifdef PROTOTYPES
7730 store_frame_title_char (char c)
7731 #else
7732 store_frame_title_char (c)
7733 char c;
7734 #endif
7735 {
7736 /* If output position has reached the end of the allocated buffer,
7737 double the buffer's size. */
7738 if (frame_title_ptr == frame_title_buf_end)
7739 {
7740 int len = frame_title_ptr - frame_title_buf;
7741 int new_size = 2 * len * sizeof *frame_title_buf;
7742 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7743 frame_title_buf_end = frame_title_buf + new_size;
7744 frame_title_ptr = frame_title_buf + len;
7745 }
7746
7747 *frame_title_ptr++ = c;
7748 }
7749
7750
7751 /* Store part of a frame title in frame_title_buf, beginning at
7752 frame_title_ptr. STR is the string to store. Do not copy
7753 characters that yield more columns than PRECISION; PRECISION <= 0
7754 means copy the whole string. Pad with spaces until FIELD_WIDTH
7755 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7756 pad. Called from display_mode_element when it is used to build a
7757 frame title. */
7758
7759 static int
7760 store_frame_title (str, field_width, precision)
7761 const unsigned char *str;
7762 int field_width, precision;
7763 {
7764 int n = 0;
7765 int dummy, nbytes;
7766
7767 /* Copy at most PRECISION chars from STR. */
7768 nbytes = strlen (str);
7769 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7770 while (nbytes--)
7771 store_frame_title_char (*str++);
7772
7773 /* Fill up with spaces until FIELD_WIDTH reached. */
7774 while (field_width > 0
7775 && n < field_width)
7776 {
7777 store_frame_title_char (' ');
7778 ++n;
7779 }
7780
7781 return n;
7782 }
7783
7784 #ifdef HAVE_WINDOW_SYSTEM
7785
7786 /* Set the title of FRAME, if it has changed. The title format is
7787 Vicon_title_format if FRAME is iconified, otherwise it is
7788 frame_title_format. */
7789
7790 static void
7791 x_consider_frame_title (frame)
7792 Lisp_Object frame;
7793 {
7794 struct frame *f = XFRAME (frame);
7795
7796 if (FRAME_WINDOW_P (f)
7797 || FRAME_MINIBUF_ONLY_P (f)
7798 || f->explicit_name)
7799 {
7800 /* Do we have more than one visible frame on this X display? */
7801 Lisp_Object tail;
7802 Lisp_Object fmt;
7803 struct buffer *obuf;
7804 int len;
7805 struct it it;
7806
7807 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7808 {
7809 Lisp_Object other_frame = XCAR (tail);
7810 struct frame *tf = XFRAME (other_frame);
7811
7812 if (tf != f
7813 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
7814 && !FRAME_MINIBUF_ONLY_P (tf)
7815 && !EQ (other_frame, tip_frame)
7816 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
7817 break;
7818 }
7819
7820 /* Set global variable indicating that multiple frames exist. */
7821 multiple_frames = CONSP (tail);
7822
7823 /* Switch to the buffer of selected window of the frame. Set up
7824 frame_title_ptr so that display_mode_element will output into it;
7825 then display the title. */
7826 obuf = current_buffer;
7827 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
7828 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
7829 frame_title_ptr = frame_title_buf;
7830 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
7831 NULL, DEFAULT_FACE_ID);
7832 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
7833 len = frame_title_ptr - frame_title_buf;
7834 frame_title_ptr = NULL;
7835 set_buffer_internal_1 (obuf);
7836
7837 /* Set the title only if it's changed. This avoids consing in
7838 the common case where it hasn't. (If it turns out that we've
7839 already wasted too much time by walking through the list with
7840 display_mode_element, then we might need to optimize at a
7841 higher level than this.) */
7842 if (! STRINGP (f->name)
7843 || SBYTES (f->name) != len
7844 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
7845 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
7846 }
7847 }
7848
7849 #endif /* not HAVE_WINDOW_SYSTEM */
7850
7851
7852
7853 \f
7854 /***********************************************************************
7855 Menu Bars
7856 ***********************************************************************/
7857
7858
7859 /* Prepare for redisplay by updating menu-bar item lists when
7860 appropriate. This can call eval. */
7861
7862 void
7863 prepare_menu_bars ()
7864 {
7865 int all_windows;
7866 struct gcpro gcpro1, gcpro2;
7867 struct frame *f;
7868 Lisp_Object tooltip_frame;
7869
7870 #ifdef HAVE_WINDOW_SYSTEM
7871 tooltip_frame = tip_frame;
7872 #else
7873 tooltip_frame = Qnil;
7874 #endif
7875
7876 /* Update all frame titles based on their buffer names, etc. We do
7877 this before the menu bars so that the buffer-menu will show the
7878 up-to-date frame titles. */
7879 #ifdef HAVE_WINDOW_SYSTEM
7880 if (windows_or_buffers_changed || update_mode_lines)
7881 {
7882 Lisp_Object tail, frame;
7883
7884 FOR_EACH_FRAME (tail, frame)
7885 {
7886 f = XFRAME (frame);
7887 if (!EQ (frame, tooltip_frame)
7888 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
7889 x_consider_frame_title (frame);
7890 }
7891 }
7892 #endif /* HAVE_WINDOW_SYSTEM */
7893
7894 /* Update the menu bar item lists, if appropriate. This has to be
7895 done before any actual redisplay or generation of display lines. */
7896 all_windows = (update_mode_lines
7897 || buffer_shared > 1
7898 || windows_or_buffers_changed);
7899 if (all_windows)
7900 {
7901 Lisp_Object tail, frame;
7902 int count = SPECPDL_INDEX ();
7903
7904 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
7905
7906 FOR_EACH_FRAME (tail, frame)
7907 {
7908 f = XFRAME (frame);
7909
7910 /* Ignore tooltip frame. */
7911 if (EQ (frame, tooltip_frame))
7912 continue;
7913
7914 /* If a window on this frame changed size, report that to
7915 the user and clear the size-change flag. */
7916 if (FRAME_WINDOW_SIZES_CHANGED (f))
7917 {
7918 Lisp_Object functions;
7919
7920 /* Clear flag first in case we get an error below. */
7921 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
7922 functions = Vwindow_size_change_functions;
7923 GCPRO2 (tail, functions);
7924
7925 while (CONSP (functions))
7926 {
7927 call1 (XCAR (functions), frame);
7928 functions = XCDR (functions);
7929 }
7930 UNGCPRO;
7931 }
7932
7933 GCPRO1 (tail);
7934 update_menu_bar (f, 0);
7935 #ifdef HAVE_WINDOW_SYSTEM
7936 update_tool_bar (f, 0);
7937 #endif
7938 UNGCPRO;
7939 }
7940
7941 unbind_to (count, Qnil);
7942 }
7943 else
7944 {
7945 struct frame *sf = SELECTED_FRAME ();
7946 update_menu_bar (sf, 1);
7947 #ifdef HAVE_WINDOW_SYSTEM
7948 update_tool_bar (sf, 1);
7949 #endif
7950 }
7951
7952 /* Motif needs this. See comment in xmenu.c. Turn it off when
7953 pending_menu_activation is not defined. */
7954 #ifdef USE_X_TOOLKIT
7955 pending_menu_activation = 0;
7956 #endif
7957 }
7958
7959
7960 /* Update the menu bar item list for frame F. This has to be done
7961 before we start to fill in any display lines, because it can call
7962 eval.
7963
7964 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
7965
7966 static void
7967 update_menu_bar (f, save_match_data)
7968 struct frame *f;
7969 int save_match_data;
7970 {
7971 Lisp_Object window;
7972 register struct window *w;
7973
7974 /* If called recursively during a menu update, do nothing. This can
7975 happen when, for instance, an activate-menubar-hook causes a
7976 redisplay. */
7977 if (inhibit_menubar_update)
7978 return;
7979
7980 window = FRAME_SELECTED_WINDOW (f);
7981 w = XWINDOW (window);
7982
7983 #if 0 /* The if statement below this if statement used to include the
7984 condition !NILP (w->update_mode_line), rather than using
7985 update_mode_lines directly, and this if statement may have
7986 been added to make that condition work. Now the if
7987 statement below matches its comment, this isn't needed. */
7988 if (update_mode_lines)
7989 w->update_mode_line = Qt;
7990 #endif
7991
7992 if (FRAME_WINDOW_P (f)
7993 ?
7994 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
7995 || defined (USE_GTK)
7996 FRAME_EXTERNAL_MENU_BAR (f)
7997 #else
7998 FRAME_MENU_BAR_LINES (f) > 0
7999 #endif
8000 : FRAME_MENU_BAR_LINES (f) > 0)
8001 {
8002 /* If the user has switched buffers or windows, we need to
8003 recompute to reflect the new bindings. But we'll
8004 recompute when update_mode_lines is set too; that means
8005 that people can use force-mode-line-update to request
8006 that the menu bar be recomputed. The adverse effect on
8007 the rest of the redisplay algorithm is about the same as
8008 windows_or_buffers_changed anyway. */
8009 if (windows_or_buffers_changed
8010 /* This used to test w->update_mode_line, but we believe
8011 there is no need to recompute the menu in that case. */
8012 || update_mode_lines
8013 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8014 < BUF_MODIFF (XBUFFER (w->buffer)))
8015 != !NILP (w->last_had_star))
8016 || ((!NILP (Vtransient_mark_mode)
8017 && !NILP (XBUFFER (w->buffer)->mark_active))
8018 != !NILP (w->region_showing)))
8019 {
8020 struct buffer *prev = current_buffer;
8021 int count = SPECPDL_INDEX ();
8022
8023 specbind (Qinhibit_menubar_update, Qt);
8024
8025 set_buffer_internal_1 (XBUFFER (w->buffer));
8026 if (save_match_data)
8027 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8028 if (NILP (Voverriding_local_map_menu_flag))
8029 {
8030 specbind (Qoverriding_terminal_local_map, Qnil);
8031 specbind (Qoverriding_local_map, Qnil);
8032 }
8033
8034 /* Run the Lucid hook. */
8035 safe_run_hooks (Qactivate_menubar_hook);
8036
8037 /* If it has changed current-menubar from previous value,
8038 really recompute the menu-bar from the value. */
8039 if (! NILP (Vlucid_menu_bar_dirty_flag))
8040 call0 (Qrecompute_lucid_menubar);
8041
8042 safe_run_hooks (Qmenu_bar_update_hook);
8043 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8044
8045 /* Redisplay the menu bar in case we changed it. */
8046 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8047 || defined (USE_GTK)
8048 if (FRAME_WINDOW_P (f)
8049 #if defined (MAC_OS)
8050 /* All frames on Mac OS share the same menubar. So only the
8051 selected frame should be allowed to set it. */
8052 && f == SELECTED_FRAME ()
8053 #endif
8054 )
8055 set_frame_menubar (f, 0, 0);
8056 else
8057 /* On a terminal screen, the menu bar is an ordinary screen
8058 line, and this makes it get updated. */
8059 w->update_mode_line = Qt;
8060 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8061 /* In the non-toolkit version, the menu bar is an ordinary screen
8062 line, and this makes it get updated. */
8063 w->update_mode_line = Qt;
8064 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8065
8066 unbind_to (count, Qnil);
8067 set_buffer_internal_1 (prev);
8068 }
8069 }
8070 }
8071
8072
8073 \f
8074 /***********************************************************************
8075 Output Cursor
8076 ***********************************************************************/
8077
8078 #ifdef HAVE_WINDOW_SYSTEM
8079
8080 /* EXPORT:
8081 Nominal cursor position -- where to draw output.
8082 HPOS and VPOS are window relative glyph matrix coordinates.
8083 X and Y are window relative pixel coordinates. */
8084
8085 struct cursor_pos output_cursor;
8086
8087
8088 /* EXPORT:
8089 Set the global variable output_cursor to CURSOR. All cursor
8090 positions are relative to updated_window. */
8091
8092 void
8093 set_output_cursor (cursor)
8094 struct cursor_pos *cursor;
8095 {
8096 output_cursor.hpos = cursor->hpos;
8097 output_cursor.vpos = cursor->vpos;
8098 output_cursor.x = cursor->x;
8099 output_cursor.y = cursor->y;
8100 }
8101
8102
8103 /* EXPORT for RIF:
8104 Set a nominal cursor position.
8105
8106 HPOS and VPOS are column/row positions in a window glyph matrix. X
8107 and Y are window text area relative pixel positions.
8108
8109 If this is done during an update, updated_window will contain the
8110 window that is being updated and the position is the future output
8111 cursor position for that window. If updated_window is null, use
8112 selected_window and display the cursor at the given position. */
8113
8114 void
8115 x_cursor_to (vpos, hpos, y, x)
8116 int vpos, hpos, y, x;
8117 {
8118 struct window *w;
8119
8120 /* If updated_window is not set, work on selected_window. */
8121 if (updated_window)
8122 w = updated_window;
8123 else
8124 w = XWINDOW (selected_window);
8125
8126 /* Set the output cursor. */
8127 output_cursor.hpos = hpos;
8128 output_cursor.vpos = vpos;
8129 output_cursor.x = x;
8130 output_cursor.y = y;
8131
8132 /* If not called as part of an update, really display the cursor.
8133 This will also set the cursor position of W. */
8134 if (updated_window == NULL)
8135 {
8136 BLOCK_INPUT;
8137 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8138 if (rif->flush_display_optional)
8139 rif->flush_display_optional (SELECTED_FRAME ());
8140 UNBLOCK_INPUT;
8141 }
8142 }
8143
8144 #endif /* HAVE_WINDOW_SYSTEM */
8145
8146 \f
8147 /***********************************************************************
8148 Tool-bars
8149 ***********************************************************************/
8150
8151 #ifdef HAVE_WINDOW_SYSTEM
8152
8153 /* Where the mouse was last time we reported a mouse event. */
8154
8155 FRAME_PTR last_mouse_frame;
8156
8157 /* Tool-bar item index of the item on which a mouse button was pressed
8158 or -1. */
8159
8160 int last_tool_bar_item;
8161
8162
8163 /* Update the tool-bar item list for frame F. This has to be done
8164 before we start to fill in any display lines. Called from
8165 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8166 and restore it here. */
8167
8168 static void
8169 update_tool_bar (f, save_match_data)
8170 struct frame *f;
8171 int save_match_data;
8172 {
8173 #ifdef USE_GTK
8174 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8175 #else
8176 int do_update = WINDOWP (f->tool_bar_window)
8177 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8178 #endif
8179
8180 if (do_update)
8181 {
8182 Lisp_Object window;
8183 struct window *w;
8184
8185 window = FRAME_SELECTED_WINDOW (f);
8186 w = XWINDOW (window);
8187
8188 /* If the user has switched buffers or windows, we need to
8189 recompute to reflect the new bindings. But we'll
8190 recompute when update_mode_lines is set too; that means
8191 that people can use force-mode-line-update to request
8192 that the menu bar be recomputed. The adverse effect on
8193 the rest of the redisplay algorithm is about the same as
8194 windows_or_buffers_changed anyway. */
8195 if (windows_or_buffers_changed
8196 || !NILP (w->update_mode_line)
8197 || update_mode_lines
8198 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8199 < BUF_MODIFF (XBUFFER (w->buffer)))
8200 != !NILP (w->last_had_star))
8201 || ((!NILP (Vtransient_mark_mode)
8202 && !NILP (XBUFFER (w->buffer)->mark_active))
8203 != !NILP (w->region_showing)))
8204 {
8205 struct buffer *prev = current_buffer;
8206 int count = SPECPDL_INDEX ();
8207 Lisp_Object old_tool_bar;
8208 struct gcpro gcpro1;
8209
8210 /* Set current_buffer to the buffer of the selected
8211 window of the frame, so that we get the right local
8212 keymaps. */
8213 set_buffer_internal_1 (XBUFFER (w->buffer));
8214
8215 /* Save match data, if we must. */
8216 if (save_match_data)
8217 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8218
8219 /* Make sure that we don't accidentally use bogus keymaps. */
8220 if (NILP (Voverriding_local_map_menu_flag))
8221 {
8222 specbind (Qoverriding_terminal_local_map, Qnil);
8223 specbind (Qoverriding_local_map, Qnil);
8224 }
8225
8226 old_tool_bar = f->tool_bar_items;
8227 GCPRO1 (old_tool_bar);
8228
8229 /* Build desired tool-bar items from keymaps. */
8230 BLOCK_INPUT;
8231 f->tool_bar_items
8232 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8233 UNBLOCK_INPUT;
8234
8235 /* Redisplay the tool-bar if we changed it. */
8236 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8237 w->update_mode_line = Qt;
8238
8239 UNGCPRO;
8240
8241 unbind_to (count, Qnil);
8242 set_buffer_internal_1 (prev);
8243 }
8244 }
8245 }
8246
8247
8248 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8249 F's desired tool-bar contents. F->tool_bar_items must have
8250 been set up previously by calling prepare_menu_bars. */
8251
8252 static void
8253 build_desired_tool_bar_string (f)
8254 struct frame *f;
8255 {
8256 int i, size, size_needed;
8257 struct gcpro gcpro1, gcpro2, gcpro3;
8258 Lisp_Object image, plist, props;
8259
8260 image = plist = props = Qnil;
8261 GCPRO3 (image, plist, props);
8262
8263 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8264 Otherwise, make a new string. */
8265
8266 /* The size of the string we might be able to reuse. */
8267 size = (STRINGP (f->desired_tool_bar_string)
8268 ? SCHARS (f->desired_tool_bar_string)
8269 : 0);
8270
8271 /* We need one space in the string for each image. */
8272 size_needed = f->n_tool_bar_items;
8273
8274 /* Reuse f->desired_tool_bar_string, if possible. */
8275 if (size < size_needed || NILP (f->desired_tool_bar_string))
8276 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8277 make_number (' '));
8278 else
8279 {
8280 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8281 Fremove_text_properties (make_number (0), make_number (size),
8282 props, f->desired_tool_bar_string);
8283 }
8284
8285 /* Put a `display' property on the string for the images to display,
8286 put a `menu_item' property on tool-bar items with a value that
8287 is the index of the item in F's tool-bar item vector. */
8288 for (i = 0; i < f->n_tool_bar_items; ++i)
8289 {
8290 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8291
8292 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8293 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8294 int hmargin, vmargin, relief, idx, end;
8295 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8296
8297 /* If image is a vector, choose the image according to the
8298 button state. */
8299 image = PROP (TOOL_BAR_ITEM_IMAGES);
8300 if (VECTORP (image))
8301 {
8302 if (enabled_p)
8303 idx = (selected_p
8304 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8305 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8306 else
8307 idx = (selected_p
8308 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8309 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8310
8311 xassert (ASIZE (image) >= idx);
8312 image = AREF (image, idx);
8313 }
8314 else
8315 idx = -1;
8316
8317 /* Ignore invalid image specifications. */
8318 if (!valid_image_p (image))
8319 continue;
8320
8321 /* Display the tool-bar button pressed, or depressed. */
8322 plist = Fcopy_sequence (XCDR (image));
8323
8324 /* Compute margin and relief to draw. */
8325 relief = (tool_bar_button_relief >= 0
8326 ? tool_bar_button_relief
8327 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8328 hmargin = vmargin = relief;
8329
8330 if (INTEGERP (Vtool_bar_button_margin)
8331 && XINT (Vtool_bar_button_margin) > 0)
8332 {
8333 hmargin += XFASTINT (Vtool_bar_button_margin);
8334 vmargin += XFASTINT (Vtool_bar_button_margin);
8335 }
8336 else if (CONSP (Vtool_bar_button_margin))
8337 {
8338 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8339 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8340 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8341
8342 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8343 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8344 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8345 }
8346
8347 if (auto_raise_tool_bar_buttons_p)
8348 {
8349 /* Add a `:relief' property to the image spec if the item is
8350 selected. */
8351 if (selected_p)
8352 {
8353 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8354 hmargin -= relief;
8355 vmargin -= relief;
8356 }
8357 }
8358 else
8359 {
8360 /* If image is selected, display it pressed, i.e. with a
8361 negative relief. If it's not selected, display it with a
8362 raised relief. */
8363 plist = Fplist_put (plist, QCrelief,
8364 (selected_p
8365 ? make_number (-relief)
8366 : make_number (relief)));
8367 hmargin -= relief;
8368 vmargin -= relief;
8369 }
8370
8371 /* Put a margin around the image. */
8372 if (hmargin || vmargin)
8373 {
8374 if (hmargin == vmargin)
8375 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8376 else
8377 plist = Fplist_put (plist, QCmargin,
8378 Fcons (make_number (hmargin),
8379 make_number (vmargin)));
8380 }
8381
8382 /* If button is not enabled, and we don't have special images
8383 for the disabled state, make the image appear disabled by
8384 applying an appropriate algorithm to it. */
8385 if (!enabled_p && idx < 0)
8386 plist = Fplist_put (plist, QCconversion, Qdisabled);
8387
8388 /* Put a `display' text property on the string for the image to
8389 display. Put a `menu-item' property on the string that gives
8390 the start of this item's properties in the tool-bar items
8391 vector. */
8392 image = Fcons (Qimage, plist);
8393 props = list4 (Qdisplay, image,
8394 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8395
8396 /* Let the last image hide all remaining spaces in the tool bar
8397 string. The string can be longer than needed when we reuse a
8398 previous string. */
8399 if (i + 1 == f->n_tool_bar_items)
8400 end = SCHARS (f->desired_tool_bar_string);
8401 else
8402 end = i + 1;
8403 Fadd_text_properties (make_number (i), make_number (end),
8404 props, f->desired_tool_bar_string);
8405 #undef PROP
8406 }
8407
8408 UNGCPRO;
8409 }
8410
8411
8412 /* Display one line of the tool-bar of frame IT->f. */
8413
8414 static void
8415 display_tool_bar_line (it)
8416 struct it *it;
8417 {
8418 struct glyph_row *row = it->glyph_row;
8419 int max_x = it->last_visible_x;
8420 struct glyph *last;
8421
8422 prepare_desired_row (row);
8423 row->y = it->current_y;
8424
8425 /* Note that this isn't made use of if the face hasn't a box,
8426 so there's no need to check the face here. */
8427 it->start_of_box_run_p = 1;
8428
8429 while (it->current_x < max_x)
8430 {
8431 int x_before, x, n_glyphs_before, i, nglyphs;
8432
8433 /* Get the next display element. */
8434 if (!get_next_display_element (it))
8435 break;
8436
8437 /* Produce glyphs. */
8438 x_before = it->current_x;
8439 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8440 PRODUCE_GLYPHS (it);
8441
8442 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8443 i = 0;
8444 x = x_before;
8445 while (i < nglyphs)
8446 {
8447 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8448
8449 if (x + glyph->pixel_width > max_x)
8450 {
8451 /* Glyph doesn't fit on line. */
8452 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8453 it->current_x = x;
8454 goto out;
8455 }
8456
8457 ++it->hpos;
8458 x += glyph->pixel_width;
8459 ++i;
8460 }
8461
8462 /* Stop at line ends. */
8463 if (ITERATOR_AT_END_OF_LINE_P (it))
8464 break;
8465
8466 set_iterator_to_next (it, 1);
8467 }
8468
8469 out:;
8470
8471 row->displays_text_p = row->used[TEXT_AREA] != 0;
8472 extend_face_to_end_of_line (it);
8473 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8474 last->right_box_line_p = 1;
8475 if (last == row->glyphs[TEXT_AREA])
8476 last->left_box_line_p = 1;
8477 compute_line_metrics (it);
8478
8479 /* If line is empty, make it occupy the rest of the tool-bar. */
8480 if (!row->displays_text_p)
8481 {
8482 row->height = row->phys_height = it->last_visible_y - row->y;
8483 row->ascent = row->phys_ascent = 0;
8484 }
8485
8486 row->full_width_p = 1;
8487 row->continued_p = 0;
8488 row->truncated_on_left_p = 0;
8489 row->truncated_on_right_p = 0;
8490
8491 it->current_x = it->hpos = 0;
8492 it->current_y += row->height;
8493 ++it->vpos;
8494 ++it->glyph_row;
8495 }
8496
8497
8498 /* Value is the number of screen lines needed to make all tool-bar
8499 items of frame F visible. */
8500
8501 static int
8502 tool_bar_lines_needed (f)
8503 struct frame *f;
8504 {
8505 struct window *w = XWINDOW (f->tool_bar_window);
8506 struct it it;
8507
8508 /* Initialize an iterator for iteration over
8509 F->desired_tool_bar_string in the tool-bar window of frame F. */
8510 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8511 it.first_visible_x = 0;
8512 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8513 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8514
8515 while (!ITERATOR_AT_END_P (&it))
8516 {
8517 it.glyph_row = w->desired_matrix->rows;
8518 clear_glyph_row (it.glyph_row);
8519 display_tool_bar_line (&it);
8520 }
8521
8522 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8523 }
8524
8525
8526 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8527 0, 1, 0,
8528 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8529 (frame)
8530 Lisp_Object frame;
8531 {
8532 struct frame *f;
8533 struct window *w;
8534 int nlines = 0;
8535
8536 if (NILP (frame))
8537 frame = selected_frame;
8538 else
8539 CHECK_FRAME (frame);
8540 f = XFRAME (frame);
8541
8542 if (WINDOWP (f->tool_bar_window)
8543 || (w = XWINDOW (f->tool_bar_window),
8544 WINDOW_TOTAL_LINES (w) > 0))
8545 {
8546 update_tool_bar (f, 1);
8547 if (f->n_tool_bar_items)
8548 {
8549 build_desired_tool_bar_string (f);
8550 nlines = tool_bar_lines_needed (f);
8551 }
8552 }
8553
8554 return make_number (nlines);
8555 }
8556
8557
8558 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8559 height should be changed. */
8560
8561 static int
8562 redisplay_tool_bar (f)
8563 struct frame *f;
8564 {
8565 struct window *w;
8566 struct it it;
8567 struct glyph_row *row;
8568 int change_height_p = 0;
8569
8570 #ifdef USE_GTK
8571 if (FRAME_EXTERNAL_TOOL_BAR (f))
8572 update_frame_tool_bar (f);
8573 return 0;
8574 #endif
8575
8576 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8577 do anything. This means you must start with tool-bar-lines
8578 non-zero to get the auto-sizing effect. Or in other words, you
8579 can turn off tool-bars by specifying tool-bar-lines zero. */
8580 if (!WINDOWP (f->tool_bar_window)
8581 || (w = XWINDOW (f->tool_bar_window),
8582 WINDOW_TOTAL_LINES (w) == 0))
8583 return 0;
8584
8585 /* Set up an iterator for the tool-bar window. */
8586 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8587 it.first_visible_x = 0;
8588 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8589 row = it.glyph_row;
8590
8591 /* Build a string that represents the contents of the tool-bar. */
8592 build_desired_tool_bar_string (f);
8593 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8594
8595 /* Display as many lines as needed to display all tool-bar items. */
8596 while (it.current_y < it.last_visible_y)
8597 display_tool_bar_line (&it);
8598
8599 /* It doesn't make much sense to try scrolling in the tool-bar
8600 window, so don't do it. */
8601 w->desired_matrix->no_scrolling_p = 1;
8602 w->must_be_updated_p = 1;
8603
8604 if (auto_resize_tool_bars_p)
8605 {
8606 int nlines;
8607
8608 /* If we couldn't display everything, change the tool-bar's
8609 height. */
8610 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8611 change_height_p = 1;
8612
8613 /* If there are blank lines at the end, except for a partially
8614 visible blank line at the end that is smaller than
8615 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8616 row = it.glyph_row - 1;
8617 if (!row->displays_text_p
8618 && row->height >= FRAME_LINE_HEIGHT (f))
8619 change_height_p = 1;
8620
8621 /* If row displays tool-bar items, but is partially visible,
8622 change the tool-bar's height. */
8623 if (row->displays_text_p
8624 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8625 change_height_p = 1;
8626
8627 /* Resize windows as needed by changing the `tool-bar-lines'
8628 frame parameter. */
8629 if (change_height_p
8630 && (nlines = tool_bar_lines_needed (f),
8631 nlines != WINDOW_TOTAL_LINES (w)))
8632 {
8633 extern Lisp_Object Qtool_bar_lines;
8634 Lisp_Object frame;
8635 int old_height = WINDOW_TOTAL_LINES (w);
8636
8637 XSETFRAME (frame, f);
8638 clear_glyph_matrix (w->desired_matrix);
8639 Fmodify_frame_parameters (frame,
8640 Fcons (Fcons (Qtool_bar_lines,
8641 make_number (nlines)),
8642 Qnil));
8643 if (WINDOW_TOTAL_LINES (w) != old_height)
8644 fonts_changed_p = 1;
8645 }
8646 }
8647
8648 return change_height_p;
8649 }
8650
8651
8652 /* Get information about the tool-bar item which is displayed in GLYPH
8653 on frame F. Return in *PROP_IDX the index where tool-bar item
8654 properties start in F->tool_bar_items. Value is zero if
8655 GLYPH doesn't display a tool-bar item. */
8656
8657 static int
8658 tool_bar_item_info (f, glyph, prop_idx)
8659 struct frame *f;
8660 struct glyph *glyph;
8661 int *prop_idx;
8662 {
8663 Lisp_Object prop;
8664 int success_p;
8665 int charpos;
8666
8667 /* This function can be called asynchronously, which means we must
8668 exclude any possibility that Fget_text_property signals an
8669 error. */
8670 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8671 charpos = max (0, charpos);
8672
8673 /* Get the text property `menu-item' at pos. The value of that
8674 property is the start index of this item's properties in
8675 F->tool_bar_items. */
8676 prop = Fget_text_property (make_number (charpos),
8677 Qmenu_item, f->current_tool_bar_string);
8678 if (INTEGERP (prop))
8679 {
8680 *prop_idx = XINT (prop);
8681 success_p = 1;
8682 }
8683 else
8684 success_p = 0;
8685
8686 return success_p;
8687 }
8688
8689 \f
8690 /* Get information about the tool-bar item at position X/Y on frame F.
8691 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8692 the current matrix of the tool-bar window of F, or NULL if not
8693 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8694 item in F->tool_bar_items. Value is
8695
8696 -1 if X/Y is not on a tool-bar item
8697 0 if X/Y is on the same item that was highlighted before.
8698 1 otherwise. */
8699
8700 static int
8701 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8702 struct frame *f;
8703 int x, y;
8704 struct glyph **glyph;
8705 int *hpos, *vpos, *prop_idx;
8706 {
8707 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8708 struct window *w = XWINDOW (f->tool_bar_window);
8709 int area;
8710
8711 /* Find the glyph under X/Y. */
8712 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8713 if (*glyph == NULL)
8714 return -1;
8715
8716 /* Get the start of this tool-bar item's properties in
8717 f->tool_bar_items. */
8718 if (!tool_bar_item_info (f, *glyph, prop_idx))
8719 return -1;
8720
8721 /* Is mouse on the highlighted item? */
8722 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8723 && *vpos >= dpyinfo->mouse_face_beg_row
8724 && *vpos <= dpyinfo->mouse_face_end_row
8725 && (*vpos > dpyinfo->mouse_face_beg_row
8726 || *hpos >= dpyinfo->mouse_face_beg_col)
8727 && (*vpos < dpyinfo->mouse_face_end_row
8728 || *hpos < dpyinfo->mouse_face_end_col
8729 || dpyinfo->mouse_face_past_end))
8730 return 0;
8731
8732 return 1;
8733 }
8734
8735
8736 /* EXPORT:
8737 Handle mouse button event on the tool-bar of frame F, at
8738 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8739 0 for button release. MODIFIERS is event modifiers for button
8740 release. */
8741
8742 void
8743 handle_tool_bar_click (f, x, y, down_p, modifiers)
8744 struct frame *f;
8745 int x, y, down_p;
8746 unsigned int modifiers;
8747 {
8748 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8749 struct window *w = XWINDOW (f->tool_bar_window);
8750 int hpos, vpos, prop_idx;
8751 struct glyph *glyph;
8752 Lisp_Object enabled_p;
8753
8754 /* If not on the highlighted tool-bar item, return. */
8755 frame_to_window_pixel_xy (w, &x, &y);
8756 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8757 return;
8758
8759 /* If item is disabled, do nothing. */
8760 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8761 if (NILP (enabled_p))
8762 return;
8763
8764 if (down_p)
8765 {
8766 /* Show item in pressed state. */
8767 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8768 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8769 last_tool_bar_item = prop_idx;
8770 }
8771 else
8772 {
8773 Lisp_Object key, frame;
8774 struct input_event event;
8775 EVENT_INIT (event);
8776
8777 /* Show item in released state. */
8778 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8779 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8780
8781 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8782
8783 XSETFRAME (frame, f);
8784 event.kind = TOOL_BAR_EVENT;
8785 event.frame_or_window = frame;
8786 event.arg = frame;
8787 kbd_buffer_store_event (&event);
8788
8789 event.kind = TOOL_BAR_EVENT;
8790 event.frame_or_window = frame;
8791 event.arg = key;
8792 event.modifiers = modifiers;
8793 kbd_buffer_store_event (&event);
8794 last_tool_bar_item = -1;
8795 }
8796 }
8797
8798
8799 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8800 tool-bar window-relative coordinates X/Y. Called from
8801 note_mouse_highlight. */
8802
8803 static void
8804 note_tool_bar_highlight (f, x, y)
8805 struct frame *f;
8806 int x, y;
8807 {
8808 Lisp_Object window = f->tool_bar_window;
8809 struct window *w = XWINDOW (window);
8810 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8811 int hpos, vpos;
8812 struct glyph *glyph;
8813 struct glyph_row *row;
8814 int i;
8815 Lisp_Object enabled_p;
8816 int prop_idx;
8817 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8818 int mouse_down_p, rc;
8819
8820 /* Function note_mouse_highlight is called with negative x(y
8821 values when mouse moves outside of the frame. */
8822 if (x <= 0 || y <= 0)
8823 {
8824 clear_mouse_face (dpyinfo);
8825 return;
8826 }
8827
8828 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
8829 if (rc < 0)
8830 {
8831 /* Not on tool-bar item. */
8832 clear_mouse_face (dpyinfo);
8833 return;
8834 }
8835 else if (rc == 0)
8836 /* On same tool-bar item as before. */
8837 goto set_help_echo;
8838
8839 clear_mouse_face (dpyinfo);
8840
8841 /* Mouse is down, but on different tool-bar item? */
8842 mouse_down_p = (dpyinfo->grabbed
8843 && f == last_mouse_frame
8844 && FRAME_LIVE_P (f));
8845 if (mouse_down_p
8846 && last_tool_bar_item != prop_idx)
8847 return;
8848
8849 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
8850 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
8851
8852 /* If tool-bar item is not enabled, don't highlight it. */
8853 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8854 if (!NILP (enabled_p))
8855 {
8856 /* Compute the x-position of the glyph. In front and past the
8857 image is a space. We include this in the highlighted area. */
8858 row = MATRIX_ROW (w->current_matrix, vpos);
8859 for (i = x = 0; i < hpos; ++i)
8860 x += row->glyphs[TEXT_AREA][i].pixel_width;
8861
8862 /* Record this as the current active region. */
8863 dpyinfo->mouse_face_beg_col = hpos;
8864 dpyinfo->mouse_face_beg_row = vpos;
8865 dpyinfo->mouse_face_beg_x = x;
8866 dpyinfo->mouse_face_beg_y = row->y;
8867 dpyinfo->mouse_face_past_end = 0;
8868
8869 dpyinfo->mouse_face_end_col = hpos + 1;
8870 dpyinfo->mouse_face_end_row = vpos;
8871 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
8872 dpyinfo->mouse_face_end_y = row->y;
8873 dpyinfo->mouse_face_window = window;
8874 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
8875
8876 /* Display it as active. */
8877 show_mouse_face (dpyinfo, draw);
8878 dpyinfo->mouse_face_image_state = draw;
8879 }
8880
8881 set_help_echo:
8882
8883 /* Set help_echo_string to a help string to display for this tool-bar item.
8884 XTread_socket does the rest. */
8885 help_echo_object = help_echo_window = Qnil;
8886 help_echo_pos = -1;
8887 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
8888 if (NILP (help_echo_string))
8889 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
8890 }
8891
8892 #endif /* HAVE_WINDOW_SYSTEM */
8893
8894
8895 \f
8896 /***********************************************************************
8897 Fringes
8898 ***********************************************************************/
8899
8900 #ifdef HAVE_WINDOW_SYSTEM
8901
8902 /* An arrow like this: `<-'. */
8903 static unsigned char left_bits[] = {
8904 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
8905
8906 /* Right truncation arrow bitmap `->'. */
8907 static unsigned char right_bits[] = {
8908 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
8909
8910 /* Marker for continued lines. */
8911 static unsigned char continued_bits[] = {
8912 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
8913
8914 /* Marker for continuation lines. */
8915 static unsigned char continuation_bits[] = {
8916 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
8917
8918 /* Overlay arrow bitmap. A triangular arrow. */
8919 static unsigned char ov_bits[] = {
8920 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
8921
8922 /* Bitmap drawn to indicate lines not displaying text if
8923 `indicate-empty-lines' is non-nil. */
8924 static unsigned char zv_bits[] = {
8925 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8926 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8927 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8928 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8929 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8930 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8931 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8932 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
8933
8934 struct fringe_bitmap fringe_bitmaps[MAX_FRINGE_BITMAPS] =
8935 {
8936 { 0, 0, 0, NULL /* NO_FRINGE_BITMAP */ },
8937 { 8, sizeof (left_bits), 0, left_bits },
8938 { 8, sizeof (right_bits), 0, right_bits },
8939 { 8, sizeof (continued_bits), 0, continued_bits },
8940 { 8, sizeof (continuation_bits), 0, continuation_bits },
8941 { 8, sizeof (ov_bits), 0, ov_bits },
8942 { 8, sizeof (zv_bits), 3, zv_bits }
8943 };
8944
8945
8946 /* Draw the bitmap WHICH in one of the left or right fringes of
8947 window W. ROW is the glyph row for which to display the bitmap; it
8948 determines the vertical position at which the bitmap has to be
8949 drawn. */
8950
8951 static void
8952 draw_fringe_bitmap (w, row, which, left_p)
8953 struct window *w;
8954 struct glyph_row *row;
8955 enum fringe_bitmap_type which;
8956 int left_p;
8957 {
8958 struct frame *f = XFRAME (WINDOW_FRAME (w));
8959 struct draw_fringe_bitmap_params p;
8960
8961 /* Convert row to frame coordinates. */
8962 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
8963
8964 p.which = which;
8965 p.wd = fringe_bitmaps[which].width;
8966
8967 p.h = fringe_bitmaps[which].height;
8968 p.dh = (fringe_bitmaps[which].period
8969 ? (p.y % fringe_bitmaps[which].period)
8970 : 0);
8971 p.h -= p.dh;
8972 /* Clip bitmap if too high. */
8973 if (p.h > row->height)
8974 p.h = row->height;
8975
8976 p.face = FACE_FROM_ID (f, FRINGE_FACE_ID);
8977 PREPARE_FACE_FOR_DISPLAY (f, p.face);
8978
8979 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
8980 the fringe. */
8981 p.bx = -1;
8982 if (left_p)
8983 {
8984 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
8985 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
8986 ? LEFT_MARGIN_AREA
8987 : TEXT_AREA));
8988 if (p.wd > wd)
8989 p.wd = wd;
8990 p.x = x - p.wd - (wd - p.wd) / 2;
8991
8992 if (p.wd < wd || row->height > p.h)
8993 {
8994 /* If W has a vertical border to its left, don't draw over it. */
8995 wd -= ((!WINDOW_LEFTMOST_P (w)
8996 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
8997 ? 1 : 0);
8998 p.bx = x - wd;
8999 p.nx = wd;
9000 }
9001 }
9002 else
9003 {
9004 int x = window_box_right (w,
9005 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
9006 ? RIGHT_MARGIN_AREA
9007 : TEXT_AREA));
9008 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
9009 if (p.wd > wd)
9010 p.wd = wd;
9011 p.x = x + (wd - p.wd) / 2;
9012 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
9013 the fringe. */
9014 if (p.wd < wd || row->height > p.h)
9015 {
9016 p.bx = x;
9017 p.nx = wd;
9018 }
9019 }
9020
9021 if (p.bx >= 0)
9022 {
9023 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
9024
9025 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
9026 p.ny = row->visible_height;
9027 }
9028
9029 /* Adjust y to the offset in the row to start drawing the bitmap. */
9030 p.y += (row->height - p.h) / 2;
9031
9032 rif->draw_fringe_bitmap (w, row, &p);
9033 }
9034
9035 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
9036 function with input blocked. */
9037
9038 void
9039 draw_row_fringe_bitmaps (w, row)
9040 struct window *w;
9041 struct glyph_row *row;
9042 {
9043 enum fringe_bitmap_type bitmap;
9044
9045 xassert (interrupt_input_blocked);
9046
9047 /* If row is completely invisible, because of vscrolling, we
9048 don't have to draw anything. */
9049 if (row->visible_height <= 0)
9050 return;
9051
9052 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
9053 {
9054 /* Decide which bitmap to draw in the left fringe. */
9055 if (row->overlay_arrow_p)
9056 bitmap = OVERLAY_ARROW_BITMAP;
9057 else if (row->truncated_on_left_p)
9058 bitmap = LEFT_TRUNCATION_BITMAP;
9059 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
9060 bitmap = CONTINUATION_LINE_BITMAP;
9061 else if (row->indicate_empty_line_p)
9062 bitmap = ZV_LINE_BITMAP;
9063 else
9064 bitmap = NO_FRINGE_BITMAP;
9065
9066 draw_fringe_bitmap (w, row, bitmap, 1);
9067 }
9068
9069 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
9070 {
9071 /* Decide which bitmap to draw in the right fringe. */
9072 if (row->truncated_on_right_p)
9073 bitmap = RIGHT_TRUNCATION_BITMAP;
9074 else if (row->continued_p)
9075 bitmap = CONTINUED_LINE_BITMAP;
9076 else if (row->indicate_empty_line_p && WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
9077 bitmap = ZV_LINE_BITMAP;
9078 else
9079 bitmap = NO_FRINGE_BITMAP;
9080
9081 draw_fringe_bitmap (w, row, bitmap, 0);
9082 }
9083 }
9084
9085
9086 /* Compute actual fringe widths for frame F.
9087
9088 If REDRAW is 1, redraw F if the fringe settings was actually
9089 modified and F is visible.
9090
9091 Since the combined left and right fringe must occupy an integral
9092 number of columns, we may need to add some pixels to each fringe.
9093 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
9094 but a negative width value is taken literally (after negating it).
9095
9096 We never make the fringes narrower than specified. It is planned
9097 to make fringe bitmaps customizable and expandable, and at that
9098 time, the user will typically specify the minimum number of pixels
9099 needed for his bitmaps, so we shouldn't select anything less than
9100 what is specified.
9101 */
9102
9103 void
9104 compute_fringe_widths (f, redraw)
9105 struct frame *f;
9106 int redraw;
9107 {
9108 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
9109 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
9110 int o_cols = FRAME_FRINGE_COLS (f);
9111
9112 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
9113 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
9114 int left_fringe_width, right_fringe_width;
9115
9116 if (!NILP (left_fringe))
9117 left_fringe = Fcdr (left_fringe);
9118 if (!NILP (right_fringe))
9119 right_fringe = Fcdr (right_fringe);
9120
9121 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
9122 XINT (left_fringe));
9123 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
9124 XINT (right_fringe));
9125
9126 if (left_fringe_width || right_fringe_width)
9127 {
9128 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
9129 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
9130 int conf_wid = left_wid + right_wid;
9131 int font_wid = FRAME_COLUMN_WIDTH (f);
9132 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
9133 int real_wid = cols * font_wid;
9134 if (left_wid && right_wid)
9135 {
9136 if (left_fringe_width < 0)
9137 {
9138 /* Left fringe width is fixed, adjust right fringe if necessary */
9139 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
9140 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
9141 }
9142 else if (right_fringe_width < 0)
9143 {
9144 /* Right fringe width is fixed, adjust left fringe if necessary */
9145 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
9146 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
9147 }
9148 else
9149 {
9150 /* Adjust both fringes with an equal amount.
9151 Note that we are doing integer arithmetic here, so don't
9152 lose a pixel if the total width is an odd number. */
9153 int fill = real_wid - conf_wid;
9154 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
9155 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
9156 }
9157 }
9158 else if (left_fringe_width)
9159 {
9160 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
9161 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
9162 }
9163 else
9164 {
9165 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
9166 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
9167 }
9168 FRAME_FRINGE_COLS (f) = cols;
9169 }
9170 else
9171 {
9172 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
9173 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
9174 FRAME_FRINGE_COLS (f) = 0;
9175 }
9176
9177 if (redraw && FRAME_VISIBLE_P (f))
9178 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
9179 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
9180 o_cols != FRAME_FRINGE_COLS (f))
9181 redraw_frame (f);
9182 }
9183
9184 #endif /* HAVE_WINDOW_SYSTEM */
9185
9186
9187 \f
9188 /************************************************************************
9189 Horizontal scrolling
9190 ************************************************************************/
9191
9192 static int hscroll_window_tree P_ ((Lisp_Object));
9193 static int hscroll_windows P_ ((Lisp_Object));
9194
9195 /* For all leaf windows in the window tree rooted at WINDOW, set their
9196 hscroll value so that PT is (i) visible in the window, and (ii) so
9197 that it is not within a certain margin at the window's left and
9198 right border. Value is non-zero if any window's hscroll has been
9199 changed. */
9200
9201 static int
9202 hscroll_window_tree (window)
9203 Lisp_Object window;
9204 {
9205 int hscrolled_p = 0;
9206 int hscroll_relative_p = FLOATP (Vhscroll_step);
9207 int hscroll_step_abs = 0;
9208 double hscroll_step_rel = 0;
9209
9210 if (hscroll_relative_p)
9211 {
9212 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9213 if (hscroll_step_rel < 0)
9214 {
9215 hscroll_relative_p = 0;
9216 hscroll_step_abs = 0;
9217 }
9218 }
9219 else if (INTEGERP (Vhscroll_step))
9220 {
9221 hscroll_step_abs = XINT (Vhscroll_step);
9222 if (hscroll_step_abs < 0)
9223 hscroll_step_abs = 0;
9224 }
9225 else
9226 hscroll_step_abs = 0;
9227
9228 while (WINDOWP (window))
9229 {
9230 struct window *w = XWINDOW (window);
9231
9232 if (WINDOWP (w->hchild))
9233 hscrolled_p |= hscroll_window_tree (w->hchild);
9234 else if (WINDOWP (w->vchild))
9235 hscrolled_p |= hscroll_window_tree (w->vchild);
9236 else if (w->cursor.vpos >= 0)
9237 {
9238 int h_margin;
9239 int text_area_width;
9240 struct glyph_row *current_cursor_row
9241 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9242 struct glyph_row *desired_cursor_row
9243 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9244 struct glyph_row *cursor_row
9245 = (desired_cursor_row->enabled_p
9246 ? desired_cursor_row
9247 : current_cursor_row);
9248
9249 text_area_width = window_box_width (w, TEXT_AREA);
9250
9251 /* Scroll when cursor is inside this scroll margin. */
9252 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9253
9254 if ((XFASTINT (w->hscroll)
9255 && w->cursor.x <= h_margin)
9256 || (cursor_row->enabled_p
9257 && cursor_row->truncated_on_right_p
9258 && (w->cursor.x >= text_area_width - h_margin)))
9259 {
9260 struct it it;
9261 int hscroll;
9262 struct buffer *saved_current_buffer;
9263 int pt;
9264 int wanted_x;
9265
9266 /* Find point in a display of infinite width. */
9267 saved_current_buffer = current_buffer;
9268 current_buffer = XBUFFER (w->buffer);
9269
9270 if (w == XWINDOW (selected_window))
9271 pt = BUF_PT (current_buffer);
9272 else
9273 {
9274 pt = marker_position (w->pointm);
9275 pt = max (BEGV, pt);
9276 pt = min (ZV, pt);
9277 }
9278
9279 /* Move iterator to pt starting at cursor_row->start in
9280 a line with infinite width. */
9281 init_to_row_start (&it, w, cursor_row);
9282 it.last_visible_x = INFINITY;
9283 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9284 current_buffer = saved_current_buffer;
9285
9286 /* Position cursor in window. */
9287 if (!hscroll_relative_p && hscroll_step_abs == 0)
9288 hscroll = max (0, it.current_x - text_area_width / 2)
9289 / FRAME_COLUMN_WIDTH (it.f);
9290 else if (w->cursor.x >= text_area_width - h_margin)
9291 {
9292 if (hscroll_relative_p)
9293 wanted_x = text_area_width * (1 - hscroll_step_rel)
9294 - h_margin;
9295 else
9296 wanted_x = text_area_width
9297 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9298 - h_margin;
9299 hscroll
9300 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9301 }
9302 else
9303 {
9304 if (hscroll_relative_p)
9305 wanted_x = text_area_width * hscroll_step_rel
9306 + h_margin;
9307 else
9308 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9309 + h_margin;
9310 hscroll
9311 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9312 }
9313 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9314
9315 /* Don't call Fset_window_hscroll if value hasn't
9316 changed because it will prevent redisplay
9317 optimizations. */
9318 if (XFASTINT (w->hscroll) != hscroll)
9319 {
9320 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9321 w->hscroll = make_number (hscroll);
9322 hscrolled_p = 1;
9323 }
9324 }
9325 }
9326
9327 window = w->next;
9328 }
9329
9330 /* Value is non-zero if hscroll of any leaf window has been changed. */
9331 return hscrolled_p;
9332 }
9333
9334
9335 /* Set hscroll so that cursor is visible and not inside horizontal
9336 scroll margins for all windows in the tree rooted at WINDOW. See
9337 also hscroll_window_tree above. Value is non-zero if any window's
9338 hscroll has been changed. If it has, desired matrices on the frame
9339 of WINDOW are cleared. */
9340
9341 static int
9342 hscroll_windows (window)
9343 Lisp_Object window;
9344 {
9345 int hscrolled_p;
9346
9347 if (automatic_hscrolling_p)
9348 {
9349 hscrolled_p = hscroll_window_tree (window);
9350 if (hscrolled_p)
9351 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9352 }
9353 else
9354 hscrolled_p = 0;
9355 return hscrolled_p;
9356 }
9357
9358
9359 \f
9360 /************************************************************************
9361 Redisplay
9362 ************************************************************************/
9363
9364 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9365 to a non-zero value. This is sometimes handy to have in a debugger
9366 session. */
9367
9368 #if GLYPH_DEBUG
9369
9370 /* First and last unchanged row for try_window_id. */
9371
9372 int debug_first_unchanged_at_end_vpos;
9373 int debug_last_unchanged_at_beg_vpos;
9374
9375 /* Delta vpos and y. */
9376
9377 int debug_dvpos, debug_dy;
9378
9379 /* Delta in characters and bytes for try_window_id. */
9380
9381 int debug_delta, debug_delta_bytes;
9382
9383 /* Values of window_end_pos and window_end_vpos at the end of
9384 try_window_id. */
9385
9386 EMACS_INT debug_end_pos, debug_end_vpos;
9387
9388 /* Append a string to W->desired_matrix->method. FMT is a printf
9389 format string. A1...A9 are a supplement for a variable-length
9390 argument list. If trace_redisplay_p is non-zero also printf the
9391 resulting string to stderr. */
9392
9393 static void
9394 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9395 struct window *w;
9396 char *fmt;
9397 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9398 {
9399 char buffer[512];
9400 char *method = w->desired_matrix->method;
9401 int len = strlen (method);
9402 int size = sizeof w->desired_matrix->method;
9403 int remaining = size - len - 1;
9404
9405 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9406 if (len && remaining)
9407 {
9408 method[len] = '|';
9409 --remaining, ++len;
9410 }
9411
9412 strncpy (method + len, buffer, remaining);
9413
9414 if (trace_redisplay_p)
9415 fprintf (stderr, "%p (%s): %s\n",
9416 w,
9417 ((BUFFERP (w->buffer)
9418 && STRINGP (XBUFFER (w->buffer)->name))
9419 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9420 : "no buffer"),
9421 buffer);
9422 }
9423
9424 #endif /* GLYPH_DEBUG */
9425
9426
9427 /* Value is non-zero if all changes in window W, which displays
9428 current_buffer, are in the text between START and END. START is a
9429 buffer position, END is given as a distance from Z. Used in
9430 redisplay_internal for display optimization. */
9431
9432 static INLINE int
9433 text_outside_line_unchanged_p (w, start, end)
9434 struct window *w;
9435 int start, end;
9436 {
9437 int unchanged_p = 1;
9438
9439 /* If text or overlays have changed, see where. */
9440 if (XFASTINT (w->last_modified) < MODIFF
9441 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9442 {
9443 /* Gap in the line? */
9444 if (GPT < start || Z - GPT < end)
9445 unchanged_p = 0;
9446
9447 /* Changes start in front of the line, or end after it? */
9448 if (unchanged_p
9449 && (BEG_UNCHANGED < start - 1
9450 || END_UNCHANGED < end))
9451 unchanged_p = 0;
9452
9453 /* If selective display, can't optimize if changes start at the
9454 beginning of the line. */
9455 if (unchanged_p
9456 && INTEGERP (current_buffer->selective_display)
9457 && XINT (current_buffer->selective_display) > 0
9458 && (BEG_UNCHANGED < start || GPT <= start))
9459 unchanged_p = 0;
9460
9461 /* If there are overlays at the start or end of the line, these
9462 may have overlay strings with newlines in them. A change at
9463 START, for instance, may actually concern the display of such
9464 overlay strings as well, and they are displayed on different
9465 lines. So, quickly rule out this case. (For the future, it
9466 might be desirable to implement something more telling than
9467 just BEG/END_UNCHANGED.) */
9468 if (unchanged_p)
9469 {
9470 if (BEG + BEG_UNCHANGED == start
9471 && overlay_touches_p (start))
9472 unchanged_p = 0;
9473 if (END_UNCHANGED == end
9474 && overlay_touches_p (Z - end))
9475 unchanged_p = 0;
9476 }
9477 }
9478
9479 return unchanged_p;
9480 }
9481
9482
9483 /* Do a frame update, taking possible shortcuts into account. This is
9484 the main external entry point for redisplay.
9485
9486 If the last redisplay displayed an echo area message and that message
9487 is no longer requested, we clear the echo area or bring back the
9488 mini-buffer if that is in use. */
9489
9490 void
9491 redisplay ()
9492 {
9493 redisplay_internal (0);
9494 }
9495
9496
9497 /* Return 1 if point moved out of or into a composition. Otherwise
9498 return 0. PREV_BUF and PREV_PT are the last point buffer and
9499 position. BUF and PT are the current point buffer and position. */
9500
9501 int
9502 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9503 struct buffer *prev_buf, *buf;
9504 int prev_pt, pt;
9505 {
9506 int start, end;
9507 Lisp_Object prop;
9508 Lisp_Object buffer;
9509
9510 XSETBUFFER (buffer, buf);
9511 /* Check a composition at the last point if point moved within the
9512 same buffer. */
9513 if (prev_buf == buf)
9514 {
9515 if (prev_pt == pt)
9516 /* Point didn't move. */
9517 return 0;
9518
9519 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9520 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9521 && COMPOSITION_VALID_P (start, end, prop)
9522 && start < prev_pt && end > prev_pt)
9523 /* The last point was within the composition. Return 1 iff
9524 point moved out of the composition. */
9525 return (pt <= start || pt >= end);
9526 }
9527
9528 /* Check a composition at the current point. */
9529 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9530 && find_composition (pt, -1, &start, &end, &prop, buffer)
9531 && COMPOSITION_VALID_P (start, end, prop)
9532 && start < pt && end > pt);
9533 }
9534
9535
9536 /* Reconsider the setting of B->clip_changed which is displayed
9537 in window W. */
9538
9539 static INLINE void
9540 reconsider_clip_changes (w, b)
9541 struct window *w;
9542 struct buffer *b;
9543 {
9544 if (b->clip_changed
9545 && !NILP (w->window_end_valid)
9546 && w->current_matrix->buffer == b
9547 && w->current_matrix->zv == BUF_ZV (b)
9548 && w->current_matrix->begv == BUF_BEGV (b))
9549 b->clip_changed = 0;
9550
9551 /* If display wasn't paused, and W is not a tool bar window, see if
9552 point has been moved into or out of a composition. In that case,
9553 we set b->clip_changed to 1 to force updating the screen. If
9554 b->clip_changed has already been set to 1, we can skip this
9555 check. */
9556 if (!b->clip_changed
9557 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9558 {
9559 int pt;
9560
9561 if (w == XWINDOW (selected_window))
9562 pt = BUF_PT (current_buffer);
9563 else
9564 pt = marker_position (w->pointm);
9565
9566 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9567 || pt != XINT (w->last_point))
9568 && check_point_in_composition (w->current_matrix->buffer,
9569 XINT (w->last_point),
9570 XBUFFER (w->buffer), pt))
9571 b->clip_changed = 1;
9572 }
9573 }
9574 \f
9575
9576 /* Select FRAME to forward the values of frame-local variables into C
9577 variables so that the redisplay routines can access those values
9578 directly. */
9579
9580 static void
9581 select_frame_for_redisplay (frame)
9582 Lisp_Object frame;
9583 {
9584 Lisp_Object tail, sym, val;
9585 Lisp_Object old = selected_frame;
9586
9587 selected_frame = frame;
9588
9589 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9590 if (CONSP (XCAR (tail))
9591 && (sym = XCAR (XCAR (tail)),
9592 SYMBOLP (sym))
9593 && (sym = indirect_variable (sym),
9594 val = SYMBOL_VALUE (sym),
9595 (BUFFER_LOCAL_VALUEP (val)
9596 || SOME_BUFFER_LOCAL_VALUEP (val)))
9597 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9598 Fsymbol_value (sym);
9599
9600 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9601 if (CONSP (XCAR (tail))
9602 && (sym = XCAR (XCAR (tail)),
9603 SYMBOLP (sym))
9604 && (sym = indirect_variable (sym),
9605 val = SYMBOL_VALUE (sym),
9606 (BUFFER_LOCAL_VALUEP (val)
9607 || SOME_BUFFER_LOCAL_VALUEP (val)))
9608 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9609 Fsymbol_value (sym);
9610 }
9611
9612
9613 #define STOP_POLLING \
9614 do { if (! polling_stopped_here) stop_polling (); \
9615 polling_stopped_here = 1; } while (0)
9616
9617 #define RESUME_POLLING \
9618 do { if (polling_stopped_here) start_polling (); \
9619 polling_stopped_here = 0; } while (0)
9620
9621
9622 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9623 response to any user action; therefore, we should preserve the echo
9624 area. (Actually, our caller does that job.) Perhaps in the future
9625 avoid recentering windows if it is not necessary; currently that
9626 causes some problems. */
9627
9628 static void
9629 redisplay_internal (preserve_echo_area)
9630 int preserve_echo_area;
9631 {
9632 struct window *w = XWINDOW (selected_window);
9633 struct frame *f = XFRAME (w->frame);
9634 int pause;
9635 int must_finish = 0;
9636 struct text_pos tlbufpos, tlendpos;
9637 int number_of_visible_frames;
9638 int count;
9639 struct frame *sf = SELECTED_FRAME ();
9640 int polling_stopped_here = 0;
9641
9642 /* Non-zero means redisplay has to consider all windows on all
9643 frames. Zero means, only selected_window is considered. */
9644 int consider_all_windows_p;
9645
9646 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9647
9648 /* No redisplay if running in batch mode or frame is not yet fully
9649 initialized, or redisplay is explicitly turned off by setting
9650 Vinhibit_redisplay. */
9651 if (noninteractive
9652 || !NILP (Vinhibit_redisplay)
9653 || !f->glyphs_initialized_p)
9654 return;
9655
9656 /* The flag redisplay_performed_directly_p is set by
9657 direct_output_for_insert when it already did the whole screen
9658 update necessary. */
9659 if (redisplay_performed_directly_p)
9660 {
9661 redisplay_performed_directly_p = 0;
9662 if (!hscroll_windows (selected_window))
9663 return;
9664 }
9665
9666 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9667 if (popup_activated ())
9668 return;
9669 #endif
9670
9671 /* I don't think this happens but let's be paranoid. */
9672 if (redisplaying_p)
9673 return;
9674
9675 /* Record a function that resets redisplaying_p to its old value
9676 when we leave this function. */
9677 count = SPECPDL_INDEX ();
9678 record_unwind_protect (unwind_redisplay,
9679 Fcons (make_number (redisplaying_p), selected_frame));
9680 ++redisplaying_p;
9681 specbind (Qinhibit_free_realized_faces, Qnil);
9682
9683 retry:
9684 pause = 0;
9685 reconsider_clip_changes (w, current_buffer);
9686
9687 /* If new fonts have been loaded that make a glyph matrix adjustment
9688 necessary, do it. */
9689 if (fonts_changed_p)
9690 {
9691 adjust_glyphs (NULL);
9692 ++windows_or_buffers_changed;
9693 fonts_changed_p = 0;
9694 }
9695
9696 /* If face_change_count is non-zero, init_iterator will free all
9697 realized faces, which includes the faces referenced from current
9698 matrices. So, we can't reuse current matrices in this case. */
9699 if (face_change_count)
9700 ++windows_or_buffers_changed;
9701
9702 if (! FRAME_WINDOW_P (sf)
9703 && previous_terminal_frame != sf)
9704 {
9705 /* Since frames on an ASCII terminal share the same display
9706 area, displaying a different frame means redisplay the whole
9707 thing. */
9708 windows_or_buffers_changed++;
9709 SET_FRAME_GARBAGED (sf);
9710 XSETFRAME (Vterminal_frame, sf);
9711 }
9712 previous_terminal_frame = sf;
9713
9714 /* Set the visible flags for all frames. Do this before checking
9715 for resized or garbaged frames; they want to know if their frames
9716 are visible. See the comment in frame.h for
9717 FRAME_SAMPLE_VISIBILITY. */
9718 {
9719 Lisp_Object tail, frame;
9720
9721 number_of_visible_frames = 0;
9722
9723 FOR_EACH_FRAME (tail, frame)
9724 {
9725 struct frame *f = XFRAME (frame);
9726
9727 FRAME_SAMPLE_VISIBILITY (f);
9728 if (FRAME_VISIBLE_P (f))
9729 ++number_of_visible_frames;
9730 clear_desired_matrices (f);
9731 }
9732 }
9733
9734 /* Notice any pending interrupt request to change frame size. */
9735 do_pending_window_change (1);
9736
9737 /* Clear frames marked as garbaged. */
9738 if (frame_garbaged)
9739 clear_garbaged_frames ();
9740
9741 /* Build menubar and tool-bar items. */
9742 prepare_menu_bars ();
9743
9744 if (windows_or_buffers_changed)
9745 update_mode_lines++;
9746
9747 /* Detect case that we need to write or remove a star in the mode line. */
9748 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9749 {
9750 w->update_mode_line = Qt;
9751 if (buffer_shared > 1)
9752 update_mode_lines++;
9753 }
9754
9755 /* If %c is in the mode line, update it if needed. */
9756 if (!NILP (w->column_number_displayed)
9757 /* This alternative quickly identifies a common case
9758 where no change is needed. */
9759 && !(PT == XFASTINT (w->last_point)
9760 && XFASTINT (w->last_modified) >= MODIFF
9761 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9762 && (XFASTINT (w->column_number_displayed)
9763 != (int) current_column ())) /* iftc */
9764 w->update_mode_line = Qt;
9765
9766 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9767
9768 /* The variable buffer_shared is set in redisplay_window and
9769 indicates that we redisplay a buffer in different windows. See
9770 there. */
9771 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9772 || cursor_type_changed);
9773
9774 /* If specs for an arrow have changed, do thorough redisplay
9775 to ensure we remove any arrow that should no longer exist. */
9776 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
9777 || ! EQ (Voverlay_arrow_string, last_arrow_string))
9778 consider_all_windows_p = windows_or_buffers_changed = 1;
9779
9780 /* Normally the message* functions will have already displayed and
9781 updated the echo area, but the frame may have been trashed, or
9782 the update may have been preempted, so display the echo area
9783 again here. Checking message_cleared_p captures the case that
9784 the echo area should be cleared. */
9785 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9786 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9787 || (message_cleared_p
9788 && minibuf_level == 0
9789 /* If the mini-window is currently selected, this means the
9790 echo-area doesn't show through. */
9791 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9792 {
9793 int window_height_changed_p = echo_area_display (0);
9794 must_finish = 1;
9795
9796 /* If we don't display the current message, don't clear the
9797 message_cleared_p flag, because, if we did, we wouldn't clear
9798 the echo area in the next redisplay which doesn't preserve
9799 the echo area. */
9800 if (!display_last_displayed_message_p)
9801 message_cleared_p = 0;
9802
9803 if (fonts_changed_p)
9804 goto retry;
9805 else if (window_height_changed_p)
9806 {
9807 consider_all_windows_p = 1;
9808 ++update_mode_lines;
9809 ++windows_or_buffers_changed;
9810
9811 /* If window configuration was changed, frames may have been
9812 marked garbaged. Clear them or we will experience
9813 surprises wrt scrolling. */
9814 if (frame_garbaged)
9815 clear_garbaged_frames ();
9816 }
9817 }
9818 else if (EQ (selected_window, minibuf_window)
9819 && (current_buffer->clip_changed
9820 || XFASTINT (w->last_modified) < MODIFF
9821 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9822 && resize_mini_window (w, 0))
9823 {
9824 /* Resized active mini-window to fit the size of what it is
9825 showing if its contents might have changed. */
9826 must_finish = 1;
9827 consider_all_windows_p = 1;
9828 ++windows_or_buffers_changed;
9829 ++update_mode_lines;
9830
9831 /* If window configuration was changed, frames may have been
9832 marked garbaged. Clear them or we will experience
9833 surprises wrt scrolling. */
9834 if (frame_garbaged)
9835 clear_garbaged_frames ();
9836 }
9837
9838
9839 /* If showing the region, and mark has changed, we must redisplay
9840 the whole window. The assignment to this_line_start_pos prevents
9841 the optimization directly below this if-statement. */
9842 if (((!NILP (Vtransient_mark_mode)
9843 && !NILP (XBUFFER (w->buffer)->mark_active))
9844 != !NILP (w->region_showing))
9845 || (!NILP (w->region_showing)
9846 && !EQ (w->region_showing,
9847 Fmarker_position (XBUFFER (w->buffer)->mark))))
9848 CHARPOS (this_line_start_pos) = 0;
9849
9850 /* Optimize the case that only the line containing the cursor in the
9851 selected window has changed. Variables starting with this_ are
9852 set in display_line and record information about the line
9853 containing the cursor. */
9854 tlbufpos = this_line_start_pos;
9855 tlendpos = this_line_end_pos;
9856 if (!consider_all_windows_p
9857 && CHARPOS (tlbufpos) > 0
9858 && NILP (w->update_mode_line)
9859 && !current_buffer->clip_changed
9860 && !current_buffer->prevent_redisplay_optimizations_p
9861 && FRAME_VISIBLE_P (XFRAME (w->frame))
9862 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9863 /* Make sure recorded data applies to current buffer, etc. */
9864 && this_line_buffer == current_buffer
9865 && current_buffer == XBUFFER (w->buffer)
9866 && NILP (w->force_start)
9867 && NILP (w->optional_new_start)
9868 /* Point must be on the line that we have info recorded about. */
9869 && PT >= CHARPOS (tlbufpos)
9870 && PT <= Z - CHARPOS (tlendpos)
9871 /* All text outside that line, including its final newline,
9872 must be unchanged */
9873 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9874 CHARPOS (tlendpos)))
9875 {
9876 if (CHARPOS (tlbufpos) > BEGV
9877 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9878 && (CHARPOS (tlbufpos) == ZV
9879 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9880 /* Former continuation line has disappeared by becoming empty */
9881 goto cancel;
9882 else if (XFASTINT (w->last_modified) < MODIFF
9883 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9884 || MINI_WINDOW_P (w))
9885 {
9886 /* We have to handle the case of continuation around a
9887 wide-column character (See the comment in indent.c around
9888 line 885).
9889
9890 For instance, in the following case:
9891
9892 -------- Insert --------
9893 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9894 J_I_ ==> J_I_ `^^' are cursors.
9895 ^^ ^^
9896 -------- --------
9897
9898 As we have to redraw the line above, we should goto cancel. */
9899
9900 struct it it;
9901 int line_height_before = this_line_pixel_height;
9902
9903 /* Note that start_display will handle the case that the
9904 line starting at tlbufpos is a continuation lines. */
9905 start_display (&it, w, tlbufpos);
9906
9907 /* Implementation note: It this still necessary? */
9908 if (it.current_x != this_line_start_x)
9909 goto cancel;
9910
9911 TRACE ((stderr, "trying display optimization 1\n"));
9912 w->cursor.vpos = -1;
9913 overlay_arrow_seen = 0;
9914 it.vpos = this_line_vpos;
9915 it.current_y = this_line_y;
9916 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9917 display_line (&it);
9918
9919 /* If line contains point, is not continued,
9920 and ends at same distance from eob as before, we win */
9921 if (w->cursor.vpos >= 0
9922 /* Line is not continued, otherwise this_line_start_pos
9923 would have been set to 0 in display_line. */
9924 && CHARPOS (this_line_start_pos)
9925 /* Line ends as before. */
9926 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9927 /* Line has same height as before. Otherwise other lines
9928 would have to be shifted up or down. */
9929 && this_line_pixel_height == line_height_before)
9930 {
9931 /* If this is not the window's last line, we must adjust
9932 the charstarts of the lines below. */
9933 if (it.current_y < it.last_visible_y)
9934 {
9935 struct glyph_row *row
9936 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
9937 int delta, delta_bytes;
9938
9939 if (Z - CHARPOS (tlendpos) == ZV)
9940 {
9941 /* This line ends at end of (accessible part of)
9942 buffer. There is no newline to count. */
9943 delta = (Z
9944 - CHARPOS (tlendpos)
9945 - MATRIX_ROW_START_CHARPOS (row));
9946 delta_bytes = (Z_BYTE
9947 - BYTEPOS (tlendpos)
9948 - MATRIX_ROW_START_BYTEPOS (row));
9949 }
9950 else
9951 {
9952 /* This line ends in a newline. Must take
9953 account of the newline and the rest of the
9954 text that follows. */
9955 delta = (Z
9956 - CHARPOS (tlendpos)
9957 - MATRIX_ROW_START_CHARPOS (row));
9958 delta_bytes = (Z_BYTE
9959 - BYTEPOS (tlendpos)
9960 - MATRIX_ROW_START_BYTEPOS (row));
9961 }
9962
9963 increment_matrix_positions (w->current_matrix,
9964 this_line_vpos + 1,
9965 w->current_matrix->nrows,
9966 delta, delta_bytes);
9967 }
9968
9969 /* If this row displays text now but previously didn't,
9970 or vice versa, w->window_end_vpos may have to be
9971 adjusted. */
9972 if ((it.glyph_row - 1)->displays_text_p)
9973 {
9974 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
9975 XSETINT (w->window_end_vpos, this_line_vpos);
9976 }
9977 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
9978 && this_line_vpos > 0)
9979 XSETINT (w->window_end_vpos, this_line_vpos - 1);
9980 w->window_end_valid = Qnil;
9981
9982 /* Update hint: No need to try to scroll in update_window. */
9983 w->desired_matrix->no_scrolling_p = 1;
9984
9985 #if GLYPH_DEBUG
9986 *w->desired_matrix->method = 0;
9987 debug_method_add (w, "optimization 1");
9988 #endif
9989 goto update;
9990 }
9991 else
9992 goto cancel;
9993 }
9994 else if (/* Cursor position hasn't changed. */
9995 PT == XFASTINT (w->last_point)
9996 /* Make sure the cursor was last displayed
9997 in this window. Otherwise we have to reposition it. */
9998 && 0 <= w->cursor.vpos
9999 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10000 {
10001 if (!must_finish)
10002 {
10003 do_pending_window_change (1);
10004
10005 /* We used to always goto end_of_redisplay here, but this
10006 isn't enough if we have a blinking cursor. */
10007 if (w->cursor_off_p == w->last_cursor_off_p)
10008 goto end_of_redisplay;
10009 }
10010 goto update;
10011 }
10012 /* If highlighting the region, or if the cursor is in the echo area,
10013 then we can't just move the cursor. */
10014 else if (! (!NILP (Vtransient_mark_mode)
10015 && !NILP (current_buffer->mark_active))
10016 && (EQ (selected_window, current_buffer->last_selected_window)
10017 || highlight_nonselected_windows)
10018 && NILP (w->region_showing)
10019 && NILP (Vshow_trailing_whitespace)
10020 && !cursor_in_echo_area)
10021 {
10022 struct it it;
10023 struct glyph_row *row;
10024
10025 /* Skip from tlbufpos to PT and see where it is. Note that
10026 PT may be in invisible text. If so, we will end at the
10027 next visible position. */
10028 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10029 NULL, DEFAULT_FACE_ID);
10030 it.current_x = this_line_start_x;
10031 it.current_y = this_line_y;
10032 it.vpos = this_line_vpos;
10033
10034 /* The call to move_it_to stops in front of PT, but
10035 moves over before-strings. */
10036 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10037
10038 if (it.vpos == this_line_vpos
10039 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10040 row->enabled_p))
10041 {
10042 xassert (this_line_vpos == it.vpos);
10043 xassert (this_line_y == it.current_y);
10044 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10045 #if GLYPH_DEBUG
10046 *w->desired_matrix->method = 0;
10047 debug_method_add (w, "optimization 3");
10048 #endif
10049 goto update;
10050 }
10051 else
10052 goto cancel;
10053 }
10054
10055 cancel:
10056 /* Text changed drastically or point moved off of line. */
10057 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10058 }
10059
10060 CHARPOS (this_line_start_pos) = 0;
10061 consider_all_windows_p |= buffer_shared > 1;
10062 ++clear_face_cache_count;
10063
10064
10065 /* Build desired matrices, and update the display. If
10066 consider_all_windows_p is non-zero, do it for all windows on all
10067 frames. Otherwise do it for selected_window, only. */
10068
10069 if (consider_all_windows_p)
10070 {
10071 Lisp_Object tail, frame;
10072 int i, n = 0, size = 50;
10073 struct frame **updated
10074 = (struct frame **) alloca (size * sizeof *updated);
10075
10076 /* Clear the face cache eventually. */
10077 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10078 {
10079 clear_face_cache (0);
10080 clear_face_cache_count = 0;
10081 }
10082
10083 /* Recompute # windows showing selected buffer. This will be
10084 incremented each time such a window is displayed. */
10085 buffer_shared = 0;
10086
10087 FOR_EACH_FRAME (tail, frame)
10088 {
10089 struct frame *f = XFRAME (frame);
10090
10091 if (FRAME_WINDOW_P (f) || f == sf)
10092 {
10093 if (! EQ (frame, selected_frame))
10094 /* Select the frame, for the sake of frame-local
10095 variables. */
10096 select_frame_for_redisplay (frame);
10097
10098 #ifdef HAVE_WINDOW_SYSTEM
10099 if (clear_face_cache_count % 50 == 0
10100 && FRAME_WINDOW_P (f))
10101 clear_image_cache (f, 0);
10102 #endif /* HAVE_WINDOW_SYSTEM */
10103
10104 /* Mark all the scroll bars to be removed; we'll redeem
10105 the ones we want when we redisplay their windows. */
10106 if (condemn_scroll_bars_hook)
10107 condemn_scroll_bars_hook (f);
10108
10109 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10110 redisplay_windows (FRAME_ROOT_WINDOW (f));
10111
10112 /* Any scroll bars which redisplay_windows should have
10113 nuked should now go away. */
10114 if (judge_scroll_bars_hook)
10115 judge_scroll_bars_hook (f);
10116
10117 /* If fonts changed, display again. */
10118 /* ??? rms: I suspect it is a mistake to jump all the way
10119 back to retry here. It should just retry this frame. */
10120 if (fonts_changed_p)
10121 goto retry;
10122
10123 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10124 {
10125 /* See if we have to hscroll. */
10126 if (hscroll_windows (f->root_window))
10127 goto retry;
10128
10129 /* Prevent various kinds of signals during display
10130 update. stdio is not robust about handling
10131 signals, which can cause an apparent I/O
10132 error. */
10133 if (interrupt_input)
10134 unrequest_sigio ();
10135 STOP_POLLING;
10136
10137 /* Update the display. */
10138 set_window_update_flags (XWINDOW (f->root_window), 1);
10139 pause |= update_frame (f, 0, 0);
10140 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10141 if (pause)
10142 break;
10143 #endif
10144
10145 if (n == size)
10146 {
10147 int nbytes = size * sizeof *updated;
10148 struct frame **p = (struct frame **) alloca (2 * nbytes);
10149 bcopy (updated, p, nbytes);
10150 size *= 2;
10151 }
10152
10153 updated[n++] = f;
10154 }
10155 }
10156 }
10157
10158 if (!pause)
10159 {
10160 /* Do the mark_window_display_accurate after all windows have
10161 been redisplayed because this call resets flags in buffers
10162 which are needed for proper redisplay. */
10163 for (i = 0; i < n; ++i)
10164 {
10165 struct frame *f = updated[i];
10166 mark_window_display_accurate (f->root_window, 1);
10167 if (frame_up_to_date_hook)
10168 frame_up_to_date_hook (f);
10169 }
10170 }
10171 }
10172 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10173 {
10174 Lisp_Object mini_window;
10175 struct frame *mini_frame;
10176
10177 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10178 /* Use list_of_error, not Qerror, so that
10179 we catch only errors and don't run the debugger. */
10180 internal_condition_case_1 (redisplay_window_1, selected_window,
10181 list_of_error,
10182 redisplay_window_error);
10183
10184 /* Compare desired and current matrices, perform output. */
10185
10186 update:
10187 /* If fonts changed, display again. */
10188 if (fonts_changed_p)
10189 goto retry;
10190
10191 /* Prevent various kinds of signals during display update.
10192 stdio is not robust about handling signals,
10193 which can cause an apparent I/O error. */
10194 if (interrupt_input)
10195 unrequest_sigio ();
10196 STOP_POLLING;
10197
10198 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10199 {
10200 if (hscroll_windows (selected_window))
10201 goto retry;
10202
10203 XWINDOW (selected_window)->must_be_updated_p = 1;
10204 pause = update_frame (sf, 0, 0);
10205 }
10206
10207 /* We may have called echo_area_display at the top of this
10208 function. If the echo area is on another frame, that may
10209 have put text on a frame other than the selected one, so the
10210 above call to update_frame would not have caught it. Catch
10211 it here. */
10212 mini_window = FRAME_MINIBUF_WINDOW (sf);
10213 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10214
10215 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10216 {
10217 XWINDOW (mini_window)->must_be_updated_p = 1;
10218 pause |= update_frame (mini_frame, 0, 0);
10219 if (!pause && hscroll_windows (mini_window))
10220 goto retry;
10221 }
10222 }
10223
10224 /* If display was paused because of pending input, make sure we do a
10225 thorough update the next time. */
10226 if (pause)
10227 {
10228 /* Prevent the optimization at the beginning of
10229 redisplay_internal that tries a single-line update of the
10230 line containing the cursor in the selected window. */
10231 CHARPOS (this_line_start_pos) = 0;
10232
10233 /* Let the overlay arrow be updated the next time. */
10234 if (!NILP (last_arrow_position))
10235 {
10236 last_arrow_position = Qt;
10237 last_arrow_string = Qt;
10238 }
10239
10240 /* If we pause after scrolling, some rows in the current
10241 matrices of some windows are not valid. */
10242 if (!WINDOW_FULL_WIDTH_P (w)
10243 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10244 update_mode_lines = 1;
10245 }
10246 else
10247 {
10248 if (!consider_all_windows_p)
10249 {
10250 /* This has already been done above if
10251 consider_all_windows_p is set. */
10252 mark_window_display_accurate_1 (w, 1);
10253
10254 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10255 last_arrow_string = Voverlay_arrow_string;
10256
10257 if (frame_up_to_date_hook != 0)
10258 frame_up_to_date_hook (sf);
10259 }
10260
10261 update_mode_lines = 0;
10262 windows_or_buffers_changed = 0;
10263 cursor_type_changed = 0;
10264 }
10265
10266 /* Start SIGIO interrupts coming again. Having them off during the
10267 code above makes it less likely one will discard output, but not
10268 impossible, since there might be stuff in the system buffer here.
10269 But it is much hairier to try to do anything about that. */
10270 if (interrupt_input)
10271 request_sigio ();
10272 RESUME_POLLING;
10273
10274 /* If a frame has become visible which was not before, redisplay
10275 again, so that we display it. Expose events for such a frame
10276 (which it gets when becoming visible) don't call the parts of
10277 redisplay constructing glyphs, so simply exposing a frame won't
10278 display anything in this case. So, we have to display these
10279 frames here explicitly. */
10280 if (!pause)
10281 {
10282 Lisp_Object tail, frame;
10283 int new_count = 0;
10284
10285 FOR_EACH_FRAME (tail, frame)
10286 {
10287 int this_is_visible = 0;
10288
10289 if (XFRAME (frame)->visible)
10290 this_is_visible = 1;
10291 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10292 if (XFRAME (frame)->visible)
10293 this_is_visible = 1;
10294
10295 if (this_is_visible)
10296 new_count++;
10297 }
10298
10299 if (new_count != number_of_visible_frames)
10300 windows_or_buffers_changed++;
10301 }
10302
10303 /* Change frame size now if a change is pending. */
10304 do_pending_window_change (1);
10305
10306 /* If we just did a pending size change, or have additional
10307 visible frames, redisplay again. */
10308 if (windows_or_buffers_changed && !pause)
10309 goto retry;
10310
10311 end_of_redisplay:
10312 unbind_to (count, Qnil);
10313 RESUME_POLLING;
10314 }
10315
10316
10317 /* Redisplay, but leave alone any recent echo area message unless
10318 another message has been requested in its place.
10319
10320 This is useful in situations where you need to redisplay but no
10321 user action has occurred, making it inappropriate for the message
10322 area to be cleared. See tracking_off and
10323 wait_reading_process_input for examples of these situations.
10324
10325 FROM_WHERE is an integer saying from where this function was
10326 called. This is useful for debugging. */
10327
10328 void
10329 redisplay_preserve_echo_area (from_where)
10330 int from_where;
10331 {
10332 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10333
10334 if (!NILP (echo_area_buffer[1]))
10335 {
10336 /* We have a previously displayed message, but no current
10337 message. Redisplay the previous message. */
10338 display_last_displayed_message_p = 1;
10339 redisplay_internal (1);
10340 display_last_displayed_message_p = 0;
10341 }
10342 else
10343 redisplay_internal (1);
10344 }
10345
10346
10347 /* Function registered with record_unwind_protect in
10348 redisplay_internal. Reset redisplaying_p to the value it had
10349 before redisplay_internal was called, and clear
10350 prevent_freeing_realized_faces_p. It also selects the previously
10351 selected frame. */
10352
10353 static Lisp_Object
10354 unwind_redisplay (val)
10355 Lisp_Object val;
10356 {
10357 Lisp_Object old_redisplaying_p, old_frame;
10358
10359 old_redisplaying_p = XCAR (val);
10360 redisplaying_p = XFASTINT (old_redisplaying_p);
10361 old_frame = XCDR (val);
10362 if (! EQ (old_frame, selected_frame))
10363 select_frame_for_redisplay (old_frame);
10364 return Qnil;
10365 }
10366
10367
10368 /* Mark the display of window W as accurate or inaccurate. If
10369 ACCURATE_P is non-zero mark display of W as accurate. If
10370 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10371 redisplay_internal is called. */
10372
10373 static void
10374 mark_window_display_accurate_1 (w, accurate_p)
10375 struct window *w;
10376 int accurate_p;
10377 {
10378 if (BUFFERP (w->buffer))
10379 {
10380 struct buffer *b = XBUFFER (w->buffer);
10381
10382 w->last_modified
10383 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10384 w->last_overlay_modified
10385 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10386 w->last_had_star
10387 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10388
10389 if (accurate_p)
10390 {
10391 b->clip_changed = 0;
10392 b->prevent_redisplay_optimizations_p = 0;
10393
10394 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10395 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10396 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10397 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10398
10399 w->current_matrix->buffer = b;
10400 w->current_matrix->begv = BUF_BEGV (b);
10401 w->current_matrix->zv = BUF_ZV (b);
10402
10403 w->last_cursor = w->cursor;
10404 w->last_cursor_off_p = w->cursor_off_p;
10405
10406 if (w == XWINDOW (selected_window))
10407 w->last_point = make_number (BUF_PT (b));
10408 else
10409 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10410 }
10411 }
10412
10413 if (accurate_p)
10414 {
10415 w->window_end_valid = w->buffer;
10416 #if 0 /* This is incorrect with variable-height lines. */
10417 xassert (XINT (w->window_end_vpos)
10418 < (WINDOW_TOTAL_LINES (w)
10419 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10420 #endif
10421 w->update_mode_line = Qnil;
10422 }
10423 }
10424
10425
10426 /* Mark the display of windows in the window tree rooted at WINDOW as
10427 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10428 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10429 be redisplayed the next time redisplay_internal is called. */
10430
10431 void
10432 mark_window_display_accurate (window, accurate_p)
10433 Lisp_Object window;
10434 int accurate_p;
10435 {
10436 struct window *w;
10437
10438 for (; !NILP (window); window = w->next)
10439 {
10440 w = XWINDOW (window);
10441 mark_window_display_accurate_1 (w, accurate_p);
10442
10443 if (!NILP (w->vchild))
10444 mark_window_display_accurate (w->vchild, accurate_p);
10445 if (!NILP (w->hchild))
10446 mark_window_display_accurate (w->hchild, accurate_p);
10447 }
10448
10449 if (accurate_p)
10450 {
10451 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10452 last_arrow_string = Voverlay_arrow_string;
10453 }
10454 else
10455 {
10456 /* Force a thorough redisplay the next time by setting
10457 last_arrow_position and last_arrow_string to t, which is
10458 unequal to any useful value of Voverlay_arrow_... */
10459 last_arrow_position = Qt;
10460 last_arrow_string = Qt;
10461 }
10462 }
10463
10464
10465 /* Return value in display table DP (Lisp_Char_Table *) for character
10466 C. Since a display table doesn't have any parent, we don't have to
10467 follow parent. Do not call this function directly but use the
10468 macro DISP_CHAR_VECTOR. */
10469
10470 Lisp_Object
10471 disp_char_vector (dp, c)
10472 struct Lisp_Char_Table *dp;
10473 int c;
10474 {
10475 int code[4], i;
10476 Lisp_Object val;
10477
10478 if (SINGLE_BYTE_CHAR_P (c))
10479 return (dp->contents[c]);
10480
10481 SPLIT_CHAR (c, code[0], code[1], code[2]);
10482 if (code[1] < 32)
10483 code[1] = -1;
10484 else if (code[2] < 32)
10485 code[2] = -1;
10486
10487 /* Here, the possible range of code[0] (== charset ID) is
10488 128..max_charset. Since the top level char table contains data
10489 for multibyte characters after 256th element, we must increment
10490 code[0] by 128 to get a correct index. */
10491 code[0] += 128;
10492 code[3] = -1; /* anchor */
10493
10494 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10495 {
10496 val = dp->contents[code[i]];
10497 if (!SUB_CHAR_TABLE_P (val))
10498 return (NILP (val) ? dp->defalt : val);
10499 }
10500
10501 /* Here, val is a sub char table. We return the default value of
10502 it. */
10503 return (dp->defalt);
10504 }
10505
10506
10507 \f
10508 /***********************************************************************
10509 Window Redisplay
10510 ***********************************************************************/
10511
10512 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10513
10514 static void
10515 redisplay_windows (window)
10516 Lisp_Object window;
10517 {
10518 while (!NILP (window))
10519 {
10520 struct window *w = XWINDOW (window);
10521
10522 if (!NILP (w->hchild))
10523 redisplay_windows (w->hchild);
10524 else if (!NILP (w->vchild))
10525 redisplay_windows (w->vchild);
10526 else
10527 {
10528 displayed_buffer = XBUFFER (w->buffer);
10529 /* Use list_of_error, not Qerror, so that
10530 we catch only errors and don't run the debugger. */
10531 internal_condition_case_1 (redisplay_window_0, window,
10532 list_of_error,
10533 redisplay_window_error);
10534 }
10535
10536 window = w->next;
10537 }
10538 }
10539
10540 static Lisp_Object
10541 redisplay_window_error ()
10542 {
10543 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10544 return Qnil;
10545 }
10546
10547 static Lisp_Object
10548 redisplay_window_0 (window)
10549 Lisp_Object window;
10550 {
10551 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10552 redisplay_window (window, 0);
10553 return Qnil;
10554 }
10555
10556 static Lisp_Object
10557 redisplay_window_1 (window)
10558 Lisp_Object window;
10559 {
10560 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10561 redisplay_window (window, 1);
10562 return Qnil;
10563 }
10564 \f
10565
10566 /* Increment GLYPH until it reaches END or CONDITION fails while
10567 adding (GLYPH)->pixel_width to X. */
10568
10569 #define SKIP_GLYPHS(glyph, end, x, condition) \
10570 do \
10571 { \
10572 (x) += (glyph)->pixel_width; \
10573 ++(glyph); \
10574 } \
10575 while ((glyph) < (end) && (condition))
10576
10577
10578 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10579 DELTA is the number of bytes by which positions recorded in ROW
10580 differ from current buffer positions. */
10581
10582 void
10583 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10584 struct window *w;
10585 struct glyph_row *row;
10586 struct glyph_matrix *matrix;
10587 int delta, delta_bytes, dy, dvpos;
10588 {
10589 struct glyph *glyph = row->glyphs[TEXT_AREA];
10590 struct glyph *end = glyph + row->used[TEXT_AREA];
10591 /* The first glyph that starts a sequence of glyphs from string. */
10592 struct glyph *string_start;
10593 /* The X coordinate of string_start. */
10594 int string_start_x;
10595 /* The last known character position. */
10596 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10597 /* The last known character position before string_start. */
10598 int string_before_pos;
10599 int x = row->x;
10600 int pt_old = PT - delta;
10601
10602 /* Skip over glyphs not having an object at the start of the row.
10603 These are special glyphs like truncation marks on terminal
10604 frames. */
10605 if (row->displays_text_p)
10606 while (glyph < end
10607 && INTEGERP (glyph->object)
10608 && glyph->charpos < 0)
10609 {
10610 x += glyph->pixel_width;
10611 ++glyph;
10612 }
10613
10614 string_start = NULL;
10615 while (glyph < end
10616 && !INTEGERP (glyph->object)
10617 && (!BUFFERP (glyph->object)
10618 || (last_pos = glyph->charpos) < pt_old))
10619 {
10620 if (! STRINGP (glyph->object))
10621 {
10622 string_start = NULL;
10623 x += glyph->pixel_width;
10624 ++glyph;
10625 }
10626 else
10627 {
10628 string_before_pos = last_pos;
10629 string_start = glyph;
10630 string_start_x = x;
10631 /* Skip all glyphs from string. */
10632 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10633 }
10634 }
10635
10636 if (string_start
10637 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10638 {
10639 /* We may have skipped over point because the previous glyphs
10640 are from string. As there's no easy way to know the
10641 character position of the current glyph, find the correct
10642 glyph on point by scanning from string_start again. */
10643 Lisp_Object limit;
10644 Lisp_Object string;
10645 int pos;
10646
10647 limit = make_number (pt_old + 1);
10648 end = glyph;
10649 glyph = string_start;
10650 x = string_start_x;
10651 string = glyph->object;
10652 pos = string_buffer_position (w, string, string_before_pos);
10653 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10654 because we always put cursor after overlay strings. */
10655 while (pos == 0 && glyph < end)
10656 {
10657 string = glyph->object;
10658 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10659 if (glyph < end)
10660 pos = string_buffer_position (w, glyph->object, string_before_pos);
10661 }
10662
10663 while (glyph < end)
10664 {
10665 pos = XINT (Fnext_single_char_property_change
10666 (make_number (pos), Qdisplay, Qnil, limit));
10667 if (pos > pt_old)
10668 break;
10669 /* Skip glyphs from the same string. */
10670 string = glyph->object;
10671 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10672 /* Skip glyphs from an overlay. */
10673 while (glyph < end
10674 && ! string_buffer_position (w, glyph->object, pos))
10675 {
10676 string = glyph->object;
10677 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10678 }
10679 }
10680 }
10681
10682 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10683 w->cursor.x = x;
10684 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10685 w->cursor.y = row->y + dy;
10686
10687 if (w == XWINDOW (selected_window))
10688 {
10689 if (!row->continued_p
10690 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10691 && row->x == 0)
10692 {
10693 this_line_buffer = XBUFFER (w->buffer);
10694
10695 CHARPOS (this_line_start_pos)
10696 = MATRIX_ROW_START_CHARPOS (row) + delta;
10697 BYTEPOS (this_line_start_pos)
10698 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10699
10700 CHARPOS (this_line_end_pos)
10701 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10702 BYTEPOS (this_line_end_pos)
10703 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10704
10705 this_line_y = w->cursor.y;
10706 this_line_pixel_height = row->height;
10707 this_line_vpos = w->cursor.vpos;
10708 this_line_start_x = row->x;
10709 }
10710 else
10711 CHARPOS (this_line_start_pos) = 0;
10712 }
10713 }
10714
10715
10716 /* Run window scroll functions, if any, for WINDOW with new window
10717 start STARTP. Sets the window start of WINDOW to that position.
10718
10719 We assume that the window's buffer is really current. */
10720
10721 static INLINE struct text_pos
10722 run_window_scroll_functions (window, startp)
10723 Lisp_Object window;
10724 struct text_pos startp;
10725 {
10726 struct window *w = XWINDOW (window);
10727 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10728
10729 if (current_buffer != XBUFFER (w->buffer))
10730 abort ();
10731
10732 if (!NILP (Vwindow_scroll_functions))
10733 {
10734 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10735 make_number (CHARPOS (startp)));
10736 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10737 /* In case the hook functions switch buffers. */
10738 if (current_buffer != XBUFFER (w->buffer))
10739 set_buffer_internal_1 (XBUFFER (w->buffer));
10740 }
10741
10742 return startp;
10743 }
10744
10745
10746 /* Make sure the line containing the cursor is fully visible.
10747 A value of 1 means there is nothing to be done.
10748 (Either the line is fully visible, or it cannot be made so,
10749 or we cannot tell.)
10750 A value of 0 means the caller should do scrolling
10751 as if point had gone off the screen. */
10752
10753 static int
10754 make_cursor_line_fully_visible (w)
10755 struct window *w;
10756 {
10757 struct glyph_matrix *matrix;
10758 struct glyph_row *row;
10759 int window_height;
10760
10761 /* It's not always possible to find the cursor, e.g, when a window
10762 is full of overlay strings. Don't do anything in that case. */
10763 if (w->cursor.vpos < 0)
10764 return 1;
10765
10766 matrix = w->desired_matrix;
10767 row = MATRIX_ROW (matrix, w->cursor.vpos);
10768
10769 /* If the cursor row is not partially visible, there's nothing to do. */
10770 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10771 return 1;
10772
10773 /* If the row the cursor is in is taller than the window's height,
10774 it's not clear what to do, so do nothing. */
10775 window_height = window_box_height (w);
10776 if (row->height >= window_height)
10777 return 1;
10778
10779 return 0;
10780
10781 #if 0
10782 /* This code used to try to scroll the window just enough to make
10783 the line visible. It returned 0 to say that the caller should
10784 allocate larger glyph matrices. */
10785
10786 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10787 {
10788 int dy = row->height - row->visible_height;
10789 w->vscroll = 0;
10790 w->cursor.y += dy;
10791 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10792 }
10793 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10794 {
10795 int dy = - (row->height - row->visible_height);
10796 w->vscroll = dy;
10797 w->cursor.y += dy;
10798 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10799 }
10800
10801 /* When we change the cursor y-position of the selected window,
10802 change this_line_y as well so that the display optimization for
10803 the cursor line of the selected window in redisplay_internal uses
10804 the correct y-position. */
10805 if (w == XWINDOW (selected_window))
10806 this_line_y = w->cursor.y;
10807
10808 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10809 redisplay with larger matrices. */
10810 if (matrix->nrows < required_matrix_height (w))
10811 {
10812 fonts_changed_p = 1;
10813 return 0;
10814 }
10815
10816 return 1;
10817 #endif /* 0 */
10818 }
10819
10820
10821 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10822 non-zero means only WINDOW is redisplayed in redisplay_internal.
10823 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10824 in redisplay_window to bring a partially visible line into view in
10825 the case that only the cursor has moved.
10826
10827 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10828 last screen line's vertical height extends past the end of the screen.
10829
10830 Value is
10831
10832 1 if scrolling succeeded
10833
10834 0 if scrolling didn't find point.
10835
10836 -1 if new fonts have been loaded so that we must interrupt
10837 redisplay, adjust glyph matrices, and try again. */
10838
10839 enum
10840 {
10841 SCROLLING_SUCCESS,
10842 SCROLLING_FAILED,
10843 SCROLLING_NEED_LARGER_MATRICES
10844 };
10845
10846 static int
10847 try_scrolling (window, just_this_one_p, scroll_conservatively,
10848 scroll_step, temp_scroll_step, last_line_misfit)
10849 Lisp_Object window;
10850 int just_this_one_p;
10851 EMACS_INT scroll_conservatively, scroll_step;
10852 int temp_scroll_step;
10853 int last_line_misfit;
10854 {
10855 struct window *w = XWINDOW (window);
10856 struct frame *f = XFRAME (w->frame);
10857 struct text_pos scroll_margin_pos;
10858 struct text_pos pos;
10859 struct text_pos startp;
10860 struct it it;
10861 Lisp_Object window_end;
10862 int this_scroll_margin;
10863 int dy = 0;
10864 int scroll_max;
10865 int rc;
10866 int amount_to_scroll = 0;
10867 Lisp_Object aggressive;
10868 int height;
10869 int end_scroll_margin;
10870
10871 #if GLYPH_DEBUG
10872 debug_method_add (w, "try_scrolling");
10873 #endif
10874
10875 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10876
10877 /* Compute scroll margin height in pixels. We scroll when point is
10878 within this distance from the top or bottom of the window. */
10879 if (scroll_margin > 0)
10880 {
10881 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10882 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10883 }
10884 else
10885 this_scroll_margin = 0;
10886
10887 /* Compute how much we should try to scroll maximally to bring point
10888 into view. */
10889 if (scroll_step || scroll_conservatively || temp_scroll_step)
10890 scroll_max = max (scroll_step,
10891 max (scroll_conservatively, temp_scroll_step));
10892 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10893 || NUMBERP (current_buffer->scroll_up_aggressively))
10894 /* We're trying to scroll because of aggressive scrolling
10895 but no scroll_step is set. Choose an arbitrary one. Maybe
10896 there should be a variable for this. */
10897 scroll_max = 10;
10898 else
10899 scroll_max = 0;
10900 scroll_max *= FRAME_LINE_HEIGHT (f);
10901
10902 /* Decide whether we have to scroll down. Start at the window end
10903 and move this_scroll_margin up to find the position of the scroll
10904 margin. */
10905 window_end = Fwindow_end (window, Qt);
10906
10907 too_near_end:
10908
10909 CHARPOS (scroll_margin_pos) = XINT (window_end);
10910 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10911
10912 end_scroll_margin = this_scroll_margin + !!last_line_misfit;
10913 if (end_scroll_margin)
10914 {
10915 start_display (&it, w, scroll_margin_pos);
10916 move_it_vertically (&it, - end_scroll_margin);
10917 scroll_margin_pos = it.current.pos;
10918 }
10919
10920 if (PT >= CHARPOS (scroll_margin_pos))
10921 {
10922 int y0;
10923
10924 /* Point is in the scroll margin at the bottom of the window, or
10925 below. Compute a new window start that makes point visible. */
10926
10927 /* Compute the distance from the scroll margin to PT.
10928 Give up if the distance is greater than scroll_max. */
10929 start_display (&it, w, scroll_margin_pos);
10930 y0 = it.current_y;
10931 move_it_to (&it, PT, 0, it.last_visible_y, -1,
10932 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10933
10934 /* To make point visible, we have to move the window start
10935 down so that the line the cursor is in is visible, which
10936 means we have to add in the height of the cursor line. */
10937 dy = line_bottom_y (&it) - y0;
10938
10939 if (dy > scroll_max)
10940 return SCROLLING_FAILED;
10941
10942 /* Move the window start down. If scrolling conservatively,
10943 move it just enough down to make point visible. If
10944 scroll_step is set, move it down by scroll_step. */
10945 start_display (&it, w, startp);
10946
10947 if (scroll_conservatively)
10948 /* Set AMOUNT_TO_SCROLL to at least one line,
10949 and at most scroll_conservatively lines. */
10950 amount_to_scroll
10951 = min (max (dy, FRAME_LINE_HEIGHT (f)),
10952 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
10953 else if (scroll_step || temp_scroll_step)
10954 amount_to_scroll = scroll_max;
10955 else
10956 {
10957 aggressive = current_buffer->scroll_up_aggressively;
10958 height = WINDOW_BOX_TEXT_HEIGHT (w);
10959 if (NUMBERP (aggressive))
10960 amount_to_scroll = XFLOATINT (aggressive) * height;
10961 }
10962
10963 if (amount_to_scroll <= 0)
10964 return SCROLLING_FAILED;
10965
10966 /* If moving by amount_to_scroll leaves STARTP unchanged,
10967 move it down one screen line. */
10968
10969 move_it_vertically (&it, amount_to_scroll);
10970 if (CHARPOS (it.current.pos) == CHARPOS (startp))
10971 move_it_by_lines (&it, 1, 1);
10972 startp = it.current.pos;
10973 }
10974 else
10975 {
10976 /* See if point is inside the scroll margin at the top of the
10977 window. */
10978 scroll_margin_pos = startp;
10979 if (this_scroll_margin)
10980 {
10981 start_display (&it, w, startp);
10982 move_it_vertically (&it, this_scroll_margin);
10983 scroll_margin_pos = it.current.pos;
10984 }
10985
10986 if (PT < CHARPOS (scroll_margin_pos))
10987 {
10988 /* Point is in the scroll margin at the top of the window or
10989 above what is displayed in the window. */
10990 int y0;
10991
10992 /* Compute the vertical distance from PT to the scroll
10993 margin position. Give up if distance is greater than
10994 scroll_max. */
10995 SET_TEXT_POS (pos, PT, PT_BYTE);
10996 start_display (&it, w, pos);
10997 y0 = it.current_y;
10998 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
10999 it.last_visible_y, -1,
11000 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11001 dy = it.current_y - y0;
11002 if (dy > scroll_max)
11003 return SCROLLING_FAILED;
11004
11005 /* Compute new window start. */
11006 start_display (&it, w, startp);
11007
11008 if (scroll_conservatively)
11009 amount_to_scroll =
11010 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11011 else if (scroll_step || temp_scroll_step)
11012 amount_to_scroll = scroll_max;
11013 else
11014 {
11015 aggressive = current_buffer->scroll_down_aggressively;
11016 height = WINDOW_BOX_TEXT_HEIGHT (w);
11017 if (NUMBERP (aggressive))
11018 amount_to_scroll = XFLOATINT (aggressive) * height;
11019 }
11020
11021 if (amount_to_scroll <= 0)
11022 return SCROLLING_FAILED;
11023
11024 move_it_vertically (&it, - amount_to_scroll);
11025 startp = it.current.pos;
11026 }
11027 }
11028
11029 /* Run window scroll functions. */
11030 startp = run_window_scroll_functions (window, startp);
11031
11032 /* Display the window. Give up if new fonts are loaded, or if point
11033 doesn't appear. */
11034 if (!try_window (window, startp))
11035 rc = SCROLLING_NEED_LARGER_MATRICES;
11036 else if (w->cursor.vpos < 0)
11037 {
11038 clear_glyph_matrix (w->desired_matrix);
11039 rc = SCROLLING_FAILED;
11040 }
11041 else
11042 {
11043 /* Maybe forget recorded base line for line number display. */
11044 if (!just_this_one_p
11045 || current_buffer->clip_changed
11046 || BEG_UNCHANGED < CHARPOS (startp))
11047 w->base_line_number = Qnil;
11048
11049 /* If cursor ends up on a partially visible line,
11050 treat that as being off the bottom of the screen. */
11051 if (! make_cursor_line_fully_visible (w))
11052 {
11053 clear_glyph_matrix (w->desired_matrix);
11054 last_line_misfit = 1;
11055 goto too_near_end;
11056 }
11057 rc = SCROLLING_SUCCESS;
11058 }
11059
11060 return rc;
11061 }
11062
11063
11064 /* Compute a suitable window start for window W if display of W starts
11065 on a continuation line. Value is non-zero if a new window start
11066 was computed.
11067
11068 The new window start will be computed, based on W's width, starting
11069 from the start of the continued line. It is the start of the
11070 screen line with the minimum distance from the old start W->start. */
11071
11072 static int
11073 compute_window_start_on_continuation_line (w)
11074 struct window *w;
11075 {
11076 struct text_pos pos, start_pos;
11077 int window_start_changed_p = 0;
11078
11079 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11080
11081 /* If window start is on a continuation line... Window start may be
11082 < BEGV in case there's invisible text at the start of the
11083 buffer (M-x rmail, for example). */
11084 if (CHARPOS (start_pos) > BEGV
11085 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11086 {
11087 struct it it;
11088 struct glyph_row *row;
11089
11090 /* Handle the case that the window start is out of range. */
11091 if (CHARPOS (start_pos) < BEGV)
11092 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11093 else if (CHARPOS (start_pos) > ZV)
11094 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11095
11096 /* Find the start of the continued line. This should be fast
11097 because scan_buffer is fast (newline cache). */
11098 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11099 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11100 row, DEFAULT_FACE_ID);
11101 reseat_at_previous_visible_line_start (&it);
11102
11103 /* If the line start is "too far" away from the window start,
11104 say it takes too much time to compute a new window start. */
11105 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11106 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11107 {
11108 int min_distance, distance;
11109
11110 /* Move forward by display lines to find the new window
11111 start. If window width was enlarged, the new start can
11112 be expected to be > the old start. If window width was
11113 decreased, the new window start will be < the old start.
11114 So, we're looking for the display line start with the
11115 minimum distance from the old window start. */
11116 pos = it.current.pos;
11117 min_distance = INFINITY;
11118 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11119 distance < min_distance)
11120 {
11121 min_distance = distance;
11122 pos = it.current.pos;
11123 move_it_by_lines (&it, 1, 0);
11124 }
11125
11126 /* Set the window start there. */
11127 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11128 window_start_changed_p = 1;
11129 }
11130 }
11131
11132 return window_start_changed_p;
11133 }
11134
11135
11136 /* Try cursor movement in case text has not changed in window WINDOW,
11137 with window start STARTP. Value is
11138
11139 CURSOR_MOVEMENT_SUCCESS if successful
11140
11141 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11142
11143 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11144 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11145 we want to scroll as if scroll-step were set to 1. See the code.
11146
11147 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11148 which case we have to abort this redisplay, and adjust matrices
11149 first. */
11150
11151 enum
11152 {
11153 CURSOR_MOVEMENT_SUCCESS,
11154 CURSOR_MOVEMENT_CANNOT_BE_USED,
11155 CURSOR_MOVEMENT_MUST_SCROLL,
11156 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11157 };
11158
11159 static int
11160 try_cursor_movement (window, startp, scroll_step)
11161 Lisp_Object window;
11162 struct text_pos startp;
11163 int *scroll_step;
11164 {
11165 struct window *w = XWINDOW (window);
11166 struct frame *f = XFRAME (w->frame);
11167 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11168
11169 #if GLYPH_DEBUG
11170 if (inhibit_try_cursor_movement)
11171 return rc;
11172 #endif
11173
11174 /* Handle case where text has not changed, only point, and it has
11175 not moved off the frame. */
11176 if (/* Point may be in this window. */
11177 PT >= CHARPOS (startp)
11178 /* Selective display hasn't changed. */
11179 && !current_buffer->clip_changed
11180 /* Function force-mode-line-update is used to force a thorough
11181 redisplay. It sets either windows_or_buffers_changed or
11182 update_mode_lines. So don't take a shortcut here for these
11183 cases. */
11184 && !update_mode_lines
11185 && !windows_or_buffers_changed
11186 && !cursor_type_changed
11187 /* Can't use this case if highlighting a region. When a
11188 region exists, cursor movement has to do more than just
11189 set the cursor. */
11190 && !(!NILP (Vtransient_mark_mode)
11191 && !NILP (current_buffer->mark_active))
11192 && NILP (w->region_showing)
11193 && NILP (Vshow_trailing_whitespace)
11194 /* Right after splitting windows, last_point may be nil. */
11195 && INTEGERP (w->last_point)
11196 /* This code is not used for mini-buffer for the sake of the case
11197 of redisplaying to replace an echo area message; since in
11198 that case the mini-buffer contents per se are usually
11199 unchanged. This code is of no real use in the mini-buffer
11200 since the handling of this_line_start_pos, etc., in redisplay
11201 handles the same cases. */
11202 && !EQ (window, minibuf_window)
11203 /* When splitting windows or for new windows, it happens that
11204 redisplay is called with a nil window_end_vpos or one being
11205 larger than the window. This should really be fixed in
11206 window.c. I don't have this on my list, now, so we do
11207 approximately the same as the old redisplay code. --gerd. */
11208 && INTEGERP (w->window_end_vpos)
11209 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11210 && (FRAME_WINDOW_P (f)
11211 || !MARKERP (Voverlay_arrow_position)
11212 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
11213 {
11214 int this_scroll_margin;
11215 struct glyph_row *row = NULL;
11216
11217 #if GLYPH_DEBUG
11218 debug_method_add (w, "cursor movement");
11219 #endif
11220
11221 /* Scroll if point within this distance from the top or bottom
11222 of the window. This is a pixel value. */
11223 this_scroll_margin = max (0, scroll_margin);
11224 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11225 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11226
11227 /* Start with the row the cursor was displayed during the last
11228 not paused redisplay. Give up if that row is not valid. */
11229 if (w->last_cursor.vpos < 0
11230 || w->last_cursor.vpos >= w->current_matrix->nrows)
11231 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11232 else
11233 {
11234 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11235 if (row->mode_line_p)
11236 ++row;
11237 if (!row->enabled_p)
11238 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11239 }
11240
11241 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11242 {
11243 int scroll_p = 0;
11244 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11245
11246 if (PT > XFASTINT (w->last_point))
11247 {
11248 /* Point has moved forward. */
11249 while (MATRIX_ROW_END_CHARPOS (row) < PT
11250 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11251 {
11252 xassert (row->enabled_p);
11253 ++row;
11254 }
11255
11256 /* The end position of a row equals the start position
11257 of the next row. If PT is there, we would rather
11258 display it in the next line. */
11259 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11260 && MATRIX_ROW_END_CHARPOS (row) == PT
11261 && !cursor_row_p (w, row))
11262 ++row;
11263
11264 /* If within the scroll margin, scroll. Note that
11265 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11266 the next line would be drawn, and that
11267 this_scroll_margin can be zero. */
11268 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11269 || PT > MATRIX_ROW_END_CHARPOS (row)
11270 /* Line is completely visible last line in window
11271 and PT is to be set in the next line. */
11272 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11273 && PT == MATRIX_ROW_END_CHARPOS (row)
11274 && !row->ends_at_zv_p
11275 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11276 scroll_p = 1;
11277 }
11278 else if (PT < XFASTINT (w->last_point))
11279 {
11280 /* Cursor has to be moved backward. Note that PT >=
11281 CHARPOS (startp) because of the outer
11282 if-statement. */
11283 while (!row->mode_line_p
11284 && (MATRIX_ROW_START_CHARPOS (row) > PT
11285 || (MATRIX_ROW_START_CHARPOS (row) == PT
11286 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11287 && (row->y > this_scroll_margin
11288 || CHARPOS (startp) == BEGV))
11289 {
11290 xassert (row->enabled_p);
11291 --row;
11292 }
11293
11294 /* Consider the following case: Window starts at BEGV,
11295 there is invisible, intangible text at BEGV, so that
11296 display starts at some point START > BEGV. It can
11297 happen that we are called with PT somewhere between
11298 BEGV and START. Try to handle that case. */
11299 if (row < w->current_matrix->rows
11300 || row->mode_line_p)
11301 {
11302 row = w->current_matrix->rows;
11303 if (row->mode_line_p)
11304 ++row;
11305 }
11306
11307 /* Due to newlines in overlay strings, we may have to
11308 skip forward over overlay strings. */
11309 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11310 && MATRIX_ROW_END_CHARPOS (row) == PT
11311 && !cursor_row_p (w, row))
11312 ++row;
11313
11314 /* If within the scroll margin, scroll. */
11315 if (row->y < this_scroll_margin
11316 && CHARPOS (startp) != BEGV)
11317 scroll_p = 1;
11318 }
11319
11320 if (PT < MATRIX_ROW_START_CHARPOS (row)
11321 || PT > MATRIX_ROW_END_CHARPOS (row))
11322 {
11323 /* if PT is not in the glyph row, give up. */
11324 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11325 }
11326 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11327 {
11328 if (PT == MATRIX_ROW_END_CHARPOS (row)
11329 && !row->ends_at_zv_p
11330 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11331 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11332 else if (row->height > window_box_height (w))
11333 {
11334 /* If we end up in a partially visible line, let's
11335 make it fully visible, except when it's taller
11336 than the window, in which case we can't do much
11337 about it. */
11338 *scroll_step = 1;
11339 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11340 }
11341 else
11342 {
11343 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11344 if (!make_cursor_line_fully_visible (w))
11345 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11346 else
11347 rc = CURSOR_MOVEMENT_SUCCESS;
11348 }
11349 }
11350 else if (scroll_p)
11351 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11352 else
11353 {
11354 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11355 rc = CURSOR_MOVEMENT_SUCCESS;
11356 }
11357 }
11358 }
11359
11360 return rc;
11361 }
11362
11363 void
11364 set_vertical_scroll_bar (w)
11365 struct window *w;
11366 {
11367 int start, end, whole;
11368
11369 /* Calculate the start and end positions for the current window.
11370 At some point, it would be nice to choose between scrollbars
11371 which reflect the whole buffer size, with special markers
11372 indicating narrowing, and scrollbars which reflect only the
11373 visible region.
11374
11375 Note that mini-buffers sometimes aren't displaying any text. */
11376 if (!MINI_WINDOW_P (w)
11377 || (w == XWINDOW (minibuf_window)
11378 && NILP (echo_area_buffer[0])))
11379 {
11380 struct buffer *buf = XBUFFER (w->buffer);
11381 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11382 start = marker_position (w->start) - BUF_BEGV (buf);
11383 /* I don't think this is guaranteed to be right. For the
11384 moment, we'll pretend it is. */
11385 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11386
11387 if (end < start)
11388 end = start;
11389 if (whole < (end - start))
11390 whole = end - start;
11391 }
11392 else
11393 start = end = whole = 0;
11394
11395 /* Indicate what this scroll bar ought to be displaying now. */
11396 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11397 }
11398
11399 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11400 selected_window is redisplayed.
11401
11402 We can return without actually redisplaying the window if
11403 fonts_changed_p is nonzero. In that case, redisplay_internal will
11404 retry. */
11405
11406 static void
11407 redisplay_window (window, just_this_one_p)
11408 Lisp_Object window;
11409 int just_this_one_p;
11410 {
11411 struct window *w = XWINDOW (window);
11412 struct frame *f = XFRAME (w->frame);
11413 struct buffer *buffer = XBUFFER (w->buffer);
11414 struct buffer *old = current_buffer;
11415 struct text_pos lpoint, opoint, startp;
11416 int update_mode_line;
11417 int tem;
11418 struct it it;
11419 /* Record it now because it's overwritten. */
11420 int current_matrix_up_to_date_p = 0;
11421 /* This is less strict than current_matrix_up_to_date_p.
11422 It indictes that the buffer contents and narrowing are unchanged. */
11423 int buffer_unchanged_p = 0;
11424 int temp_scroll_step = 0;
11425 int count = SPECPDL_INDEX ();
11426 int rc;
11427 int centering_position;
11428 int last_line_misfit = 0;
11429
11430 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11431 opoint = lpoint;
11432
11433 /* W must be a leaf window here. */
11434 xassert (!NILP (w->buffer));
11435 #if GLYPH_DEBUG
11436 *w->desired_matrix->method = 0;
11437 #endif
11438
11439 specbind (Qinhibit_point_motion_hooks, Qt);
11440
11441 reconsider_clip_changes (w, buffer);
11442
11443 /* Has the mode line to be updated? */
11444 update_mode_line = (!NILP (w->update_mode_line)
11445 || update_mode_lines
11446 || buffer->clip_changed
11447 || buffer->prevent_redisplay_optimizations_p);
11448
11449 if (MINI_WINDOW_P (w))
11450 {
11451 if (w == XWINDOW (echo_area_window)
11452 && !NILP (echo_area_buffer[0]))
11453 {
11454 if (update_mode_line)
11455 /* We may have to update a tty frame's menu bar or a
11456 tool-bar. Example `M-x C-h C-h C-g'. */
11457 goto finish_menu_bars;
11458 else
11459 /* We've already displayed the echo area glyphs in this window. */
11460 goto finish_scroll_bars;
11461 }
11462 else if ((w != XWINDOW (minibuf_window)
11463 || minibuf_level == 0)
11464 /* When buffer is nonempty, redisplay window normally. */
11465 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11466 /* Quail displays non-mini buffers in minibuffer window.
11467 In that case, redisplay the window normally. */
11468 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11469 {
11470 /* W is a mini-buffer window, but it's not active, so clear
11471 it. */
11472 int yb = window_text_bottom_y (w);
11473 struct glyph_row *row;
11474 int y;
11475
11476 for (y = 0, row = w->desired_matrix->rows;
11477 y < yb;
11478 y += row->height, ++row)
11479 blank_row (w, row, y);
11480 goto finish_scroll_bars;
11481 }
11482
11483 clear_glyph_matrix (w->desired_matrix);
11484 }
11485
11486 /* Otherwise set up data on this window; select its buffer and point
11487 value. */
11488 /* Really select the buffer, for the sake of buffer-local
11489 variables. */
11490 set_buffer_internal_1 (XBUFFER (w->buffer));
11491 SET_TEXT_POS (opoint, PT, PT_BYTE);
11492
11493 current_matrix_up_to_date_p
11494 = (!NILP (w->window_end_valid)
11495 && !current_buffer->clip_changed
11496 && !current_buffer->prevent_redisplay_optimizations_p
11497 && XFASTINT (w->last_modified) >= MODIFF
11498 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11499
11500 buffer_unchanged_p
11501 = (!NILP (w->window_end_valid)
11502 && !current_buffer->clip_changed
11503 && XFASTINT (w->last_modified) >= MODIFF
11504 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11505
11506 /* When windows_or_buffers_changed is non-zero, we can't rely on
11507 the window end being valid, so set it to nil there. */
11508 if (windows_or_buffers_changed)
11509 {
11510 /* If window starts on a continuation line, maybe adjust the
11511 window start in case the window's width changed. */
11512 if (XMARKER (w->start)->buffer == current_buffer)
11513 compute_window_start_on_continuation_line (w);
11514
11515 w->window_end_valid = Qnil;
11516 }
11517
11518 /* Some sanity checks. */
11519 CHECK_WINDOW_END (w);
11520 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11521 abort ();
11522 if (BYTEPOS (opoint) < CHARPOS (opoint))
11523 abort ();
11524
11525 /* If %c is in mode line, update it if needed. */
11526 if (!NILP (w->column_number_displayed)
11527 /* This alternative quickly identifies a common case
11528 where no change is needed. */
11529 && !(PT == XFASTINT (w->last_point)
11530 && XFASTINT (w->last_modified) >= MODIFF
11531 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11532 && (XFASTINT (w->column_number_displayed)
11533 != (int) current_column ())) /* iftc */
11534 update_mode_line = 1;
11535
11536 /* Count number of windows showing the selected buffer. An indirect
11537 buffer counts as its base buffer. */
11538 if (!just_this_one_p)
11539 {
11540 struct buffer *current_base, *window_base;
11541 current_base = current_buffer;
11542 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11543 if (current_base->base_buffer)
11544 current_base = current_base->base_buffer;
11545 if (window_base->base_buffer)
11546 window_base = window_base->base_buffer;
11547 if (current_base == window_base)
11548 buffer_shared++;
11549 }
11550
11551 /* Point refers normally to the selected window. For any other
11552 window, set up appropriate value. */
11553 if (!EQ (window, selected_window))
11554 {
11555 int new_pt = XMARKER (w->pointm)->charpos;
11556 int new_pt_byte = marker_byte_position (w->pointm);
11557 if (new_pt < BEGV)
11558 {
11559 new_pt = BEGV;
11560 new_pt_byte = BEGV_BYTE;
11561 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11562 }
11563 else if (new_pt > (ZV - 1))
11564 {
11565 new_pt = ZV;
11566 new_pt_byte = ZV_BYTE;
11567 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11568 }
11569
11570 /* We don't use SET_PT so that the point-motion hooks don't run. */
11571 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11572 }
11573
11574 /* If any of the character widths specified in the display table
11575 have changed, invalidate the width run cache. It's true that
11576 this may be a bit late to catch such changes, but the rest of
11577 redisplay goes (non-fatally) haywire when the display table is
11578 changed, so why should we worry about doing any better? */
11579 if (current_buffer->width_run_cache)
11580 {
11581 struct Lisp_Char_Table *disptab = buffer_display_table ();
11582
11583 if (! disptab_matches_widthtab (disptab,
11584 XVECTOR (current_buffer->width_table)))
11585 {
11586 invalidate_region_cache (current_buffer,
11587 current_buffer->width_run_cache,
11588 BEG, Z);
11589 recompute_width_table (current_buffer, disptab);
11590 }
11591 }
11592
11593 /* If window-start is screwed up, choose a new one. */
11594 if (XMARKER (w->start)->buffer != current_buffer)
11595 goto recenter;
11596
11597 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11598
11599 /* If someone specified a new starting point but did not insist,
11600 check whether it can be used. */
11601 if (!NILP (w->optional_new_start)
11602 && CHARPOS (startp) >= BEGV
11603 && CHARPOS (startp) <= ZV)
11604 {
11605 w->optional_new_start = Qnil;
11606 start_display (&it, w, startp);
11607 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11608 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11609 if (IT_CHARPOS (it) == PT)
11610 w->force_start = Qt;
11611 /* IT may overshoot PT if text at PT is invisible. */
11612 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11613 w->force_start = Qt;
11614
11615
11616 }
11617
11618 /* Handle case where place to start displaying has been specified,
11619 unless the specified location is outside the accessible range. */
11620 if (!NILP (w->force_start)
11621 || w->frozen_window_start_p)
11622 {
11623 /* We set this later on if we have to adjust point. */
11624 int new_vpos = -1;
11625
11626 w->force_start = Qnil;
11627 w->vscroll = 0;
11628 w->window_end_valid = Qnil;
11629
11630 /* Forget any recorded base line for line number display. */
11631 if (!buffer_unchanged_p)
11632 w->base_line_number = Qnil;
11633
11634 /* Redisplay the mode line. Select the buffer properly for that.
11635 Also, run the hook window-scroll-functions
11636 because we have scrolled. */
11637 /* Note, we do this after clearing force_start because
11638 if there's an error, it is better to forget about force_start
11639 than to get into an infinite loop calling the hook functions
11640 and having them get more errors. */
11641 if (!update_mode_line
11642 || ! NILP (Vwindow_scroll_functions))
11643 {
11644 update_mode_line = 1;
11645 w->update_mode_line = Qt;
11646 startp = run_window_scroll_functions (window, startp);
11647 }
11648
11649 w->last_modified = make_number (0);
11650 w->last_overlay_modified = make_number (0);
11651 if (CHARPOS (startp) < BEGV)
11652 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11653 else if (CHARPOS (startp) > ZV)
11654 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11655
11656 /* Redisplay, then check if cursor has been set during the
11657 redisplay. Give up if new fonts were loaded. */
11658 if (!try_window (window, startp))
11659 {
11660 w->force_start = Qt;
11661 clear_glyph_matrix (w->desired_matrix);
11662 goto need_larger_matrices;
11663 }
11664
11665 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11666 {
11667 /* If point does not appear, try to move point so it does
11668 appear. The desired matrix has been built above, so we
11669 can use it here. */
11670 new_vpos = window_box_height (w) / 2;
11671 }
11672
11673 if (!make_cursor_line_fully_visible (w))
11674 {
11675 /* Point does appear, but on a line partly visible at end of window.
11676 Move it back to a fully-visible line. */
11677 new_vpos = window_box_height (w);
11678 }
11679
11680 /* If we need to move point for either of the above reasons,
11681 now actually do it. */
11682 if (new_vpos >= 0)
11683 {
11684 struct glyph_row *row;
11685
11686 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11687 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11688 ++row;
11689
11690 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11691 MATRIX_ROW_START_BYTEPOS (row));
11692
11693 if (w != XWINDOW (selected_window))
11694 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11695 else if (current_buffer == old)
11696 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11697
11698 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11699
11700 /* If we are highlighting the region, then we just changed
11701 the region, so redisplay to show it. */
11702 if (!NILP (Vtransient_mark_mode)
11703 && !NILP (current_buffer->mark_active))
11704 {
11705 clear_glyph_matrix (w->desired_matrix);
11706 if (!try_window (window, startp))
11707 goto need_larger_matrices;
11708 }
11709 }
11710
11711 #if GLYPH_DEBUG
11712 debug_method_add (w, "forced window start");
11713 #endif
11714 goto done;
11715 }
11716
11717 /* Handle case where text has not changed, only point, and it has
11718 not moved off the frame, and we are not retrying after hscroll.
11719 (current_matrix_up_to_date_p is nonzero when retrying.) */
11720 if (current_matrix_up_to_date_p
11721 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11722 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11723 {
11724 switch (rc)
11725 {
11726 case CURSOR_MOVEMENT_SUCCESS:
11727 goto done;
11728
11729 #if 0 /* try_cursor_movement never returns this value. */
11730 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11731 goto need_larger_matrices;
11732 #endif
11733
11734 case CURSOR_MOVEMENT_MUST_SCROLL:
11735 goto try_to_scroll;
11736
11737 default:
11738 abort ();
11739 }
11740 }
11741 /* If current starting point was originally the beginning of a line
11742 but no longer is, find a new starting point. */
11743 else if (!NILP (w->start_at_line_beg)
11744 && !(CHARPOS (startp) <= BEGV
11745 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11746 {
11747 #if GLYPH_DEBUG
11748 debug_method_add (w, "recenter 1");
11749 #endif
11750 goto recenter;
11751 }
11752
11753 /* Try scrolling with try_window_id. Value is > 0 if update has
11754 been done, it is -1 if we know that the same window start will
11755 not work. It is 0 if unsuccessful for some other reason. */
11756 else if ((tem = try_window_id (w)) != 0)
11757 {
11758 #if GLYPH_DEBUG
11759 debug_method_add (w, "try_window_id %d", tem);
11760 #endif
11761
11762 if (fonts_changed_p)
11763 goto need_larger_matrices;
11764 if (tem > 0)
11765 goto done;
11766
11767 /* Otherwise try_window_id has returned -1 which means that we
11768 don't want the alternative below this comment to execute. */
11769 }
11770 else if (CHARPOS (startp) >= BEGV
11771 && CHARPOS (startp) <= ZV
11772 && PT >= CHARPOS (startp)
11773 && (CHARPOS (startp) < ZV
11774 /* Avoid starting at end of buffer. */
11775 || CHARPOS (startp) == BEGV
11776 || (XFASTINT (w->last_modified) >= MODIFF
11777 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11778 {
11779 #if GLYPH_DEBUG
11780 debug_method_add (w, "same window start");
11781 #endif
11782
11783 /* Try to redisplay starting at same place as before.
11784 If point has not moved off frame, accept the results. */
11785 if (!current_matrix_up_to_date_p
11786 /* Don't use try_window_reusing_current_matrix in this case
11787 because a window scroll function can have changed the
11788 buffer. */
11789 || !NILP (Vwindow_scroll_functions)
11790 || MINI_WINDOW_P (w)
11791 || !try_window_reusing_current_matrix (w))
11792 {
11793 IF_DEBUG (debug_method_add (w, "1"));
11794 try_window (window, startp);
11795 }
11796
11797 if (fonts_changed_p)
11798 goto need_larger_matrices;
11799
11800 if (w->cursor.vpos >= 0)
11801 {
11802 if (!just_this_one_p
11803 || current_buffer->clip_changed
11804 || BEG_UNCHANGED < CHARPOS (startp))
11805 /* Forget any recorded base line for line number display. */
11806 w->base_line_number = Qnil;
11807
11808 if (!make_cursor_line_fully_visible (w))
11809 {
11810 clear_glyph_matrix (w->desired_matrix);
11811 last_line_misfit = 1;
11812 }
11813 /* Drop through and scroll. */
11814 else
11815 goto done;
11816 }
11817 else
11818 clear_glyph_matrix (w->desired_matrix);
11819 }
11820
11821 try_to_scroll:
11822
11823 w->last_modified = make_number (0);
11824 w->last_overlay_modified = make_number (0);
11825
11826 /* Redisplay the mode line. Select the buffer properly for that. */
11827 if (!update_mode_line)
11828 {
11829 update_mode_line = 1;
11830 w->update_mode_line = Qt;
11831 }
11832
11833 /* Try to scroll by specified few lines. */
11834 if ((scroll_conservatively
11835 || scroll_step
11836 || temp_scroll_step
11837 || NUMBERP (current_buffer->scroll_up_aggressively)
11838 || NUMBERP (current_buffer->scroll_down_aggressively))
11839 && !current_buffer->clip_changed
11840 && CHARPOS (startp) >= BEGV
11841 && CHARPOS (startp) <= ZV)
11842 {
11843 /* The function returns -1 if new fonts were loaded, 1 if
11844 successful, 0 if not successful. */
11845 int rc = try_scrolling (window, just_this_one_p,
11846 scroll_conservatively,
11847 scroll_step,
11848 temp_scroll_step, last_line_misfit);
11849 switch (rc)
11850 {
11851 case SCROLLING_SUCCESS:
11852 goto done;
11853
11854 case SCROLLING_NEED_LARGER_MATRICES:
11855 goto need_larger_matrices;
11856
11857 case SCROLLING_FAILED:
11858 break;
11859
11860 default:
11861 abort ();
11862 }
11863 }
11864
11865 /* Finally, just choose place to start which centers point */
11866
11867 recenter:
11868 centering_position = window_box_height (w) / 2;
11869
11870 point_at_top:
11871 /* Jump here with centering_position already set to 0. */
11872
11873 #if GLYPH_DEBUG
11874 debug_method_add (w, "recenter");
11875 #endif
11876
11877 /* w->vscroll = 0; */
11878
11879 /* Forget any previously recorded base line for line number display. */
11880 if (!buffer_unchanged_p)
11881 w->base_line_number = Qnil;
11882
11883 /* Move backward half the height of the window. */
11884 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11885 it.current_y = it.last_visible_y;
11886 move_it_vertically_backward (&it, centering_position);
11887 xassert (IT_CHARPOS (it) >= BEGV);
11888
11889 /* The function move_it_vertically_backward may move over more
11890 than the specified y-distance. If it->w is small, e.g. a
11891 mini-buffer window, we may end up in front of the window's
11892 display area. Start displaying at the start of the line
11893 containing PT in this case. */
11894 if (it.current_y <= 0)
11895 {
11896 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11897 move_it_vertically (&it, 0);
11898 xassert (IT_CHARPOS (it) <= PT);
11899 it.current_y = 0;
11900 }
11901
11902 it.current_x = it.hpos = 0;
11903
11904 /* Set startp here explicitly in case that helps avoid an infinite loop
11905 in case the window-scroll-functions functions get errors. */
11906 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
11907
11908 /* Run scroll hooks. */
11909 startp = run_window_scroll_functions (window, it.current.pos);
11910
11911 /* Redisplay the window. */
11912 if (!current_matrix_up_to_date_p
11913 || windows_or_buffers_changed
11914 || cursor_type_changed
11915 /* Don't use try_window_reusing_current_matrix in this case
11916 because it can have changed the buffer. */
11917 || !NILP (Vwindow_scroll_functions)
11918 || !just_this_one_p
11919 || MINI_WINDOW_P (w)
11920 || !try_window_reusing_current_matrix (w))
11921 try_window (window, startp);
11922
11923 /* If new fonts have been loaded (due to fontsets), give up. We
11924 have to start a new redisplay since we need to re-adjust glyph
11925 matrices. */
11926 if (fonts_changed_p)
11927 goto need_larger_matrices;
11928
11929 /* If cursor did not appear assume that the middle of the window is
11930 in the first line of the window. Do it again with the next line.
11931 (Imagine a window of height 100, displaying two lines of height
11932 60. Moving back 50 from it->last_visible_y will end in the first
11933 line.) */
11934 if (w->cursor.vpos < 0)
11935 {
11936 if (!NILP (w->window_end_valid)
11937 && PT >= Z - XFASTINT (w->window_end_pos))
11938 {
11939 clear_glyph_matrix (w->desired_matrix);
11940 move_it_by_lines (&it, 1, 0);
11941 try_window (window, it.current.pos);
11942 }
11943 else if (PT < IT_CHARPOS (it))
11944 {
11945 clear_glyph_matrix (w->desired_matrix);
11946 move_it_by_lines (&it, -1, 0);
11947 try_window (window, it.current.pos);
11948 }
11949 else
11950 {
11951 /* Not much we can do about it. */
11952 }
11953 }
11954
11955 /* Consider the following case: Window starts at BEGV, there is
11956 invisible, intangible text at BEGV, so that display starts at
11957 some point START > BEGV. It can happen that we are called with
11958 PT somewhere between BEGV and START. Try to handle that case. */
11959 if (w->cursor.vpos < 0)
11960 {
11961 struct glyph_row *row = w->current_matrix->rows;
11962 if (row->mode_line_p)
11963 ++row;
11964 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11965 }
11966
11967 if (!make_cursor_line_fully_visible (w))
11968 {
11969 /* If vscroll is enabled, disable it and try again. */
11970 if (w->vscroll)
11971 {
11972 w->vscroll = 0;
11973 clear_glyph_matrix (w->desired_matrix);
11974 goto recenter;
11975 }
11976
11977 /* If centering point failed to make the whole line visible,
11978 put point at the top instead. That has to make the whole line
11979 visible, if it can be done. */
11980 centering_position = 0;
11981 goto point_at_top;
11982 }
11983
11984 done:
11985
11986 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11987 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
11988 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
11989 ? Qt : Qnil);
11990
11991 /* Display the mode line, if we must. */
11992 if ((update_mode_line
11993 /* If window not full width, must redo its mode line
11994 if (a) the window to its side is being redone and
11995 (b) we do a frame-based redisplay. This is a consequence
11996 of how inverted lines are drawn in frame-based redisplay. */
11997 || (!just_this_one_p
11998 && !FRAME_WINDOW_P (f)
11999 && !WINDOW_FULL_WIDTH_P (w))
12000 /* Line number to display. */
12001 || INTEGERP (w->base_line_pos)
12002 /* Column number is displayed and different from the one displayed. */
12003 || (!NILP (w->column_number_displayed)
12004 && (XFASTINT (w->column_number_displayed)
12005 != (int) current_column ()))) /* iftc */
12006 /* This means that the window has a mode line. */
12007 && (WINDOW_WANTS_MODELINE_P (w)
12008 || WINDOW_WANTS_HEADER_LINE_P (w)))
12009 {
12010 display_mode_lines (w);
12011
12012 /* If mode line height has changed, arrange for a thorough
12013 immediate redisplay using the correct mode line height. */
12014 if (WINDOW_WANTS_MODELINE_P (w)
12015 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12016 {
12017 fonts_changed_p = 1;
12018 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12019 = DESIRED_MODE_LINE_HEIGHT (w);
12020 }
12021
12022 /* If top line height has changed, arrange for a thorough
12023 immediate redisplay using the correct mode line height. */
12024 if (WINDOW_WANTS_HEADER_LINE_P (w)
12025 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12026 {
12027 fonts_changed_p = 1;
12028 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12029 = DESIRED_HEADER_LINE_HEIGHT (w);
12030 }
12031
12032 if (fonts_changed_p)
12033 goto need_larger_matrices;
12034 }
12035
12036 if (!line_number_displayed
12037 && !BUFFERP (w->base_line_pos))
12038 {
12039 w->base_line_pos = Qnil;
12040 w->base_line_number = Qnil;
12041 }
12042
12043 finish_menu_bars:
12044
12045 /* When we reach a frame's selected window, redo the frame's menu bar. */
12046 if (update_mode_line
12047 && EQ (FRAME_SELECTED_WINDOW (f), window))
12048 {
12049 int redisplay_menu_p = 0;
12050 int redisplay_tool_bar_p = 0;
12051
12052 if (FRAME_WINDOW_P (f))
12053 {
12054 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12055 || defined (USE_GTK)
12056 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12057 #else
12058 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12059 #endif
12060 }
12061 else
12062 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12063
12064 if (redisplay_menu_p)
12065 display_menu_bar (w);
12066
12067 #ifdef HAVE_WINDOW_SYSTEM
12068 #ifdef USE_GTK
12069 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12070 #else
12071 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12072 && (FRAME_TOOL_BAR_LINES (f) > 0
12073 || auto_resize_tool_bars_p);
12074
12075 #endif
12076
12077 if (redisplay_tool_bar_p)
12078 redisplay_tool_bar (f);
12079 #endif
12080 }
12081
12082 /* We go to this label, with fonts_changed_p nonzero,
12083 if it is necessary to try again using larger glyph matrices.
12084 We have to redeem the scroll bar even in this case,
12085 because the loop in redisplay_internal expects that. */
12086 need_larger_matrices:
12087 ;
12088 finish_scroll_bars:
12089
12090 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12091 {
12092 /* Set the thumb's position and size. */
12093 set_vertical_scroll_bar (w);
12094
12095 /* Note that we actually used the scroll bar attached to this
12096 window, so it shouldn't be deleted at the end of redisplay. */
12097 redeem_scroll_bar_hook (w);
12098 }
12099
12100 /* Restore current_buffer and value of point in it. */
12101 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12102 set_buffer_internal_1 (old);
12103 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12104
12105 unbind_to (count, Qnil);
12106 }
12107
12108
12109 /* Build the complete desired matrix of WINDOW with a window start
12110 buffer position POS. Value is non-zero if successful. It is zero
12111 if fonts were loaded during redisplay which makes re-adjusting
12112 glyph matrices necessary. */
12113
12114 int
12115 try_window (window, pos)
12116 Lisp_Object window;
12117 struct text_pos pos;
12118 {
12119 struct window *w = XWINDOW (window);
12120 struct it it;
12121 struct glyph_row *last_text_row = NULL;
12122
12123 /* Make POS the new window start. */
12124 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12125
12126 /* Mark cursor position as unknown. No overlay arrow seen. */
12127 w->cursor.vpos = -1;
12128 overlay_arrow_seen = 0;
12129
12130 /* Initialize iterator and info to start at POS. */
12131 start_display (&it, w, pos);
12132
12133 /* Display all lines of W. */
12134 while (it.current_y < it.last_visible_y)
12135 {
12136 if (display_line (&it))
12137 last_text_row = it.glyph_row - 1;
12138 if (fonts_changed_p)
12139 return 0;
12140 }
12141
12142 /* If bottom moved off end of frame, change mode line percentage. */
12143 if (XFASTINT (w->window_end_pos) <= 0
12144 && Z != IT_CHARPOS (it))
12145 w->update_mode_line = Qt;
12146
12147 /* Set window_end_pos to the offset of the last character displayed
12148 on the window from the end of current_buffer. Set
12149 window_end_vpos to its row number. */
12150 if (last_text_row)
12151 {
12152 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12153 w->window_end_bytepos
12154 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12155 w->window_end_pos
12156 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12157 w->window_end_vpos
12158 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12159 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12160 ->displays_text_p);
12161 }
12162 else
12163 {
12164 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12165 w->window_end_pos = make_number (Z - ZV);
12166 w->window_end_vpos = make_number (0);
12167 }
12168
12169 /* But that is not valid info until redisplay finishes. */
12170 w->window_end_valid = Qnil;
12171 return 1;
12172 }
12173
12174
12175 \f
12176 /************************************************************************
12177 Window redisplay reusing current matrix when buffer has not changed
12178 ************************************************************************/
12179
12180 /* Try redisplay of window W showing an unchanged buffer with a
12181 different window start than the last time it was displayed by
12182 reusing its current matrix. Value is non-zero if successful.
12183 W->start is the new window start. */
12184
12185 static int
12186 try_window_reusing_current_matrix (w)
12187 struct window *w;
12188 {
12189 struct frame *f = XFRAME (w->frame);
12190 struct glyph_row *row, *bottom_row;
12191 struct it it;
12192 struct run run;
12193 struct text_pos start, new_start;
12194 int nrows_scrolled, i;
12195 struct glyph_row *last_text_row;
12196 struct glyph_row *last_reused_text_row;
12197 struct glyph_row *start_row;
12198 int start_vpos, min_y, max_y;
12199
12200 #if GLYPH_DEBUG
12201 if (inhibit_try_window_reusing)
12202 return 0;
12203 #endif
12204
12205 if (/* This function doesn't handle terminal frames. */
12206 !FRAME_WINDOW_P (f)
12207 /* Don't try to reuse the display if windows have been split
12208 or such. */
12209 || windows_or_buffers_changed
12210 || cursor_type_changed)
12211 return 0;
12212
12213 /* Can't do this if region may have changed. */
12214 if ((!NILP (Vtransient_mark_mode)
12215 && !NILP (current_buffer->mark_active))
12216 || !NILP (w->region_showing)
12217 || !NILP (Vshow_trailing_whitespace))
12218 return 0;
12219
12220 /* If top-line visibility has changed, give up. */
12221 if (WINDOW_WANTS_HEADER_LINE_P (w)
12222 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12223 return 0;
12224
12225 /* Give up if old or new display is scrolled vertically. We could
12226 make this function handle this, but right now it doesn't. */
12227 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12228 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12229 return 0;
12230
12231 /* The variable new_start now holds the new window start. The old
12232 start `start' can be determined from the current matrix. */
12233 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12234 start = start_row->start.pos;
12235 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12236
12237 /* Clear the desired matrix for the display below. */
12238 clear_glyph_matrix (w->desired_matrix);
12239
12240 if (CHARPOS (new_start) <= CHARPOS (start))
12241 {
12242 int first_row_y;
12243
12244 /* Don't use this method if the display starts with an ellipsis
12245 displayed for invisible text. It's not easy to handle that case
12246 below, and it's certainly not worth the effort since this is
12247 not a frequent case. */
12248 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12249 return 0;
12250
12251 IF_DEBUG (debug_method_add (w, "twu1"));
12252
12253 /* Display up to a row that can be reused. The variable
12254 last_text_row is set to the last row displayed that displays
12255 text. Note that it.vpos == 0 if or if not there is a
12256 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12257 start_display (&it, w, new_start);
12258 first_row_y = it.current_y;
12259 w->cursor.vpos = -1;
12260 last_text_row = last_reused_text_row = NULL;
12261
12262 while (it.current_y < it.last_visible_y
12263 && IT_CHARPOS (it) < CHARPOS (start)
12264 && !fonts_changed_p)
12265 if (display_line (&it))
12266 last_text_row = it.glyph_row - 1;
12267
12268 /* A value of current_y < last_visible_y means that we stopped
12269 at the previous window start, which in turn means that we
12270 have at least one reusable row. */
12271 if (it.current_y < it.last_visible_y)
12272 {
12273 /* IT.vpos always starts from 0; it counts text lines. */
12274 nrows_scrolled = it.vpos;
12275
12276 /* Find PT if not already found in the lines displayed. */
12277 if (w->cursor.vpos < 0)
12278 {
12279 int dy = it.current_y - first_row_y;
12280
12281 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12282 row = row_containing_pos (w, PT, row, NULL, dy);
12283 if (row)
12284 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12285 dy, nrows_scrolled);
12286 else
12287 {
12288 clear_glyph_matrix (w->desired_matrix);
12289 return 0;
12290 }
12291 }
12292
12293 /* Scroll the display. Do it before the current matrix is
12294 changed. The problem here is that update has not yet
12295 run, i.e. part of the current matrix is not up to date.
12296 scroll_run_hook will clear the cursor, and use the
12297 current matrix to get the height of the row the cursor is
12298 in. */
12299 run.current_y = first_row_y;
12300 run.desired_y = it.current_y;
12301 run.height = it.last_visible_y - it.current_y;
12302
12303 if (run.height > 0 && run.current_y != run.desired_y)
12304 {
12305 update_begin (f);
12306 rif->update_window_begin_hook (w);
12307 rif->clear_window_mouse_face (w);
12308 rif->scroll_run_hook (w, &run);
12309 rif->update_window_end_hook (w, 0, 0);
12310 update_end (f);
12311 }
12312
12313 /* Shift current matrix down by nrows_scrolled lines. */
12314 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12315 rotate_matrix (w->current_matrix,
12316 start_vpos,
12317 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12318 nrows_scrolled);
12319
12320 /* Disable lines that must be updated. */
12321 for (i = 0; i < it.vpos; ++i)
12322 (start_row + i)->enabled_p = 0;
12323
12324 /* Re-compute Y positions. */
12325 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12326 max_y = it.last_visible_y;
12327 for (row = start_row + nrows_scrolled;
12328 row < bottom_row;
12329 ++row)
12330 {
12331 row->y = it.current_y;
12332 row->visible_height = row->height;
12333
12334 if (row->y < min_y)
12335 row->visible_height -= min_y - row->y;
12336 if (row->y + row->height > max_y)
12337 row->visible_height -= row->y + row->height - max_y;
12338
12339 it.current_y += row->height;
12340
12341 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12342 last_reused_text_row = row;
12343 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12344 break;
12345 }
12346
12347 /* Disable lines in the current matrix which are now
12348 below the window. */
12349 for (++row; row < bottom_row; ++row)
12350 row->enabled_p = 0;
12351 }
12352
12353 /* Update window_end_pos etc.; last_reused_text_row is the last
12354 reused row from the current matrix containing text, if any.
12355 The value of last_text_row is the last displayed line
12356 containing text. */
12357 if (last_reused_text_row)
12358 {
12359 w->window_end_bytepos
12360 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12361 w->window_end_pos
12362 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12363 w->window_end_vpos
12364 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12365 w->current_matrix));
12366 }
12367 else if (last_text_row)
12368 {
12369 w->window_end_bytepos
12370 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12371 w->window_end_pos
12372 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12373 w->window_end_vpos
12374 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12375 }
12376 else
12377 {
12378 /* This window must be completely empty. */
12379 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12380 w->window_end_pos = make_number (Z - ZV);
12381 w->window_end_vpos = make_number (0);
12382 }
12383 w->window_end_valid = Qnil;
12384
12385 /* Update hint: don't try scrolling again in update_window. */
12386 w->desired_matrix->no_scrolling_p = 1;
12387
12388 #if GLYPH_DEBUG
12389 debug_method_add (w, "try_window_reusing_current_matrix 1");
12390 #endif
12391 return 1;
12392 }
12393 else if (CHARPOS (new_start) > CHARPOS (start))
12394 {
12395 struct glyph_row *pt_row, *row;
12396 struct glyph_row *first_reusable_row;
12397 struct glyph_row *first_row_to_display;
12398 int dy;
12399 int yb = window_text_bottom_y (w);
12400
12401 /* Find the row starting at new_start, if there is one. Don't
12402 reuse a partially visible line at the end. */
12403 first_reusable_row = start_row;
12404 while (first_reusable_row->enabled_p
12405 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12406 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12407 < CHARPOS (new_start)))
12408 ++first_reusable_row;
12409
12410 /* Give up if there is no row to reuse. */
12411 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12412 || !first_reusable_row->enabled_p
12413 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12414 != CHARPOS (new_start)))
12415 return 0;
12416
12417 /* We can reuse fully visible rows beginning with
12418 first_reusable_row to the end of the window. Set
12419 first_row_to_display to the first row that cannot be reused.
12420 Set pt_row to the row containing point, if there is any. */
12421 pt_row = NULL;
12422 for (first_row_to_display = first_reusable_row;
12423 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12424 ++first_row_to_display)
12425 {
12426 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12427 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12428 pt_row = first_row_to_display;
12429 }
12430
12431 /* Start displaying at the start of first_row_to_display. */
12432 xassert (first_row_to_display->y < yb);
12433 init_to_row_start (&it, w, first_row_to_display);
12434
12435 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12436 - start_vpos);
12437 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12438 - nrows_scrolled);
12439 it.current_y = (first_row_to_display->y - first_reusable_row->y
12440 + WINDOW_HEADER_LINE_HEIGHT (w));
12441
12442 /* Display lines beginning with first_row_to_display in the
12443 desired matrix. Set last_text_row to the last row displayed
12444 that displays text. */
12445 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12446 if (pt_row == NULL)
12447 w->cursor.vpos = -1;
12448 last_text_row = NULL;
12449 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12450 if (display_line (&it))
12451 last_text_row = it.glyph_row - 1;
12452
12453 /* Give up If point isn't in a row displayed or reused. */
12454 if (w->cursor.vpos < 0)
12455 {
12456 clear_glyph_matrix (w->desired_matrix);
12457 return 0;
12458 }
12459
12460 /* If point is in a reused row, adjust y and vpos of the cursor
12461 position. */
12462 if (pt_row)
12463 {
12464 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12465 w->current_matrix);
12466 w->cursor.y -= first_reusable_row->y;
12467 }
12468
12469 /* Scroll the display. */
12470 run.current_y = first_reusable_row->y;
12471 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12472 run.height = it.last_visible_y - run.current_y;
12473 dy = run.current_y - run.desired_y;
12474
12475 if (run.height)
12476 {
12477 struct frame *f = XFRAME (WINDOW_FRAME (w));
12478 update_begin (f);
12479 rif->update_window_begin_hook (w);
12480 rif->clear_window_mouse_face (w);
12481 rif->scroll_run_hook (w, &run);
12482 rif->update_window_end_hook (w, 0, 0);
12483 update_end (f);
12484 }
12485
12486 /* Adjust Y positions of reused rows. */
12487 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12488 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12489 max_y = it.last_visible_y;
12490 for (row = first_reusable_row; row < first_row_to_display; ++row)
12491 {
12492 row->y -= dy;
12493 row->visible_height = row->height;
12494 if (row->y < min_y)
12495 row->visible_height -= min_y - row->y;
12496 if (row->y + row->height > max_y)
12497 row->visible_height -= row->y + row->height - max_y;
12498 }
12499
12500 /* Scroll the current matrix. */
12501 xassert (nrows_scrolled > 0);
12502 rotate_matrix (w->current_matrix,
12503 start_vpos,
12504 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12505 -nrows_scrolled);
12506
12507 /* Disable rows not reused. */
12508 for (row -= nrows_scrolled; row < bottom_row; ++row)
12509 row->enabled_p = 0;
12510
12511 /* Adjust window end. A null value of last_text_row means that
12512 the window end is in reused rows which in turn means that
12513 only its vpos can have changed. */
12514 if (last_text_row)
12515 {
12516 w->window_end_bytepos
12517 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12518 w->window_end_pos
12519 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12520 w->window_end_vpos
12521 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12522 }
12523 else
12524 {
12525 w->window_end_vpos
12526 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12527 }
12528
12529 w->window_end_valid = Qnil;
12530 w->desired_matrix->no_scrolling_p = 1;
12531
12532 #if GLYPH_DEBUG
12533 debug_method_add (w, "try_window_reusing_current_matrix 2");
12534 #endif
12535 return 1;
12536 }
12537
12538 return 0;
12539 }
12540
12541
12542 \f
12543 /************************************************************************
12544 Window redisplay reusing current matrix when buffer has changed
12545 ************************************************************************/
12546
12547 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12548 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12549 int *, int *));
12550 static struct glyph_row *
12551 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12552 struct glyph_row *));
12553
12554
12555 /* Return the last row in MATRIX displaying text. If row START is
12556 non-null, start searching with that row. IT gives the dimensions
12557 of the display. Value is null if matrix is empty; otherwise it is
12558 a pointer to the row found. */
12559
12560 static struct glyph_row *
12561 find_last_row_displaying_text (matrix, it, start)
12562 struct glyph_matrix *matrix;
12563 struct it *it;
12564 struct glyph_row *start;
12565 {
12566 struct glyph_row *row, *row_found;
12567
12568 /* Set row_found to the last row in IT->w's current matrix
12569 displaying text. The loop looks funny but think of partially
12570 visible lines. */
12571 row_found = NULL;
12572 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12573 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12574 {
12575 xassert (row->enabled_p);
12576 row_found = row;
12577 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12578 break;
12579 ++row;
12580 }
12581
12582 return row_found;
12583 }
12584
12585
12586 /* Return the last row in the current matrix of W that is not affected
12587 by changes at the start of current_buffer that occurred since W's
12588 current matrix was built. Value is null if no such row exists.
12589
12590 BEG_UNCHANGED us the number of characters unchanged at the start of
12591 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12592 first changed character in current_buffer. Characters at positions <
12593 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12594 when the current matrix was built. */
12595
12596 static struct glyph_row *
12597 find_last_unchanged_at_beg_row (w)
12598 struct window *w;
12599 {
12600 int first_changed_pos = BEG + BEG_UNCHANGED;
12601 struct glyph_row *row;
12602 struct glyph_row *row_found = NULL;
12603 int yb = window_text_bottom_y (w);
12604
12605 /* Find the last row displaying unchanged text. */
12606 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12607 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12608 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12609 {
12610 if (/* If row ends before first_changed_pos, it is unchanged,
12611 except in some case. */
12612 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12613 /* When row ends in ZV and we write at ZV it is not
12614 unchanged. */
12615 && !row->ends_at_zv_p
12616 /* When first_changed_pos is the end of a continued line,
12617 row is not unchanged because it may be no longer
12618 continued. */
12619 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12620 && row->continued_p))
12621 row_found = row;
12622
12623 /* Stop if last visible row. */
12624 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12625 break;
12626
12627 ++row;
12628 }
12629
12630 return row_found;
12631 }
12632
12633
12634 /* Find the first glyph row in the current matrix of W that is not
12635 affected by changes at the end of current_buffer since the
12636 time W's current matrix was built.
12637
12638 Return in *DELTA the number of chars by which buffer positions in
12639 unchanged text at the end of current_buffer must be adjusted.
12640
12641 Return in *DELTA_BYTES the corresponding number of bytes.
12642
12643 Value is null if no such row exists, i.e. all rows are affected by
12644 changes. */
12645
12646 static struct glyph_row *
12647 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12648 struct window *w;
12649 int *delta, *delta_bytes;
12650 {
12651 struct glyph_row *row;
12652 struct glyph_row *row_found = NULL;
12653
12654 *delta = *delta_bytes = 0;
12655
12656 /* Display must not have been paused, otherwise the current matrix
12657 is not up to date. */
12658 if (NILP (w->window_end_valid))
12659 abort ();
12660
12661 /* A value of window_end_pos >= END_UNCHANGED means that the window
12662 end is in the range of changed text. If so, there is no
12663 unchanged row at the end of W's current matrix. */
12664 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12665 return NULL;
12666
12667 /* Set row to the last row in W's current matrix displaying text. */
12668 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12669
12670 /* If matrix is entirely empty, no unchanged row exists. */
12671 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12672 {
12673 /* The value of row is the last glyph row in the matrix having a
12674 meaningful buffer position in it. The end position of row
12675 corresponds to window_end_pos. This allows us to translate
12676 buffer positions in the current matrix to current buffer
12677 positions for characters not in changed text. */
12678 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12679 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12680 int last_unchanged_pos, last_unchanged_pos_old;
12681 struct glyph_row *first_text_row
12682 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12683
12684 *delta = Z - Z_old;
12685 *delta_bytes = Z_BYTE - Z_BYTE_old;
12686
12687 /* Set last_unchanged_pos to the buffer position of the last
12688 character in the buffer that has not been changed. Z is the
12689 index + 1 of the last character in current_buffer, i.e. by
12690 subtracting END_UNCHANGED we get the index of the last
12691 unchanged character, and we have to add BEG to get its buffer
12692 position. */
12693 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12694 last_unchanged_pos_old = last_unchanged_pos - *delta;
12695
12696 /* Search backward from ROW for a row displaying a line that
12697 starts at a minimum position >= last_unchanged_pos_old. */
12698 for (; row > first_text_row; --row)
12699 {
12700 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12701 abort ();
12702
12703 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12704 row_found = row;
12705 }
12706 }
12707
12708 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12709 abort ();
12710
12711 return row_found;
12712 }
12713
12714
12715 /* Make sure that glyph rows in the current matrix of window W
12716 reference the same glyph memory as corresponding rows in the
12717 frame's frame matrix. This function is called after scrolling W's
12718 current matrix on a terminal frame in try_window_id and
12719 try_window_reusing_current_matrix. */
12720
12721 static void
12722 sync_frame_with_window_matrix_rows (w)
12723 struct window *w;
12724 {
12725 struct frame *f = XFRAME (w->frame);
12726 struct glyph_row *window_row, *window_row_end, *frame_row;
12727
12728 /* Preconditions: W must be a leaf window and full-width. Its frame
12729 must have a frame matrix. */
12730 xassert (NILP (w->hchild) && NILP (w->vchild));
12731 xassert (WINDOW_FULL_WIDTH_P (w));
12732 xassert (!FRAME_WINDOW_P (f));
12733
12734 /* If W is a full-width window, glyph pointers in W's current matrix
12735 have, by definition, to be the same as glyph pointers in the
12736 corresponding frame matrix. Note that frame matrices have no
12737 marginal areas (see build_frame_matrix). */
12738 window_row = w->current_matrix->rows;
12739 window_row_end = window_row + w->current_matrix->nrows;
12740 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12741 while (window_row < window_row_end)
12742 {
12743 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12744 struct glyph *end = window_row->glyphs[LAST_AREA];
12745
12746 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12747 frame_row->glyphs[TEXT_AREA] = start;
12748 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12749 frame_row->glyphs[LAST_AREA] = end;
12750
12751 /* Disable frame rows whose corresponding window rows have
12752 been disabled in try_window_id. */
12753 if (!window_row->enabled_p)
12754 frame_row->enabled_p = 0;
12755
12756 ++window_row, ++frame_row;
12757 }
12758 }
12759
12760
12761 /* Find the glyph row in window W containing CHARPOS. Consider all
12762 rows between START and END (not inclusive). END null means search
12763 all rows to the end of the display area of W. Value is the row
12764 containing CHARPOS or null. */
12765
12766 struct glyph_row *
12767 row_containing_pos (w, charpos, start, end, dy)
12768 struct window *w;
12769 int charpos;
12770 struct glyph_row *start, *end;
12771 int dy;
12772 {
12773 struct glyph_row *row = start;
12774 int last_y;
12775
12776 /* If we happen to start on a header-line, skip that. */
12777 if (row->mode_line_p)
12778 ++row;
12779
12780 if ((end && row >= end) || !row->enabled_p)
12781 return NULL;
12782
12783 last_y = window_text_bottom_y (w) - dy;
12784
12785 while (1)
12786 {
12787 /* Give up if we have gone too far. */
12788 if (end && row >= end)
12789 return NULL;
12790 /* This formerly returned if they were equal.
12791 I think that both quantities are of a "last plus one" type;
12792 if so, when they are equal, the row is within the screen. -- rms. */
12793 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12794 return NULL;
12795
12796 /* If it is in this row, return this row. */
12797 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12798 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12799 /* The end position of a row equals the start
12800 position of the next row. If CHARPOS is there, we
12801 would rather display it in the next line, except
12802 when this line ends in ZV. */
12803 && !row->ends_at_zv_p
12804 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12805 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12806 return row;
12807 ++row;
12808 }
12809 }
12810
12811
12812 /* Try to redisplay window W by reusing its existing display. W's
12813 current matrix must be up to date when this function is called,
12814 i.e. window_end_valid must not be nil.
12815
12816 Value is
12817
12818 1 if display has been updated
12819 0 if otherwise unsuccessful
12820 -1 if redisplay with same window start is known not to succeed
12821
12822 The following steps are performed:
12823
12824 1. Find the last row in the current matrix of W that is not
12825 affected by changes at the start of current_buffer. If no such row
12826 is found, give up.
12827
12828 2. Find the first row in W's current matrix that is not affected by
12829 changes at the end of current_buffer. Maybe there is no such row.
12830
12831 3. Display lines beginning with the row + 1 found in step 1 to the
12832 row found in step 2 or, if step 2 didn't find a row, to the end of
12833 the window.
12834
12835 4. If cursor is not known to appear on the window, give up.
12836
12837 5. If display stopped at the row found in step 2, scroll the
12838 display and current matrix as needed.
12839
12840 6. Maybe display some lines at the end of W, if we must. This can
12841 happen under various circumstances, like a partially visible line
12842 becoming fully visible, or because newly displayed lines are displayed
12843 in smaller font sizes.
12844
12845 7. Update W's window end information. */
12846
12847 static int
12848 try_window_id (w)
12849 struct window *w;
12850 {
12851 struct frame *f = XFRAME (w->frame);
12852 struct glyph_matrix *current_matrix = w->current_matrix;
12853 struct glyph_matrix *desired_matrix = w->desired_matrix;
12854 struct glyph_row *last_unchanged_at_beg_row;
12855 struct glyph_row *first_unchanged_at_end_row;
12856 struct glyph_row *row;
12857 struct glyph_row *bottom_row;
12858 int bottom_vpos;
12859 struct it it;
12860 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
12861 struct text_pos start_pos;
12862 struct run run;
12863 int first_unchanged_at_end_vpos = 0;
12864 struct glyph_row *last_text_row, *last_text_row_at_end;
12865 struct text_pos start;
12866 int first_changed_charpos, last_changed_charpos;
12867
12868 #if GLYPH_DEBUG
12869 if (inhibit_try_window_id)
12870 return 0;
12871 #endif
12872
12873 /* This is handy for debugging. */
12874 #if 0
12875 #define GIVE_UP(X) \
12876 do { \
12877 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12878 return 0; \
12879 } while (0)
12880 #else
12881 #define GIVE_UP(X) return 0
12882 #endif
12883
12884 SET_TEXT_POS_FROM_MARKER (start, w->start);
12885
12886 /* Don't use this for mini-windows because these can show
12887 messages and mini-buffers, and we don't handle that here. */
12888 if (MINI_WINDOW_P (w))
12889 GIVE_UP (1);
12890
12891 /* This flag is used to prevent redisplay optimizations. */
12892 if (windows_or_buffers_changed || cursor_type_changed)
12893 GIVE_UP (2);
12894
12895 /* Verify that narrowing has not changed.
12896 Also verify that we were not told to prevent redisplay optimizations.
12897 It would be nice to further
12898 reduce the number of cases where this prevents try_window_id. */
12899 if (current_buffer->clip_changed
12900 || current_buffer->prevent_redisplay_optimizations_p)
12901 GIVE_UP (3);
12902
12903 /* Window must either use window-based redisplay or be full width. */
12904 if (!FRAME_WINDOW_P (f)
12905 && (!line_ins_del_ok
12906 || !WINDOW_FULL_WIDTH_P (w)))
12907 GIVE_UP (4);
12908
12909 /* Give up if point is not known NOT to appear in W. */
12910 if (PT < CHARPOS (start))
12911 GIVE_UP (5);
12912
12913 /* Another way to prevent redisplay optimizations. */
12914 if (XFASTINT (w->last_modified) == 0)
12915 GIVE_UP (6);
12916
12917 /* Verify that window is not hscrolled. */
12918 if (XFASTINT (w->hscroll) != 0)
12919 GIVE_UP (7);
12920
12921 /* Verify that display wasn't paused. */
12922 if (NILP (w->window_end_valid))
12923 GIVE_UP (8);
12924
12925 /* Can't use this if highlighting a region because a cursor movement
12926 will do more than just set the cursor. */
12927 if (!NILP (Vtransient_mark_mode)
12928 && !NILP (current_buffer->mark_active))
12929 GIVE_UP (9);
12930
12931 /* Likewise if highlighting trailing whitespace. */
12932 if (!NILP (Vshow_trailing_whitespace))
12933 GIVE_UP (11);
12934
12935 /* Likewise if showing a region. */
12936 if (!NILP (w->region_showing))
12937 GIVE_UP (10);
12938
12939 /* Can use this if overlay arrow position and or string have changed. */
12940 if (!EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
12941 || !EQ (last_arrow_string, Voverlay_arrow_string))
12942 GIVE_UP (12);
12943
12944
12945 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12946 only if buffer has really changed. The reason is that the gap is
12947 initially at Z for freshly visited files. The code below would
12948 set end_unchanged to 0 in that case. */
12949 if (MODIFF > SAVE_MODIFF
12950 /* This seems to happen sometimes after saving a buffer. */
12951 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
12952 {
12953 if (GPT - BEG < BEG_UNCHANGED)
12954 BEG_UNCHANGED = GPT - BEG;
12955 if (Z - GPT < END_UNCHANGED)
12956 END_UNCHANGED = Z - GPT;
12957 }
12958
12959 /* The position of the first and last character that has been changed. */
12960 first_changed_charpos = BEG + BEG_UNCHANGED;
12961 last_changed_charpos = Z - END_UNCHANGED;
12962
12963 /* If window starts after a line end, and the last change is in
12964 front of that newline, then changes don't affect the display.
12965 This case happens with stealth-fontification. Note that although
12966 the display is unchanged, glyph positions in the matrix have to
12967 be adjusted, of course. */
12968 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12969 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12970 && ((last_changed_charpos < CHARPOS (start)
12971 && CHARPOS (start) == BEGV)
12972 || (last_changed_charpos < CHARPOS (start) - 1
12973 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
12974 {
12975 int Z_old, delta, Z_BYTE_old, delta_bytes;
12976 struct glyph_row *r0;
12977
12978 /* Compute how many chars/bytes have been added to or removed
12979 from the buffer. */
12980 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12981 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12982 delta = Z - Z_old;
12983 delta_bytes = Z_BYTE - Z_BYTE_old;
12984
12985 /* Give up if PT is not in the window. Note that it already has
12986 been checked at the start of try_window_id that PT is not in
12987 front of the window start. */
12988 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
12989 GIVE_UP (13);
12990
12991 /* If window start is unchanged, we can reuse the whole matrix
12992 as is, after adjusting glyph positions. No need to compute
12993 the window end again, since its offset from Z hasn't changed. */
12994 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12995 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
12996 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
12997 /* PT must not be in a partially visible line. */
12998 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
12999 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13000 {
13001 /* Adjust positions in the glyph matrix. */
13002 if (delta || delta_bytes)
13003 {
13004 struct glyph_row *r1
13005 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13006 increment_matrix_positions (w->current_matrix,
13007 MATRIX_ROW_VPOS (r0, current_matrix),
13008 MATRIX_ROW_VPOS (r1, current_matrix),
13009 delta, delta_bytes);
13010 }
13011
13012 /* Set the cursor. */
13013 row = row_containing_pos (w, PT, r0, NULL, 0);
13014 if (row)
13015 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13016 else
13017 abort ();
13018 return 1;
13019 }
13020 }
13021
13022 /* Handle the case that changes are all below what is displayed in
13023 the window, and that PT is in the window. This shortcut cannot
13024 be taken if ZV is visible in the window, and text has been added
13025 there that is visible in the window. */
13026 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13027 /* ZV is not visible in the window, or there are no
13028 changes at ZV, actually. */
13029 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13030 || first_changed_charpos == last_changed_charpos))
13031 {
13032 struct glyph_row *r0;
13033
13034 /* Give up if PT is not in the window. Note that it already has
13035 been checked at the start of try_window_id that PT is not in
13036 front of the window start. */
13037 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13038 GIVE_UP (14);
13039
13040 /* If window start is unchanged, we can reuse the whole matrix
13041 as is, without changing glyph positions since no text has
13042 been added/removed in front of the window end. */
13043 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13044 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13045 /* PT must not be in a partially visible line. */
13046 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13047 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13048 {
13049 /* We have to compute the window end anew since text
13050 can have been added/removed after it. */
13051 w->window_end_pos
13052 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13053 w->window_end_bytepos
13054 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13055
13056 /* Set the cursor. */
13057 row = row_containing_pos (w, PT, r0, NULL, 0);
13058 if (row)
13059 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13060 else
13061 abort ();
13062 return 2;
13063 }
13064 }
13065
13066 /* Give up if window start is in the changed area.
13067
13068 The condition used to read
13069
13070 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13071
13072 but why that was tested escapes me at the moment. */
13073 if (CHARPOS (start) >= first_changed_charpos
13074 && CHARPOS (start) <= last_changed_charpos)
13075 GIVE_UP (15);
13076
13077 /* Check that window start agrees with the start of the first glyph
13078 row in its current matrix. Check this after we know the window
13079 start is not in changed text, otherwise positions would not be
13080 comparable. */
13081 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13082 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13083 GIVE_UP (16);
13084
13085 /* Give up if the window ends in strings. Overlay strings
13086 at the end are difficult to handle, so don't try. */
13087 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13088 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13089 GIVE_UP (20);
13090
13091 /* Compute the position at which we have to start displaying new
13092 lines. Some of the lines at the top of the window might be
13093 reusable because they are not displaying changed text. Find the
13094 last row in W's current matrix not affected by changes at the
13095 start of current_buffer. Value is null if changes start in the
13096 first line of window. */
13097 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13098 if (last_unchanged_at_beg_row)
13099 {
13100 /* Avoid starting to display in the moddle of a character, a TAB
13101 for instance. This is easier than to set up the iterator
13102 exactly, and it's not a frequent case, so the additional
13103 effort wouldn't really pay off. */
13104 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13105 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13106 && last_unchanged_at_beg_row > w->current_matrix->rows)
13107 --last_unchanged_at_beg_row;
13108
13109 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13110 GIVE_UP (17);
13111
13112 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13113 GIVE_UP (18);
13114 start_pos = it.current.pos;
13115
13116 /* Start displaying new lines in the desired matrix at the same
13117 vpos we would use in the current matrix, i.e. below
13118 last_unchanged_at_beg_row. */
13119 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13120 current_matrix);
13121 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13122 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13123
13124 xassert (it.hpos == 0 && it.current_x == 0);
13125 }
13126 else
13127 {
13128 /* There are no reusable lines at the start of the window.
13129 Start displaying in the first text line. */
13130 start_display (&it, w, start);
13131 it.vpos = it.first_vpos;
13132 start_pos = it.current.pos;
13133 }
13134
13135 /* Find the first row that is not affected by changes at the end of
13136 the buffer. Value will be null if there is no unchanged row, in
13137 which case we must redisplay to the end of the window. delta
13138 will be set to the value by which buffer positions beginning with
13139 first_unchanged_at_end_row have to be adjusted due to text
13140 changes. */
13141 first_unchanged_at_end_row
13142 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13143 IF_DEBUG (debug_delta = delta);
13144 IF_DEBUG (debug_delta_bytes = delta_bytes);
13145
13146 /* Set stop_pos to the buffer position up to which we will have to
13147 display new lines. If first_unchanged_at_end_row != NULL, this
13148 is the buffer position of the start of the line displayed in that
13149 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13150 that we don't stop at a buffer position. */
13151 stop_pos = 0;
13152 if (first_unchanged_at_end_row)
13153 {
13154 xassert (last_unchanged_at_beg_row == NULL
13155 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13156
13157 /* If this is a continuation line, move forward to the next one
13158 that isn't. Changes in lines above affect this line.
13159 Caution: this may move first_unchanged_at_end_row to a row
13160 not displaying text. */
13161 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13162 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13163 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13164 < it.last_visible_y))
13165 ++first_unchanged_at_end_row;
13166
13167 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13168 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13169 >= it.last_visible_y))
13170 first_unchanged_at_end_row = NULL;
13171 else
13172 {
13173 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13174 + delta);
13175 first_unchanged_at_end_vpos
13176 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13177 xassert (stop_pos >= Z - END_UNCHANGED);
13178 }
13179 }
13180 else if (last_unchanged_at_beg_row == NULL)
13181 GIVE_UP (19);
13182
13183
13184 #if GLYPH_DEBUG
13185
13186 /* Either there is no unchanged row at the end, or the one we have
13187 now displays text. This is a necessary condition for the window
13188 end pos calculation at the end of this function. */
13189 xassert (first_unchanged_at_end_row == NULL
13190 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13191
13192 debug_last_unchanged_at_beg_vpos
13193 = (last_unchanged_at_beg_row
13194 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13195 : -1);
13196 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13197
13198 #endif /* GLYPH_DEBUG != 0 */
13199
13200
13201 /* Display new lines. Set last_text_row to the last new line
13202 displayed which has text on it, i.e. might end up as being the
13203 line where the window_end_vpos is. */
13204 w->cursor.vpos = -1;
13205 last_text_row = NULL;
13206 overlay_arrow_seen = 0;
13207 while (it.current_y < it.last_visible_y
13208 && !fonts_changed_p
13209 && (first_unchanged_at_end_row == NULL
13210 || IT_CHARPOS (it) < stop_pos))
13211 {
13212 if (display_line (&it))
13213 last_text_row = it.glyph_row - 1;
13214 }
13215
13216 if (fonts_changed_p)
13217 return -1;
13218
13219
13220 /* Compute differences in buffer positions, y-positions etc. for
13221 lines reused at the bottom of the window. Compute what we can
13222 scroll. */
13223 if (first_unchanged_at_end_row
13224 /* No lines reused because we displayed everything up to the
13225 bottom of the window. */
13226 && it.current_y < it.last_visible_y)
13227 {
13228 dvpos = (it.vpos
13229 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13230 current_matrix));
13231 dy = it.current_y - first_unchanged_at_end_row->y;
13232 run.current_y = first_unchanged_at_end_row->y;
13233 run.desired_y = run.current_y + dy;
13234 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13235 }
13236 else
13237 {
13238 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13239 first_unchanged_at_end_row = NULL;
13240 }
13241 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13242
13243
13244 /* Find the cursor if not already found. We have to decide whether
13245 PT will appear on this window (it sometimes doesn't, but this is
13246 not a very frequent case.) This decision has to be made before
13247 the current matrix is altered. A value of cursor.vpos < 0 means
13248 that PT is either in one of the lines beginning at
13249 first_unchanged_at_end_row or below the window. Don't care for
13250 lines that might be displayed later at the window end; as
13251 mentioned, this is not a frequent case. */
13252 if (w->cursor.vpos < 0)
13253 {
13254 /* Cursor in unchanged rows at the top? */
13255 if (PT < CHARPOS (start_pos)
13256 && last_unchanged_at_beg_row)
13257 {
13258 row = row_containing_pos (w, PT,
13259 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13260 last_unchanged_at_beg_row + 1, 0);
13261 if (row)
13262 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13263 }
13264
13265 /* Start from first_unchanged_at_end_row looking for PT. */
13266 else if (first_unchanged_at_end_row)
13267 {
13268 row = row_containing_pos (w, PT - delta,
13269 first_unchanged_at_end_row, NULL, 0);
13270 if (row)
13271 set_cursor_from_row (w, row, w->current_matrix, delta,
13272 delta_bytes, dy, dvpos);
13273 }
13274
13275 /* Give up if cursor was not found. */
13276 if (w->cursor.vpos < 0)
13277 {
13278 clear_glyph_matrix (w->desired_matrix);
13279 return -1;
13280 }
13281 }
13282
13283 /* Don't let the cursor end in the scroll margins. */
13284 {
13285 int this_scroll_margin, cursor_height;
13286
13287 this_scroll_margin = max (0, scroll_margin);
13288 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13289 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13290 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13291
13292 if ((w->cursor.y < this_scroll_margin
13293 && CHARPOS (start) > BEGV)
13294 /* Don't take scroll margin into account at the bottom because
13295 old redisplay didn't do it either. */
13296 || w->cursor.y + cursor_height > it.last_visible_y)
13297 {
13298 w->cursor.vpos = -1;
13299 clear_glyph_matrix (w->desired_matrix);
13300 return -1;
13301 }
13302 }
13303
13304 /* Scroll the display. Do it before changing the current matrix so
13305 that xterm.c doesn't get confused about where the cursor glyph is
13306 found. */
13307 if (dy && run.height)
13308 {
13309 update_begin (f);
13310
13311 if (FRAME_WINDOW_P (f))
13312 {
13313 rif->update_window_begin_hook (w);
13314 rif->clear_window_mouse_face (w);
13315 rif->scroll_run_hook (w, &run);
13316 rif->update_window_end_hook (w, 0, 0);
13317 }
13318 else
13319 {
13320 /* Terminal frame. In this case, dvpos gives the number of
13321 lines to scroll by; dvpos < 0 means scroll up. */
13322 int first_unchanged_at_end_vpos
13323 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13324 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13325 int end = (WINDOW_TOP_EDGE_LINE (w)
13326 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13327 + window_internal_height (w));
13328
13329 /* Perform the operation on the screen. */
13330 if (dvpos > 0)
13331 {
13332 /* Scroll last_unchanged_at_beg_row to the end of the
13333 window down dvpos lines. */
13334 set_terminal_window (end);
13335
13336 /* On dumb terminals delete dvpos lines at the end
13337 before inserting dvpos empty lines. */
13338 if (!scroll_region_ok)
13339 ins_del_lines (end - dvpos, -dvpos);
13340
13341 /* Insert dvpos empty lines in front of
13342 last_unchanged_at_beg_row. */
13343 ins_del_lines (from, dvpos);
13344 }
13345 else if (dvpos < 0)
13346 {
13347 /* Scroll up last_unchanged_at_beg_vpos to the end of
13348 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13349 set_terminal_window (end);
13350
13351 /* Delete dvpos lines in front of
13352 last_unchanged_at_beg_vpos. ins_del_lines will set
13353 the cursor to the given vpos and emit |dvpos| delete
13354 line sequences. */
13355 ins_del_lines (from + dvpos, dvpos);
13356
13357 /* On a dumb terminal insert dvpos empty lines at the
13358 end. */
13359 if (!scroll_region_ok)
13360 ins_del_lines (end + dvpos, -dvpos);
13361 }
13362
13363 set_terminal_window (0);
13364 }
13365
13366 update_end (f);
13367 }
13368
13369 /* Shift reused rows of the current matrix to the right position.
13370 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13371 text. */
13372 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13373 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13374 if (dvpos < 0)
13375 {
13376 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13377 bottom_vpos, dvpos);
13378 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13379 bottom_vpos, 0);
13380 }
13381 else if (dvpos > 0)
13382 {
13383 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13384 bottom_vpos, dvpos);
13385 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13386 first_unchanged_at_end_vpos + dvpos, 0);
13387 }
13388
13389 /* For frame-based redisplay, make sure that current frame and window
13390 matrix are in sync with respect to glyph memory. */
13391 if (!FRAME_WINDOW_P (f))
13392 sync_frame_with_window_matrix_rows (w);
13393
13394 /* Adjust buffer positions in reused rows. */
13395 if (delta)
13396 increment_matrix_positions (current_matrix,
13397 first_unchanged_at_end_vpos + dvpos,
13398 bottom_vpos, delta, delta_bytes);
13399
13400 /* Adjust Y positions. */
13401 if (dy)
13402 shift_glyph_matrix (w, current_matrix,
13403 first_unchanged_at_end_vpos + dvpos,
13404 bottom_vpos, dy);
13405
13406 if (first_unchanged_at_end_row)
13407 first_unchanged_at_end_row += dvpos;
13408
13409 /* If scrolling up, there may be some lines to display at the end of
13410 the window. */
13411 last_text_row_at_end = NULL;
13412 if (dy < 0)
13413 {
13414 /* Scrolling up can leave for example a partially visible line
13415 at the end of the window to be redisplayed. */
13416 /* Set last_row to the glyph row in the current matrix where the
13417 window end line is found. It has been moved up or down in
13418 the matrix by dvpos. */
13419 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13420 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13421
13422 /* If last_row is the window end line, it should display text. */
13423 xassert (last_row->displays_text_p);
13424
13425 /* If window end line was partially visible before, begin
13426 displaying at that line. Otherwise begin displaying with the
13427 line following it. */
13428 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13429 {
13430 init_to_row_start (&it, w, last_row);
13431 it.vpos = last_vpos;
13432 it.current_y = last_row->y;
13433 }
13434 else
13435 {
13436 init_to_row_end (&it, w, last_row);
13437 it.vpos = 1 + last_vpos;
13438 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13439 ++last_row;
13440 }
13441
13442 /* We may start in a continuation line. If so, we have to
13443 get the right continuation_lines_width and current_x. */
13444 it.continuation_lines_width = last_row->continuation_lines_width;
13445 it.hpos = it.current_x = 0;
13446
13447 /* Display the rest of the lines at the window end. */
13448 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13449 while (it.current_y < it.last_visible_y
13450 && !fonts_changed_p)
13451 {
13452 /* Is it always sure that the display agrees with lines in
13453 the current matrix? I don't think so, so we mark rows
13454 displayed invalid in the current matrix by setting their
13455 enabled_p flag to zero. */
13456 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13457 if (display_line (&it))
13458 last_text_row_at_end = it.glyph_row - 1;
13459 }
13460 }
13461
13462 /* Update window_end_pos and window_end_vpos. */
13463 if (first_unchanged_at_end_row
13464 && first_unchanged_at_end_row->y < it.last_visible_y
13465 && !last_text_row_at_end)
13466 {
13467 /* Window end line if one of the preserved rows from the current
13468 matrix. Set row to the last row displaying text in current
13469 matrix starting at first_unchanged_at_end_row, after
13470 scrolling. */
13471 xassert (first_unchanged_at_end_row->displays_text_p);
13472 row = find_last_row_displaying_text (w->current_matrix, &it,
13473 first_unchanged_at_end_row);
13474 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13475
13476 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13477 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13478 w->window_end_vpos
13479 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13480 xassert (w->window_end_bytepos >= 0);
13481 IF_DEBUG (debug_method_add (w, "A"));
13482 }
13483 else if (last_text_row_at_end)
13484 {
13485 w->window_end_pos
13486 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13487 w->window_end_bytepos
13488 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13489 w->window_end_vpos
13490 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13491 xassert (w->window_end_bytepos >= 0);
13492 IF_DEBUG (debug_method_add (w, "B"));
13493 }
13494 else if (last_text_row)
13495 {
13496 /* We have displayed either to the end of the window or at the
13497 end of the window, i.e. the last row with text is to be found
13498 in the desired matrix. */
13499 w->window_end_pos
13500 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13501 w->window_end_bytepos
13502 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13503 w->window_end_vpos
13504 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13505 xassert (w->window_end_bytepos >= 0);
13506 }
13507 else if (first_unchanged_at_end_row == NULL
13508 && last_text_row == NULL
13509 && last_text_row_at_end == NULL)
13510 {
13511 /* Displayed to end of window, but no line containing text was
13512 displayed. Lines were deleted at the end of the window. */
13513 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13514 int vpos = XFASTINT (w->window_end_vpos);
13515 struct glyph_row *current_row = current_matrix->rows + vpos;
13516 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13517
13518 for (row = NULL;
13519 row == NULL && vpos >= first_vpos;
13520 --vpos, --current_row, --desired_row)
13521 {
13522 if (desired_row->enabled_p)
13523 {
13524 if (desired_row->displays_text_p)
13525 row = desired_row;
13526 }
13527 else if (current_row->displays_text_p)
13528 row = current_row;
13529 }
13530
13531 xassert (row != NULL);
13532 w->window_end_vpos = make_number (vpos + 1);
13533 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13534 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13535 xassert (w->window_end_bytepos >= 0);
13536 IF_DEBUG (debug_method_add (w, "C"));
13537 }
13538 else
13539 abort ();
13540
13541 #if 0 /* This leads to problems, for instance when the cursor is
13542 at ZV, and the cursor line displays no text. */
13543 /* Disable rows below what's displayed in the window. This makes
13544 debugging easier. */
13545 enable_glyph_matrix_rows (current_matrix,
13546 XFASTINT (w->window_end_vpos) + 1,
13547 bottom_vpos, 0);
13548 #endif
13549
13550 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13551 debug_end_vpos = XFASTINT (w->window_end_vpos));
13552
13553 /* Record that display has not been completed. */
13554 w->window_end_valid = Qnil;
13555 w->desired_matrix->no_scrolling_p = 1;
13556 return 3;
13557
13558 #undef GIVE_UP
13559 }
13560
13561
13562 \f
13563 /***********************************************************************
13564 More debugging support
13565 ***********************************************************************/
13566
13567 #if GLYPH_DEBUG
13568
13569 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13570 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13571 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13572
13573
13574 /* Dump the contents of glyph matrix MATRIX on stderr.
13575
13576 GLYPHS 0 means don't show glyph contents.
13577 GLYPHS 1 means show glyphs in short form
13578 GLYPHS > 1 means show glyphs in long form. */
13579
13580 void
13581 dump_glyph_matrix (matrix, glyphs)
13582 struct glyph_matrix *matrix;
13583 int glyphs;
13584 {
13585 int i;
13586 for (i = 0; i < matrix->nrows; ++i)
13587 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13588 }
13589
13590
13591 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13592 the glyph row and area where the glyph comes from. */
13593
13594 void
13595 dump_glyph (row, glyph, area)
13596 struct glyph_row *row;
13597 struct glyph *glyph;
13598 int area;
13599 {
13600 if (glyph->type == CHAR_GLYPH)
13601 {
13602 fprintf (stderr,
13603 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13604 glyph - row->glyphs[TEXT_AREA],
13605 'C',
13606 glyph->charpos,
13607 (BUFFERP (glyph->object)
13608 ? 'B'
13609 : (STRINGP (glyph->object)
13610 ? 'S'
13611 : '-')),
13612 glyph->pixel_width,
13613 glyph->u.ch,
13614 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13615 ? glyph->u.ch
13616 : '.'),
13617 glyph->face_id,
13618 glyph->left_box_line_p,
13619 glyph->right_box_line_p);
13620 }
13621 else if (glyph->type == STRETCH_GLYPH)
13622 {
13623 fprintf (stderr,
13624 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13625 glyph - row->glyphs[TEXT_AREA],
13626 'S',
13627 glyph->charpos,
13628 (BUFFERP (glyph->object)
13629 ? 'B'
13630 : (STRINGP (glyph->object)
13631 ? 'S'
13632 : '-')),
13633 glyph->pixel_width,
13634 0,
13635 '.',
13636 glyph->face_id,
13637 glyph->left_box_line_p,
13638 glyph->right_box_line_p);
13639 }
13640 else if (glyph->type == IMAGE_GLYPH)
13641 {
13642 fprintf (stderr,
13643 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13644 glyph - row->glyphs[TEXT_AREA],
13645 'I',
13646 glyph->charpos,
13647 (BUFFERP (glyph->object)
13648 ? 'B'
13649 : (STRINGP (glyph->object)
13650 ? 'S'
13651 : '-')),
13652 glyph->pixel_width,
13653 glyph->u.img_id,
13654 '.',
13655 glyph->face_id,
13656 glyph->left_box_line_p,
13657 glyph->right_box_line_p);
13658 }
13659 }
13660
13661
13662 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13663 GLYPHS 0 means don't show glyph contents.
13664 GLYPHS 1 means show glyphs in short form
13665 GLYPHS > 1 means show glyphs in long form. */
13666
13667 void
13668 dump_glyph_row (row, vpos, glyphs)
13669 struct glyph_row *row;
13670 int vpos, glyphs;
13671 {
13672 if (glyphs != 1)
13673 {
13674 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13675 fprintf (stderr, "=======================================================================\n");
13676
13677 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13678 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13679 vpos,
13680 MATRIX_ROW_START_CHARPOS (row),
13681 MATRIX_ROW_END_CHARPOS (row),
13682 row->used[TEXT_AREA],
13683 row->contains_overlapping_glyphs_p,
13684 row->enabled_p,
13685 row->truncated_on_left_p,
13686 row->truncated_on_right_p,
13687 row->overlay_arrow_p,
13688 row->continued_p,
13689 MATRIX_ROW_CONTINUATION_LINE_P (row),
13690 row->displays_text_p,
13691 row->ends_at_zv_p,
13692 row->fill_line_p,
13693 row->ends_in_middle_of_char_p,
13694 row->starts_in_middle_of_char_p,
13695 row->mouse_face_p,
13696 row->x,
13697 row->y,
13698 row->pixel_width,
13699 row->height,
13700 row->visible_height,
13701 row->ascent,
13702 row->phys_ascent);
13703 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13704 row->end.overlay_string_index,
13705 row->continuation_lines_width);
13706 fprintf (stderr, "%9d %5d\n",
13707 CHARPOS (row->start.string_pos),
13708 CHARPOS (row->end.string_pos));
13709 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13710 row->end.dpvec_index);
13711 }
13712
13713 if (glyphs > 1)
13714 {
13715 int area;
13716
13717 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13718 {
13719 struct glyph *glyph = row->glyphs[area];
13720 struct glyph *glyph_end = glyph + row->used[area];
13721
13722 /* Glyph for a line end in text. */
13723 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13724 ++glyph_end;
13725
13726 if (glyph < glyph_end)
13727 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13728
13729 for (; glyph < glyph_end; ++glyph)
13730 dump_glyph (row, glyph, area);
13731 }
13732 }
13733 else if (glyphs == 1)
13734 {
13735 int area;
13736
13737 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13738 {
13739 char *s = (char *) alloca (row->used[area] + 1);
13740 int i;
13741
13742 for (i = 0; i < row->used[area]; ++i)
13743 {
13744 struct glyph *glyph = row->glyphs[area] + i;
13745 if (glyph->type == CHAR_GLYPH
13746 && glyph->u.ch < 0x80
13747 && glyph->u.ch >= ' ')
13748 s[i] = glyph->u.ch;
13749 else
13750 s[i] = '.';
13751 }
13752
13753 s[i] = '\0';
13754 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13755 }
13756 }
13757 }
13758
13759
13760 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13761 Sdump_glyph_matrix, 0, 1, "p",
13762 doc: /* Dump the current matrix of the selected window to stderr.
13763 Shows contents of glyph row structures. With non-nil
13764 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13765 glyphs in short form, otherwise show glyphs in long form. */)
13766 (glyphs)
13767 Lisp_Object glyphs;
13768 {
13769 struct window *w = XWINDOW (selected_window);
13770 struct buffer *buffer = XBUFFER (w->buffer);
13771
13772 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13773 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13774 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13775 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13776 fprintf (stderr, "=============================================\n");
13777 dump_glyph_matrix (w->current_matrix,
13778 NILP (glyphs) ? 0 : XINT (glyphs));
13779 return Qnil;
13780 }
13781
13782
13783 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13784 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13785 ()
13786 {
13787 struct frame *f = XFRAME (selected_frame);
13788 dump_glyph_matrix (f->current_matrix, 1);
13789 return Qnil;
13790 }
13791
13792
13793 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13794 doc: /* Dump glyph row ROW to stderr.
13795 GLYPH 0 means don't dump glyphs.
13796 GLYPH 1 means dump glyphs in short form.
13797 GLYPH > 1 or omitted means dump glyphs in long form. */)
13798 (row, glyphs)
13799 Lisp_Object row, glyphs;
13800 {
13801 struct glyph_matrix *matrix;
13802 int vpos;
13803
13804 CHECK_NUMBER (row);
13805 matrix = XWINDOW (selected_window)->current_matrix;
13806 vpos = XINT (row);
13807 if (vpos >= 0 && vpos < matrix->nrows)
13808 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13809 vpos,
13810 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13811 return Qnil;
13812 }
13813
13814
13815 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13816 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13817 GLYPH 0 means don't dump glyphs.
13818 GLYPH 1 means dump glyphs in short form.
13819 GLYPH > 1 or omitted means dump glyphs in long form. */)
13820 (row, glyphs)
13821 Lisp_Object row, glyphs;
13822 {
13823 struct frame *sf = SELECTED_FRAME ();
13824 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13825 int vpos;
13826
13827 CHECK_NUMBER (row);
13828 vpos = XINT (row);
13829 if (vpos >= 0 && vpos < m->nrows)
13830 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13831 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13832 return Qnil;
13833 }
13834
13835
13836 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13837 doc: /* Toggle tracing of redisplay.
13838 With ARG, turn tracing on if and only if ARG is positive. */)
13839 (arg)
13840 Lisp_Object arg;
13841 {
13842 if (NILP (arg))
13843 trace_redisplay_p = !trace_redisplay_p;
13844 else
13845 {
13846 arg = Fprefix_numeric_value (arg);
13847 trace_redisplay_p = XINT (arg) > 0;
13848 }
13849
13850 return Qnil;
13851 }
13852
13853
13854 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13855 doc: /* Like `format', but print result to stderr.
13856 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13857 (nargs, args)
13858 int nargs;
13859 Lisp_Object *args;
13860 {
13861 Lisp_Object s = Fformat (nargs, args);
13862 fprintf (stderr, "%s", SDATA (s));
13863 return Qnil;
13864 }
13865
13866 #endif /* GLYPH_DEBUG */
13867
13868
13869 \f
13870 /***********************************************************************
13871 Building Desired Matrix Rows
13872 ***********************************************************************/
13873
13874 /* Return a temporary glyph row holding the glyphs of an overlay
13875 arrow. Only used for non-window-redisplay windows. */
13876
13877 static struct glyph_row *
13878 get_overlay_arrow_glyph_row (w)
13879 struct window *w;
13880 {
13881 struct frame *f = XFRAME (WINDOW_FRAME (w));
13882 struct buffer *buffer = XBUFFER (w->buffer);
13883 struct buffer *old = current_buffer;
13884 const unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
13885 int arrow_len = SCHARS (Voverlay_arrow_string);
13886 const unsigned char *arrow_end = arrow_string + arrow_len;
13887 const unsigned char *p;
13888 struct it it;
13889 int multibyte_p;
13890 int n_glyphs_before;
13891
13892 set_buffer_temp (buffer);
13893 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
13894 it.glyph_row->used[TEXT_AREA] = 0;
13895 SET_TEXT_POS (it.position, 0, 0);
13896
13897 multibyte_p = !NILP (buffer->enable_multibyte_characters);
13898 p = arrow_string;
13899 while (p < arrow_end)
13900 {
13901 Lisp_Object face, ilisp;
13902
13903 /* Get the next character. */
13904 if (multibyte_p)
13905 it.c = string_char_and_length (p, arrow_len, &it.len);
13906 else
13907 it.c = *p, it.len = 1;
13908 p += it.len;
13909
13910 /* Get its face. */
13911 ilisp = make_number (p - arrow_string);
13912 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
13913 it.face_id = compute_char_face (f, it.c, face);
13914
13915 /* Compute its width, get its glyphs. */
13916 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
13917 SET_TEXT_POS (it.position, -1, -1);
13918 PRODUCE_GLYPHS (&it);
13919
13920 /* If this character doesn't fit any more in the line, we have
13921 to remove some glyphs. */
13922 if (it.current_x > it.last_visible_x)
13923 {
13924 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
13925 break;
13926 }
13927 }
13928
13929 set_buffer_temp (old);
13930 return it.glyph_row;
13931 }
13932
13933
13934 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13935 glyphs are only inserted for terminal frames since we can't really
13936 win with truncation glyphs when partially visible glyphs are
13937 involved. Which glyphs to insert is determined by
13938 produce_special_glyphs. */
13939
13940 static void
13941 insert_left_trunc_glyphs (it)
13942 struct it *it;
13943 {
13944 struct it truncate_it;
13945 struct glyph *from, *end, *to, *toend;
13946
13947 xassert (!FRAME_WINDOW_P (it->f));
13948
13949 /* Get the truncation glyphs. */
13950 truncate_it = *it;
13951 truncate_it.current_x = 0;
13952 truncate_it.face_id = DEFAULT_FACE_ID;
13953 truncate_it.glyph_row = &scratch_glyph_row;
13954 truncate_it.glyph_row->used[TEXT_AREA] = 0;
13955 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
13956 truncate_it.object = make_number (0);
13957 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
13958
13959 /* Overwrite glyphs from IT with truncation glyphs. */
13960 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13961 end = from + truncate_it.glyph_row->used[TEXT_AREA];
13962 to = it->glyph_row->glyphs[TEXT_AREA];
13963 toend = to + it->glyph_row->used[TEXT_AREA];
13964
13965 while (from < end)
13966 *to++ = *from++;
13967
13968 /* There may be padding glyphs left over. Overwrite them too. */
13969 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
13970 {
13971 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13972 while (from < end)
13973 *to++ = *from++;
13974 }
13975
13976 if (to > toend)
13977 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
13978 }
13979
13980
13981 /* Compute the pixel height and width of IT->glyph_row.
13982
13983 Most of the time, ascent and height of a display line will be equal
13984 to the max_ascent and max_height values of the display iterator
13985 structure. This is not the case if
13986
13987 1. We hit ZV without displaying anything. In this case, max_ascent
13988 and max_height will be zero.
13989
13990 2. We have some glyphs that don't contribute to the line height.
13991 (The glyph row flag contributes_to_line_height_p is for future
13992 pixmap extensions).
13993
13994 The first case is easily covered by using default values because in
13995 these cases, the line height does not really matter, except that it
13996 must not be zero. */
13997
13998 static void
13999 compute_line_metrics (it)
14000 struct it *it;
14001 {
14002 struct glyph_row *row = it->glyph_row;
14003 int area, i;
14004
14005 if (FRAME_WINDOW_P (it->f))
14006 {
14007 int i, min_y, max_y;
14008
14009 /* The line may consist of one space only, that was added to
14010 place the cursor on it. If so, the row's height hasn't been
14011 computed yet. */
14012 if (row->height == 0)
14013 {
14014 if (it->max_ascent + it->max_descent == 0)
14015 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14016 row->ascent = it->max_ascent;
14017 row->height = it->max_ascent + it->max_descent;
14018 row->phys_ascent = it->max_phys_ascent;
14019 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14020 }
14021
14022 /* Compute the width of this line. */
14023 row->pixel_width = row->x;
14024 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14025 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14026
14027 xassert (row->pixel_width >= 0);
14028 xassert (row->ascent >= 0 && row->height > 0);
14029
14030 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14031 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14032
14033 /* If first line's physical ascent is larger than its logical
14034 ascent, use the physical ascent, and make the row taller.
14035 This makes accented characters fully visible. */
14036 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14037 && row->phys_ascent > row->ascent)
14038 {
14039 row->height += row->phys_ascent - row->ascent;
14040 row->ascent = row->phys_ascent;
14041 }
14042
14043 /* Compute how much of the line is visible. */
14044 row->visible_height = row->height;
14045
14046 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14047 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14048
14049 if (row->y < min_y)
14050 row->visible_height -= min_y - row->y;
14051 if (row->y + row->height > max_y)
14052 row->visible_height -= row->y + row->height - max_y;
14053 }
14054 else
14055 {
14056 row->pixel_width = row->used[TEXT_AREA];
14057 if (row->continued_p)
14058 row->pixel_width -= it->continuation_pixel_width;
14059 else if (row->truncated_on_right_p)
14060 row->pixel_width -= it->truncation_pixel_width;
14061 row->ascent = row->phys_ascent = 0;
14062 row->height = row->phys_height = row->visible_height = 1;
14063 }
14064
14065 /* Compute a hash code for this row. */
14066 row->hash = 0;
14067 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14068 for (i = 0; i < row->used[area]; ++i)
14069 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14070 + row->glyphs[area][i].u.val
14071 + row->glyphs[area][i].face_id
14072 + row->glyphs[area][i].padding_p
14073 + (row->glyphs[area][i].type << 2));
14074
14075 it->max_ascent = it->max_descent = 0;
14076 it->max_phys_ascent = it->max_phys_descent = 0;
14077 }
14078
14079
14080 /* Append one space to the glyph row of iterator IT if doing a
14081 window-based redisplay. DEFAULT_FACE_P non-zero means let the
14082 space have the default face, otherwise let it have the same face as
14083 IT->face_id. Value is non-zero if a space was added.
14084
14085 This function is called to make sure that there is always one glyph
14086 at the end of a glyph row that the cursor can be set on under
14087 window-systems. (If there weren't such a glyph we would not know
14088 how wide and tall a box cursor should be displayed).
14089
14090 At the same time this space let's a nicely handle clearing to the
14091 end of the line if the row ends in italic text. */
14092
14093 static int
14094 append_space (it, default_face_p)
14095 struct it *it;
14096 int default_face_p;
14097 {
14098 if (FRAME_WINDOW_P (it->f))
14099 {
14100 int n = it->glyph_row->used[TEXT_AREA];
14101
14102 if (it->glyph_row->glyphs[TEXT_AREA] + n
14103 < it->glyph_row->glyphs[1 + TEXT_AREA])
14104 {
14105 /* Save some values that must not be changed.
14106 Must save IT->c and IT->len because otherwise
14107 ITERATOR_AT_END_P wouldn't work anymore after
14108 append_space has been called. */
14109 enum display_element_type saved_what = it->what;
14110 int saved_c = it->c, saved_len = it->len;
14111 int saved_x = it->current_x;
14112 int saved_face_id = it->face_id;
14113 struct text_pos saved_pos;
14114 Lisp_Object saved_object;
14115 struct face *face;
14116
14117 saved_object = it->object;
14118 saved_pos = it->position;
14119
14120 it->what = IT_CHARACTER;
14121 bzero (&it->position, sizeof it->position);
14122 it->object = make_number (0);
14123 it->c = ' ';
14124 it->len = 1;
14125
14126 if (default_face_p)
14127 it->face_id = DEFAULT_FACE_ID;
14128 else if (it->face_before_selective_p)
14129 it->face_id = it->saved_face_id;
14130 face = FACE_FROM_ID (it->f, it->face_id);
14131 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14132
14133 PRODUCE_GLYPHS (it);
14134
14135 it->current_x = saved_x;
14136 it->object = saved_object;
14137 it->position = saved_pos;
14138 it->what = saved_what;
14139 it->face_id = saved_face_id;
14140 it->len = saved_len;
14141 it->c = saved_c;
14142 return 1;
14143 }
14144 }
14145
14146 return 0;
14147 }
14148
14149
14150 /* Extend the face of the last glyph in the text area of IT->glyph_row
14151 to the end of the display line. Called from display_line.
14152 If the glyph row is empty, add a space glyph to it so that we
14153 know the face to draw. Set the glyph row flag fill_line_p. */
14154
14155 static void
14156 extend_face_to_end_of_line (it)
14157 struct it *it;
14158 {
14159 struct face *face;
14160 struct frame *f = it->f;
14161
14162 /* If line is already filled, do nothing. */
14163 if (it->current_x >= it->last_visible_x)
14164 return;
14165
14166 /* Face extension extends the background and box of IT->face_id
14167 to the end of the line. If the background equals the background
14168 of the frame, we don't have to do anything. */
14169 if (it->face_before_selective_p)
14170 face = FACE_FROM_ID (it->f, it->saved_face_id);
14171 else
14172 face = FACE_FROM_ID (f, it->face_id);
14173
14174 if (FRAME_WINDOW_P (f)
14175 && face->box == FACE_NO_BOX
14176 && face->background == FRAME_BACKGROUND_PIXEL (f)
14177 && !face->stipple)
14178 return;
14179
14180 /* Set the glyph row flag indicating that the face of the last glyph
14181 in the text area has to be drawn to the end of the text area. */
14182 it->glyph_row->fill_line_p = 1;
14183
14184 /* If current character of IT is not ASCII, make sure we have the
14185 ASCII face. This will be automatically undone the next time
14186 get_next_display_element returns a multibyte character. Note
14187 that the character will always be single byte in unibyte text. */
14188 if (!SINGLE_BYTE_CHAR_P (it->c))
14189 {
14190 it->face_id = FACE_FOR_CHAR (f, face, 0);
14191 }
14192
14193 if (FRAME_WINDOW_P (f))
14194 {
14195 /* If the row is empty, add a space with the current face of IT,
14196 so that we know which face to draw. */
14197 if (it->glyph_row->used[TEXT_AREA] == 0)
14198 {
14199 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14200 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14201 it->glyph_row->used[TEXT_AREA] = 1;
14202 }
14203 }
14204 else
14205 {
14206 /* Save some values that must not be changed. */
14207 int saved_x = it->current_x;
14208 struct text_pos saved_pos;
14209 Lisp_Object saved_object;
14210 enum display_element_type saved_what = it->what;
14211 int saved_face_id = it->face_id;
14212
14213 saved_object = it->object;
14214 saved_pos = it->position;
14215
14216 it->what = IT_CHARACTER;
14217 bzero (&it->position, sizeof it->position);
14218 it->object = make_number (0);
14219 it->c = ' ';
14220 it->len = 1;
14221 it->face_id = face->id;
14222
14223 PRODUCE_GLYPHS (it);
14224
14225 while (it->current_x <= it->last_visible_x)
14226 PRODUCE_GLYPHS (it);
14227
14228 /* Don't count these blanks really. It would let us insert a left
14229 truncation glyph below and make us set the cursor on them, maybe. */
14230 it->current_x = saved_x;
14231 it->object = saved_object;
14232 it->position = saved_pos;
14233 it->what = saved_what;
14234 it->face_id = saved_face_id;
14235 }
14236 }
14237
14238
14239 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14240 trailing whitespace. */
14241
14242 static int
14243 trailing_whitespace_p (charpos)
14244 int charpos;
14245 {
14246 int bytepos = CHAR_TO_BYTE (charpos);
14247 int c = 0;
14248
14249 while (bytepos < ZV_BYTE
14250 && (c = FETCH_CHAR (bytepos),
14251 c == ' ' || c == '\t'))
14252 ++bytepos;
14253
14254 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14255 {
14256 if (bytepos != PT_BYTE)
14257 return 1;
14258 }
14259 return 0;
14260 }
14261
14262
14263 /* Highlight trailing whitespace, if any, in ROW. */
14264
14265 void
14266 highlight_trailing_whitespace (f, row)
14267 struct frame *f;
14268 struct glyph_row *row;
14269 {
14270 int used = row->used[TEXT_AREA];
14271
14272 if (used)
14273 {
14274 struct glyph *start = row->glyphs[TEXT_AREA];
14275 struct glyph *glyph = start + used - 1;
14276
14277 /* Skip over glyphs inserted to display the cursor at the
14278 end of a line, for extending the face of the last glyph
14279 to the end of the line on terminals, and for truncation
14280 and continuation glyphs. */
14281 while (glyph >= start
14282 && glyph->type == CHAR_GLYPH
14283 && INTEGERP (glyph->object))
14284 --glyph;
14285
14286 /* If last glyph is a space or stretch, and it's trailing
14287 whitespace, set the face of all trailing whitespace glyphs in
14288 IT->glyph_row to `trailing-whitespace'. */
14289 if (glyph >= start
14290 && BUFFERP (glyph->object)
14291 && (glyph->type == STRETCH_GLYPH
14292 || (glyph->type == CHAR_GLYPH
14293 && glyph->u.ch == ' '))
14294 && trailing_whitespace_p (glyph->charpos))
14295 {
14296 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14297
14298 while (glyph >= start
14299 && BUFFERP (glyph->object)
14300 && (glyph->type == STRETCH_GLYPH
14301 || (glyph->type == CHAR_GLYPH
14302 && glyph->u.ch == ' ')))
14303 (glyph--)->face_id = face_id;
14304 }
14305 }
14306 }
14307
14308
14309 /* Value is non-zero if glyph row ROW in window W should be
14310 used to hold the cursor. */
14311
14312 static int
14313 cursor_row_p (w, row)
14314 struct window *w;
14315 struct glyph_row *row;
14316 {
14317 int cursor_row_p = 1;
14318
14319 if (PT == MATRIX_ROW_END_CHARPOS (row))
14320 {
14321 /* If the row ends with a newline from a string, we don't want
14322 the cursor there (if the row is continued it doesn't end in a
14323 newline). */
14324 if (CHARPOS (row->end.string_pos) >= 0
14325 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14326 cursor_row_p = row->continued_p;
14327
14328 /* If the row ends at ZV, display the cursor at the end of that
14329 row instead of at the start of the row below. */
14330 else if (row->ends_at_zv_p)
14331 cursor_row_p = 1;
14332 else
14333 cursor_row_p = 0;
14334 }
14335
14336 return cursor_row_p;
14337 }
14338
14339
14340 /* Construct the glyph row IT->glyph_row in the desired matrix of
14341 IT->w from text at the current position of IT. See dispextern.h
14342 for an overview of struct it. Value is non-zero if
14343 IT->glyph_row displays text, as opposed to a line displaying ZV
14344 only. */
14345
14346 static int
14347 display_line (it)
14348 struct it *it;
14349 {
14350 struct glyph_row *row = it->glyph_row;
14351
14352 /* We always start displaying at hpos zero even if hscrolled. */
14353 xassert (it->hpos == 0 && it->current_x == 0);
14354
14355 /* We must not display in a row that's not a text row. */
14356 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14357 < it->w->desired_matrix->nrows);
14358
14359 /* Is IT->w showing the region? */
14360 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14361
14362 /* Clear the result glyph row and enable it. */
14363 prepare_desired_row (row);
14364
14365 row->y = it->current_y;
14366 row->start = it->start;
14367 row->continuation_lines_width = it->continuation_lines_width;
14368 row->displays_text_p = 1;
14369 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14370 it->starts_in_middle_of_char_p = 0;
14371
14372 /* Arrange the overlays nicely for our purposes. Usually, we call
14373 display_line on only one line at a time, in which case this
14374 can't really hurt too much, or we call it on lines which appear
14375 one after another in the buffer, in which case all calls to
14376 recenter_overlay_lists but the first will be pretty cheap. */
14377 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14378
14379 /* Move over display elements that are not visible because we are
14380 hscrolled. This may stop at an x-position < IT->first_visible_x
14381 if the first glyph is partially visible or if we hit a line end. */
14382 if (it->current_x < it->first_visible_x)
14383 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14384 MOVE_TO_POS | MOVE_TO_X);
14385
14386 /* Get the initial row height. This is either the height of the
14387 text hscrolled, if there is any, or zero. */
14388 row->ascent = it->max_ascent;
14389 row->height = it->max_ascent + it->max_descent;
14390 row->phys_ascent = it->max_phys_ascent;
14391 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14392
14393 /* Loop generating characters. The loop is left with IT on the next
14394 character to display. */
14395 while (1)
14396 {
14397 int n_glyphs_before, hpos_before, x_before;
14398 int x, i, nglyphs;
14399 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14400
14401 /* Retrieve the next thing to display. Value is zero if end of
14402 buffer reached. */
14403 if (!get_next_display_element (it))
14404 {
14405 /* Maybe add a space at the end of this line that is used to
14406 display the cursor there under X. Set the charpos of the
14407 first glyph of blank lines not corresponding to any text
14408 to -1. */
14409 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14410 || row->used[TEXT_AREA] == 0)
14411 {
14412 row->glyphs[TEXT_AREA]->charpos = -1;
14413 row->displays_text_p = 0;
14414
14415 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14416 && (!MINI_WINDOW_P (it->w)
14417 || (minibuf_level && EQ (it->window, minibuf_window))))
14418 row->indicate_empty_line_p = 1;
14419 }
14420
14421 it->continuation_lines_width = 0;
14422 row->ends_at_zv_p = 1;
14423 break;
14424 }
14425
14426 /* Now, get the metrics of what we want to display. This also
14427 generates glyphs in `row' (which is IT->glyph_row). */
14428 n_glyphs_before = row->used[TEXT_AREA];
14429 x = it->current_x;
14430
14431 /* Remember the line height so far in case the next element doesn't
14432 fit on the line. */
14433 if (!it->truncate_lines_p)
14434 {
14435 ascent = it->max_ascent;
14436 descent = it->max_descent;
14437 phys_ascent = it->max_phys_ascent;
14438 phys_descent = it->max_phys_descent;
14439 }
14440
14441 PRODUCE_GLYPHS (it);
14442
14443 /* If this display element was in marginal areas, continue with
14444 the next one. */
14445 if (it->area != TEXT_AREA)
14446 {
14447 row->ascent = max (row->ascent, it->max_ascent);
14448 row->height = max (row->height, it->max_ascent + it->max_descent);
14449 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14450 row->phys_height = max (row->phys_height,
14451 it->max_phys_ascent + it->max_phys_descent);
14452 set_iterator_to_next (it, 1);
14453 continue;
14454 }
14455
14456 /* Does the display element fit on the line? If we truncate
14457 lines, we should draw past the right edge of the window. If
14458 we don't truncate, we want to stop so that we can display the
14459 continuation glyph before the right margin. If lines are
14460 continued, there are two possible strategies for characters
14461 resulting in more than 1 glyph (e.g. tabs): Display as many
14462 glyphs as possible in this line and leave the rest for the
14463 continuation line, or display the whole element in the next
14464 line. Original redisplay did the former, so we do it also. */
14465 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14466 hpos_before = it->hpos;
14467 x_before = x;
14468
14469 if (/* Not a newline. */
14470 nglyphs > 0
14471 /* Glyphs produced fit entirely in the line. */
14472 && it->current_x < it->last_visible_x)
14473 {
14474 it->hpos += nglyphs;
14475 row->ascent = max (row->ascent, it->max_ascent);
14476 row->height = max (row->height, it->max_ascent + it->max_descent);
14477 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14478 row->phys_height = max (row->phys_height,
14479 it->max_phys_ascent + it->max_phys_descent);
14480 if (it->current_x - it->pixel_width < it->first_visible_x)
14481 row->x = x - it->first_visible_x;
14482 }
14483 else
14484 {
14485 int new_x;
14486 struct glyph *glyph;
14487
14488 for (i = 0; i < nglyphs; ++i, x = new_x)
14489 {
14490 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14491 new_x = x + glyph->pixel_width;
14492
14493 if (/* Lines are continued. */
14494 !it->truncate_lines_p
14495 && (/* Glyph doesn't fit on the line. */
14496 new_x > it->last_visible_x
14497 /* Or it fits exactly on a window system frame. */
14498 || (new_x == it->last_visible_x
14499 && FRAME_WINDOW_P (it->f))))
14500 {
14501 /* End of a continued line. */
14502
14503 if (it->hpos == 0
14504 || (new_x == it->last_visible_x
14505 && FRAME_WINDOW_P (it->f)))
14506 {
14507 /* Current glyph is the only one on the line or
14508 fits exactly on the line. We must continue
14509 the line because we can't draw the cursor
14510 after the glyph. */
14511 row->continued_p = 1;
14512 it->current_x = new_x;
14513 it->continuation_lines_width += new_x;
14514 ++it->hpos;
14515 if (i == nglyphs - 1)
14516 set_iterator_to_next (it, 1);
14517 }
14518 else if (CHAR_GLYPH_PADDING_P (*glyph)
14519 && !FRAME_WINDOW_P (it->f))
14520 {
14521 /* A padding glyph that doesn't fit on this line.
14522 This means the whole character doesn't fit
14523 on the line. */
14524 row->used[TEXT_AREA] = n_glyphs_before;
14525
14526 /* Fill the rest of the row with continuation
14527 glyphs like in 20.x. */
14528 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14529 < row->glyphs[1 + TEXT_AREA])
14530 produce_special_glyphs (it, IT_CONTINUATION);
14531
14532 row->continued_p = 1;
14533 it->current_x = x_before;
14534 it->continuation_lines_width += x_before;
14535
14536 /* Restore the height to what it was before the
14537 element not fitting on the line. */
14538 it->max_ascent = ascent;
14539 it->max_descent = descent;
14540 it->max_phys_ascent = phys_ascent;
14541 it->max_phys_descent = phys_descent;
14542 }
14543 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14544 {
14545 /* A TAB that extends past the right edge of the
14546 window. This produces a single glyph on
14547 window system frames. We leave the glyph in
14548 this row and let it fill the row, but don't
14549 consume the TAB. */
14550 it->continuation_lines_width += it->last_visible_x;
14551 row->ends_in_middle_of_char_p = 1;
14552 row->continued_p = 1;
14553 glyph->pixel_width = it->last_visible_x - x;
14554 it->starts_in_middle_of_char_p = 1;
14555 }
14556 else
14557 {
14558 /* Something other than a TAB that draws past
14559 the right edge of the window. Restore
14560 positions to values before the element. */
14561 row->used[TEXT_AREA] = n_glyphs_before + i;
14562
14563 /* Display continuation glyphs. */
14564 if (!FRAME_WINDOW_P (it->f))
14565 produce_special_glyphs (it, IT_CONTINUATION);
14566 row->continued_p = 1;
14567
14568 it->continuation_lines_width += x;
14569
14570 if (nglyphs > 1 && i > 0)
14571 {
14572 row->ends_in_middle_of_char_p = 1;
14573 it->starts_in_middle_of_char_p = 1;
14574 }
14575
14576 /* Restore the height to what it was before the
14577 element not fitting on the line. */
14578 it->max_ascent = ascent;
14579 it->max_descent = descent;
14580 it->max_phys_ascent = phys_ascent;
14581 it->max_phys_descent = phys_descent;
14582 }
14583
14584 break;
14585 }
14586 else if (new_x > it->first_visible_x)
14587 {
14588 /* Increment number of glyphs actually displayed. */
14589 ++it->hpos;
14590
14591 if (x < it->first_visible_x)
14592 /* Glyph is partially visible, i.e. row starts at
14593 negative X position. */
14594 row->x = x - it->first_visible_x;
14595 }
14596 else
14597 {
14598 /* Glyph is completely off the left margin of the
14599 window. This should not happen because of the
14600 move_it_in_display_line at the start of this
14601 function, unless the text display area of the
14602 window is empty. */
14603 xassert (it->first_visible_x <= it->last_visible_x);
14604 }
14605 }
14606
14607 row->ascent = max (row->ascent, it->max_ascent);
14608 row->height = max (row->height, it->max_ascent + it->max_descent);
14609 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14610 row->phys_height = max (row->phys_height,
14611 it->max_phys_ascent + it->max_phys_descent);
14612
14613 /* End of this display line if row is continued. */
14614 if (row->continued_p)
14615 break;
14616 }
14617
14618 /* Is this a line end? If yes, we're also done, after making
14619 sure that a non-default face is extended up to the right
14620 margin of the window. */
14621 if (ITERATOR_AT_END_OF_LINE_P (it))
14622 {
14623 int used_before = row->used[TEXT_AREA];
14624
14625 row->ends_in_newline_from_string_p = STRINGP (it->object);
14626
14627 /* Add a space at the end of the line that is used to
14628 display the cursor there. */
14629 append_space (it, 0);
14630
14631 /* Extend the face to the end of the line. */
14632 extend_face_to_end_of_line (it);
14633
14634 /* Make sure we have the position. */
14635 if (used_before == 0)
14636 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14637
14638 /* Consume the line end. This skips over invisible lines. */
14639 set_iterator_to_next (it, 1);
14640 it->continuation_lines_width = 0;
14641 break;
14642 }
14643
14644 /* Proceed with next display element. Note that this skips
14645 over lines invisible because of selective display. */
14646 set_iterator_to_next (it, 1);
14647
14648 /* If we truncate lines, we are done when the last displayed
14649 glyphs reach past the right margin of the window. */
14650 if (it->truncate_lines_p
14651 && (FRAME_WINDOW_P (it->f)
14652 ? (it->current_x >= it->last_visible_x)
14653 : (it->current_x > it->last_visible_x)))
14654 {
14655 /* Maybe add truncation glyphs. */
14656 if (!FRAME_WINDOW_P (it->f))
14657 {
14658 int i, n;
14659
14660 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14661 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14662 break;
14663
14664 for (n = row->used[TEXT_AREA]; i < n; ++i)
14665 {
14666 row->used[TEXT_AREA] = i;
14667 produce_special_glyphs (it, IT_TRUNCATION);
14668 }
14669 }
14670
14671 row->truncated_on_right_p = 1;
14672 it->continuation_lines_width = 0;
14673 reseat_at_next_visible_line_start (it, 0);
14674 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14675 it->hpos = hpos_before;
14676 it->current_x = x_before;
14677 break;
14678 }
14679 }
14680
14681 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14682 at the left window margin. */
14683 if (it->first_visible_x
14684 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14685 {
14686 if (!FRAME_WINDOW_P (it->f))
14687 insert_left_trunc_glyphs (it);
14688 row->truncated_on_left_p = 1;
14689 }
14690
14691 /* If the start of this line is the overlay arrow-position, then
14692 mark this glyph row as the one containing the overlay arrow.
14693 This is clearly a mess with variable size fonts. It would be
14694 better to let it be displayed like cursors under X. */
14695 if (MARKERP (Voverlay_arrow_position)
14696 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
14697 && (MATRIX_ROW_START_CHARPOS (row)
14698 == marker_position (Voverlay_arrow_position))
14699 && STRINGP (Voverlay_arrow_string)
14700 && ! overlay_arrow_seen)
14701 {
14702 /* Overlay arrow in window redisplay is a fringe bitmap. */
14703 if (!FRAME_WINDOW_P (it->f))
14704 {
14705 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
14706 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14707 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14708 struct glyph *p = row->glyphs[TEXT_AREA];
14709 struct glyph *p2, *end;
14710
14711 /* Copy the arrow glyphs. */
14712 while (glyph < arrow_end)
14713 *p++ = *glyph++;
14714
14715 /* Throw away padding glyphs. */
14716 p2 = p;
14717 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14718 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14719 ++p2;
14720 if (p2 > p)
14721 {
14722 while (p2 < end)
14723 *p++ = *p2++;
14724 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14725 }
14726 }
14727
14728 overlay_arrow_seen = 1;
14729 row->overlay_arrow_p = 1;
14730 }
14731
14732 /* Compute pixel dimensions of this line. */
14733 compute_line_metrics (it);
14734
14735 /* Remember the position at which this line ends. */
14736 row->end = it->current;
14737
14738 /* Maybe set the cursor. */
14739 if (it->w->cursor.vpos < 0
14740 && PT >= MATRIX_ROW_START_CHARPOS (row)
14741 && PT <= MATRIX_ROW_END_CHARPOS (row)
14742 && cursor_row_p (it->w, row))
14743 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14744
14745 /* Highlight trailing whitespace. */
14746 if (!NILP (Vshow_trailing_whitespace))
14747 highlight_trailing_whitespace (it->f, it->glyph_row);
14748
14749 /* Prepare for the next line. This line starts horizontally at (X
14750 HPOS) = (0 0). Vertical positions are incremented. As a
14751 convenience for the caller, IT->glyph_row is set to the next
14752 row to be used. */
14753 it->current_x = it->hpos = 0;
14754 it->current_y += row->height;
14755 ++it->vpos;
14756 ++it->glyph_row;
14757 it->start = it->current;
14758 return row->displays_text_p;
14759 }
14760
14761
14762 \f
14763 /***********************************************************************
14764 Menu Bar
14765 ***********************************************************************/
14766
14767 /* Redisplay the menu bar in the frame for window W.
14768
14769 The menu bar of X frames that don't have X toolkit support is
14770 displayed in a special window W->frame->menu_bar_window.
14771
14772 The menu bar of terminal frames is treated specially as far as
14773 glyph matrices are concerned. Menu bar lines are not part of
14774 windows, so the update is done directly on the frame matrix rows
14775 for the menu bar. */
14776
14777 static void
14778 display_menu_bar (w)
14779 struct window *w;
14780 {
14781 struct frame *f = XFRAME (WINDOW_FRAME (w));
14782 struct it it;
14783 Lisp_Object items;
14784 int i;
14785
14786 /* Don't do all this for graphical frames. */
14787 #ifdef HAVE_NTGUI
14788 if (!NILP (Vwindow_system))
14789 return;
14790 #endif
14791 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14792 if (FRAME_X_P (f))
14793 return;
14794 #endif
14795 #ifdef MAC_OS
14796 if (FRAME_MAC_P (f))
14797 return;
14798 #endif
14799
14800 #ifdef USE_X_TOOLKIT
14801 xassert (!FRAME_WINDOW_P (f));
14802 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
14803 it.first_visible_x = 0;
14804 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14805 #else /* not USE_X_TOOLKIT */
14806 if (FRAME_WINDOW_P (f))
14807 {
14808 /* Menu bar lines are displayed in the desired matrix of the
14809 dummy window menu_bar_window. */
14810 struct window *menu_w;
14811 xassert (WINDOWP (f->menu_bar_window));
14812 menu_w = XWINDOW (f->menu_bar_window);
14813 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
14814 MENU_FACE_ID);
14815 it.first_visible_x = 0;
14816 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14817 }
14818 else
14819 {
14820 /* This is a TTY frame, i.e. character hpos/vpos are used as
14821 pixel x/y. */
14822 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
14823 MENU_FACE_ID);
14824 it.first_visible_x = 0;
14825 it.last_visible_x = FRAME_COLS (f);
14826 }
14827 #endif /* not USE_X_TOOLKIT */
14828
14829 if (! mode_line_inverse_video)
14830 /* Force the menu-bar to be displayed in the default face. */
14831 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14832
14833 /* Clear all rows of the menu bar. */
14834 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
14835 {
14836 struct glyph_row *row = it.glyph_row + i;
14837 clear_glyph_row (row);
14838 row->enabled_p = 1;
14839 row->full_width_p = 1;
14840 }
14841
14842 /* Display all items of the menu bar. */
14843 items = FRAME_MENU_BAR_ITEMS (it.f);
14844 for (i = 0; i < XVECTOR (items)->size; i += 4)
14845 {
14846 Lisp_Object string;
14847
14848 /* Stop at nil string. */
14849 string = AREF (items, i + 1);
14850 if (NILP (string))
14851 break;
14852
14853 /* Remember where item was displayed. */
14854 AREF (items, i + 3) = make_number (it.hpos);
14855
14856 /* Display the item, pad with one space. */
14857 if (it.current_x < it.last_visible_x)
14858 display_string (NULL, string, Qnil, 0, 0, &it,
14859 SCHARS (string) + 1, 0, 0, -1);
14860 }
14861
14862 /* Fill out the line with spaces. */
14863 if (it.current_x < it.last_visible_x)
14864 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
14865
14866 /* Compute the total height of the lines. */
14867 compute_line_metrics (&it);
14868 }
14869
14870
14871 \f
14872 /***********************************************************************
14873 Mode Line
14874 ***********************************************************************/
14875
14876 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14877 FORCE is non-zero, redisplay mode lines unconditionally.
14878 Otherwise, redisplay only mode lines that are garbaged. Value is
14879 the number of windows whose mode lines were redisplayed. */
14880
14881 static int
14882 redisplay_mode_lines (window, force)
14883 Lisp_Object window;
14884 int force;
14885 {
14886 int nwindows = 0;
14887
14888 while (!NILP (window))
14889 {
14890 struct window *w = XWINDOW (window);
14891
14892 if (WINDOWP (w->hchild))
14893 nwindows += redisplay_mode_lines (w->hchild, force);
14894 else if (WINDOWP (w->vchild))
14895 nwindows += redisplay_mode_lines (w->vchild, force);
14896 else if (force
14897 || FRAME_GARBAGED_P (XFRAME (w->frame))
14898 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
14899 {
14900 struct text_pos lpoint;
14901 struct buffer *old = current_buffer;
14902
14903 /* Set the window's buffer for the mode line display. */
14904 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14905 set_buffer_internal_1 (XBUFFER (w->buffer));
14906
14907 /* Point refers normally to the selected window. For any
14908 other window, set up appropriate value. */
14909 if (!EQ (window, selected_window))
14910 {
14911 struct text_pos pt;
14912
14913 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
14914 if (CHARPOS (pt) < BEGV)
14915 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14916 else if (CHARPOS (pt) > (ZV - 1))
14917 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
14918 else
14919 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
14920 }
14921
14922 /* Display mode lines. */
14923 clear_glyph_matrix (w->desired_matrix);
14924 if (display_mode_lines (w))
14925 {
14926 ++nwindows;
14927 w->must_be_updated_p = 1;
14928 }
14929
14930 /* Restore old settings. */
14931 set_buffer_internal_1 (old);
14932 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14933 }
14934
14935 window = w->next;
14936 }
14937
14938 return nwindows;
14939 }
14940
14941
14942 /* Display the mode and/or top line of window W. Value is the number
14943 of mode lines displayed. */
14944
14945 static int
14946 display_mode_lines (w)
14947 struct window *w;
14948 {
14949 Lisp_Object old_selected_window, old_selected_frame;
14950 int n = 0;
14951
14952 old_selected_frame = selected_frame;
14953 selected_frame = w->frame;
14954 old_selected_window = selected_window;
14955 XSETWINDOW (selected_window, w);
14956
14957 /* These will be set while the mode line specs are processed. */
14958 line_number_displayed = 0;
14959 w->column_number_displayed = Qnil;
14960
14961 if (WINDOW_WANTS_MODELINE_P (w))
14962 {
14963 struct window *sel_w = XWINDOW (old_selected_window);
14964
14965 /* Select mode line face based on the real selected window. */
14966 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
14967 current_buffer->mode_line_format);
14968 ++n;
14969 }
14970
14971 if (WINDOW_WANTS_HEADER_LINE_P (w))
14972 {
14973 display_mode_line (w, HEADER_LINE_FACE_ID,
14974 current_buffer->header_line_format);
14975 ++n;
14976 }
14977
14978 selected_frame = old_selected_frame;
14979 selected_window = old_selected_window;
14980 return n;
14981 }
14982
14983
14984 /* Display mode or top line of window W. FACE_ID specifies which line
14985 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
14986 FORMAT is the mode line format to display. Value is the pixel
14987 height of the mode line displayed. */
14988
14989 static int
14990 display_mode_line (w, face_id, format)
14991 struct window *w;
14992 enum face_id face_id;
14993 Lisp_Object format;
14994 {
14995 struct it it;
14996 struct face *face;
14997
14998 init_iterator (&it, w, -1, -1, NULL, face_id);
14999 prepare_desired_row (it.glyph_row);
15000
15001 if (! mode_line_inverse_video)
15002 /* Force the mode-line to be displayed in the default face. */
15003 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15004
15005 /* Temporarily make frame's keyboard the current kboard so that
15006 kboard-local variables in the mode_line_format will get the right
15007 values. */
15008 push_frame_kboard (it.f);
15009 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15010 pop_frame_kboard ();
15011
15012 /* Fill up with spaces. */
15013 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15014
15015 compute_line_metrics (&it);
15016 it.glyph_row->full_width_p = 1;
15017 it.glyph_row->mode_line_p = 1;
15018 it.glyph_row->continued_p = 0;
15019 it.glyph_row->truncated_on_left_p = 0;
15020 it.glyph_row->truncated_on_right_p = 0;
15021
15022 /* Make a 3D mode-line have a shadow at its right end. */
15023 face = FACE_FROM_ID (it.f, face_id);
15024 extend_face_to_end_of_line (&it);
15025 if (face->box != FACE_NO_BOX)
15026 {
15027 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15028 + it.glyph_row->used[TEXT_AREA] - 1);
15029 last->right_box_line_p = 1;
15030 }
15031
15032 return it.glyph_row->height;
15033 }
15034
15035 /* Alist that caches the results of :propertize.
15036 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15037 Lisp_Object mode_line_proptrans_alist;
15038
15039 /* List of strings making up the mode-line. */
15040 Lisp_Object mode_line_string_list;
15041
15042 /* Base face property when building propertized mode line string. */
15043 static Lisp_Object mode_line_string_face;
15044 static Lisp_Object mode_line_string_face_prop;
15045
15046
15047 /* Contribute ELT to the mode line for window IT->w. How it
15048 translates into text depends on its data type.
15049
15050 IT describes the display environment in which we display, as usual.
15051
15052 DEPTH is the depth in recursion. It is used to prevent
15053 infinite recursion here.
15054
15055 FIELD_WIDTH is the number of characters the display of ELT should
15056 occupy in the mode line, and PRECISION is the maximum number of
15057 characters to display from ELT's representation. See
15058 display_string for details.
15059
15060 Returns the hpos of the end of the text generated by ELT.
15061
15062 PROPS is a property list to add to any string we encounter.
15063
15064 If RISKY is nonzero, remove (disregard) any properties in any string
15065 we encounter, and ignore :eval and :propertize.
15066
15067 If the global variable `frame_title_ptr' is non-NULL, then the output
15068 is passed to `store_frame_title' instead of `display_string'. */
15069
15070 static int
15071 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15072 struct it *it;
15073 int depth;
15074 int field_width, precision;
15075 Lisp_Object elt, props;
15076 int risky;
15077 {
15078 int n = 0, field, prec;
15079 int literal = 0;
15080
15081 tail_recurse:
15082 if (depth > 100)
15083 elt = build_string ("*too-deep*");
15084
15085 depth++;
15086
15087 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15088 {
15089 case Lisp_String:
15090 {
15091 /* A string: output it and check for %-constructs within it. */
15092 unsigned char c;
15093 const unsigned char *this, *lisp_string;
15094
15095 if (!NILP (props) || risky)
15096 {
15097 Lisp_Object oprops, aelt;
15098 oprops = Ftext_properties_at (make_number (0), elt);
15099
15100 if (NILP (Fequal (props, oprops)) || risky)
15101 {
15102 /* If the starting string has properties,
15103 merge the specified ones onto the existing ones. */
15104 if (! NILP (oprops) && !risky)
15105 {
15106 Lisp_Object tem;
15107
15108 oprops = Fcopy_sequence (oprops);
15109 tem = props;
15110 while (CONSP (tem))
15111 {
15112 oprops = Fplist_put (oprops, XCAR (tem),
15113 XCAR (XCDR (tem)));
15114 tem = XCDR (XCDR (tem));
15115 }
15116 props = oprops;
15117 }
15118
15119 aelt = Fassoc (elt, mode_line_proptrans_alist);
15120 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15121 {
15122 mode_line_proptrans_alist
15123 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15124 elt = XCAR (aelt);
15125 }
15126 else
15127 {
15128 Lisp_Object tem;
15129
15130 elt = Fcopy_sequence (elt);
15131 Fset_text_properties (make_number (0), Flength (elt),
15132 props, elt);
15133 /* Add this item to mode_line_proptrans_alist. */
15134 mode_line_proptrans_alist
15135 = Fcons (Fcons (elt, props),
15136 mode_line_proptrans_alist);
15137 /* Truncate mode_line_proptrans_alist
15138 to at most 50 elements. */
15139 tem = Fnthcdr (make_number (50),
15140 mode_line_proptrans_alist);
15141 if (! NILP (tem))
15142 XSETCDR (tem, Qnil);
15143 }
15144 }
15145 }
15146
15147 this = SDATA (elt);
15148 lisp_string = this;
15149
15150 if (literal)
15151 {
15152 prec = precision - n;
15153 if (frame_title_ptr)
15154 n += store_frame_title (SDATA (elt), -1, prec);
15155 else if (!NILP (mode_line_string_list))
15156 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15157 else
15158 n += display_string (NULL, elt, Qnil, 0, 0, it,
15159 0, prec, 0, STRING_MULTIBYTE (elt));
15160
15161 break;
15162 }
15163
15164 while ((precision <= 0 || n < precision)
15165 && *this
15166 && (frame_title_ptr
15167 || !NILP (mode_line_string_list)
15168 || it->current_x < it->last_visible_x))
15169 {
15170 const unsigned char *last = this;
15171
15172 /* Advance to end of string or next format specifier. */
15173 while ((c = *this++) != '\0' && c != '%')
15174 ;
15175
15176 if (this - 1 != last)
15177 {
15178 /* Output to end of string or up to '%'. Field width
15179 is length of string. Don't output more than
15180 PRECISION allows us. */
15181 --this;
15182
15183 prec = chars_in_text (last, this - last);
15184 if (precision > 0 && prec > precision - n)
15185 prec = precision - n;
15186
15187 if (frame_title_ptr)
15188 n += store_frame_title (last, 0, prec);
15189 else if (!NILP (mode_line_string_list))
15190 {
15191 int bytepos = last - lisp_string;
15192 int charpos = string_byte_to_char (elt, bytepos);
15193 n += store_mode_line_string (NULL,
15194 Fsubstring (elt, make_number (charpos),
15195 make_number (charpos + prec)),
15196 0, 0, 0, Qnil);
15197 }
15198 else
15199 {
15200 int bytepos = last - lisp_string;
15201 int charpos = string_byte_to_char (elt, bytepos);
15202 n += display_string (NULL, elt, Qnil, 0, charpos,
15203 it, 0, prec, 0,
15204 STRING_MULTIBYTE (elt));
15205 }
15206 }
15207 else /* c == '%' */
15208 {
15209 const unsigned char *percent_position = this;
15210
15211 /* Get the specified minimum width. Zero means
15212 don't pad. */
15213 field = 0;
15214 while ((c = *this++) >= '0' && c <= '9')
15215 field = field * 10 + c - '0';
15216
15217 /* Don't pad beyond the total padding allowed. */
15218 if (field_width - n > 0 && field > field_width - n)
15219 field = field_width - n;
15220
15221 /* Note that either PRECISION <= 0 or N < PRECISION. */
15222 prec = precision - n;
15223
15224 if (c == 'M')
15225 n += display_mode_element (it, depth, field, prec,
15226 Vglobal_mode_string, props,
15227 risky);
15228 else if (c != 0)
15229 {
15230 int multibyte;
15231 int bytepos, charpos;
15232 unsigned char *spec;
15233
15234 bytepos = percent_position - lisp_string;
15235 charpos = (STRING_MULTIBYTE (elt)
15236 ? string_byte_to_char (elt, bytepos)
15237 : bytepos);
15238
15239 spec
15240 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15241
15242 if (frame_title_ptr)
15243 n += store_frame_title (spec, field, prec);
15244 else if (!NILP (mode_line_string_list))
15245 {
15246 int len = strlen (spec);
15247 Lisp_Object tem = make_string (spec, len);
15248 props = Ftext_properties_at (make_number (charpos), elt);
15249 /* Should only keep face property in props */
15250 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15251 }
15252 else
15253 {
15254 int nglyphs_before, nwritten;
15255
15256 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15257 nwritten = display_string (spec, Qnil, elt,
15258 charpos, 0, it,
15259 field, prec, 0,
15260 multibyte);
15261
15262 /* Assign to the glyphs written above the
15263 string where the `%x' came from, position
15264 of the `%'. */
15265 if (nwritten > 0)
15266 {
15267 struct glyph *glyph
15268 = (it->glyph_row->glyphs[TEXT_AREA]
15269 + nglyphs_before);
15270 int i;
15271
15272 for (i = 0; i < nwritten; ++i)
15273 {
15274 glyph[i].object = elt;
15275 glyph[i].charpos = charpos;
15276 }
15277
15278 n += nwritten;
15279 }
15280 }
15281 }
15282 else /* c == 0 */
15283 break;
15284 }
15285 }
15286 }
15287 break;
15288
15289 case Lisp_Symbol:
15290 /* A symbol: process the value of the symbol recursively
15291 as if it appeared here directly. Avoid error if symbol void.
15292 Special case: if value of symbol is a string, output the string
15293 literally. */
15294 {
15295 register Lisp_Object tem;
15296
15297 /* If the variable is not marked as risky to set
15298 then its contents are risky to use. */
15299 if (NILP (Fget (elt, Qrisky_local_variable)))
15300 risky = 1;
15301
15302 tem = Fboundp (elt);
15303 if (!NILP (tem))
15304 {
15305 tem = Fsymbol_value (elt);
15306 /* If value is a string, output that string literally:
15307 don't check for % within it. */
15308 if (STRINGP (tem))
15309 literal = 1;
15310
15311 if (!EQ (tem, elt))
15312 {
15313 /* Give up right away for nil or t. */
15314 elt = tem;
15315 goto tail_recurse;
15316 }
15317 }
15318 }
15319 break;
15320
15321 case Lisp_Cons:
15322 {
15323 register Lisp_Object car, tem;
15324
15325 /* A cons cell: five distinct cases.
15326 If first element is :eval or :propertize, do something special.
15327 If first element is a string or a cons, process all the elements
15328 and effectively concatenate them.
15329 If first element is a negative number, truncate displaying cdr to
15330 at most that many characters. If positive, pad (with spaces)
15331 to at least that many characters.
15332 If first element is a symbol, process the cadr or caddr recursively
15333 according to whether the symbol's value is non-nil or nil. */
15334 car = XCAR (elt);
15335 if (EQ (car, QCeval))
15336 {
15337 /* An element of the form (:eval FORM) means evaluate FORM
15338 and use the result as mode line elements. */
15339
15340 if (risky)
15341 break;
15342
15343 if (CONSP (XCDR (elt)))
15344 {
15345 Lisp_Object spec;
15346 spec = safe_eval (XCAR (XCDR (elt)));
15347 n += display_mode_element (it, depth, field_width - n,
15348 precision - n, spec, props,
15349 risky);
15350 }
15351 }
15352 else if (EQ (car, QCpropertize))
15353 {
15354 /* An element of the form (:propertize ELT PROPS...)
15355 means display ELT but applying properties PROPS. */
15356
15357 if (risky)
15358 break;
15359
15360 if (CONSP (XCDR (elt)))
15361 n += display_mode_element (it, depth, field_width - n,
15362 precision - n, XCAR (XCDR (elt)),
15363 XCDR (XCDR (elt)), risky);
15364 }
15365 else if (SYMBOLP (car))
15366 {
15367 tem = Fboundp (car);
15368 elt = XCDR (elt);
15369 if (!CONSP (elt))
15370 goto invalid;
15371 /* elt is now the cdr, and we know it is a cons cell.
15372 Use its car if CAR has a non-nil value. */
15373 if (!NILP (tem))
15374 {
15375 tem = Fsymbol_value (car);
15376 if (!NILP (tem))
15377 {
15378 elt = XCAR (elt);
15379 goto tail_recurse;
15380 }
15381 }
15382 /* Symbol's value is nil (or symbol is unbound)
15383 Get the cddr of the original list
15384 and if possible find the caddr and use that. */
15385 elt = XCDR (elt);
15386 if (NILP (elt))
15387 break;
15388 else if (!CONSP (elt))
15389 goto invalid;
15390 elt = XCAR (elt);
15391 goto tail_recurse;
15392 }
15393 else if (INTEGERP (car))
15394 {
15395 register int lim = XINT (car);
15396 elt = XCDR (elt);
15397 if (lim < 0)
15398 {
15399 /* Negative int means reduce maximum width. */
15400 if (precision <= 0)
15401 precision = -lim;
15402 else
15403 precision = min (precision, -lim);
15404 }
15405 else if (lim > 0)
15406 {
15407 /* Padding specified. Don't let it be more than
15408 current maximum. */
15409 if (precision > 0)
15410 lim = min (precision, lim);
15411
15412 /* If that's more padding than already wanted, queue it.
15413 But don't reduce padding already specified even if
15414 that is beyond the current truncation point. */
15415 field_width = max (lim, field_width);
15416 }
15417 goto tail_recurse;
15418 }
15419 else if (STRINGP (car) || CONSP (car))
15420 {
15421 register int limit = 50;
15422 /* Limit is to protect against circular lists. */
15423 while (CONSP (elt)
15424 && --limit > 0
15425 && (precision <= 0 || n < precision))
15426 {
15427 n += display_mode_element (it, depth, field_width - n,
15428 precision - n, XCAR (elt),
15429 props, risky);
15430 elt = XCDR (elt);
15431 }
15432 }
15433 }
15434 break;
15435
15436 default:
15437 invalid:
15438 elt = build_string ("*invalid*");
15439 goto tail_recurse;
15440 }
15441
15442 /* Pad to FIELD_WIDTH. */
15443 if (field_width > 0 && n < field_width)
15444 {
15445 if (frame_title_ptr)
15446 n += store_frame_title ("", field_width - n, 0);
15447 else if (!NILP (mode_line_string_list))
15448 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15449 else
15450 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15451 0, 0, 0);
15452 }
15453
15454 return n;
15455 }
15456
15457 /* Store a mode-line string element in mode_line_string_list.
15458
15459 If STRING is non-null, display that C string. Otherwise, the Lisp
15460 string LISP_STRING is displayed.
15461
15462 FIELD_WIDTH is the minimum number of output glyphs to produce.
15463 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15464 with spaces. FIELD_WIDTH <= 0 means don't pad.
15465
15466 PRECISION is the maximum number of characters to output from
15467 STRING. PRECISION <= 0 means don't truncate the string.
15468
15469 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15470 properties to the string.
15471
15472 PROPS are the properties to add to the string.
15473 The mode_line_string_face face property is always added to the string.
15474 */
15475
15476 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15477 char *string;
15478 Lisp_Object lisp_string;
15479 int copy_string;
15480 int field_width;
15481 int precision;
15482 Lisp_Object props;
15483 {
15484 int len;
15485 int n = 0;
15486
15487 if (string != NULL)
15488 {
15489 len = strlen (string);
15490 if (precision > 0 && len > precision)
15491 len = precision;
15492 lisp_string = make_string (string, len);
15493 if (NILP (props))
15494 props = mode_line_string_face_prop;
15495 else if (!NILP (mode_line_string_face))
15496 {
15497 Lisp_Object face = Fplist_get (props, Qface);
15498 props = Fcopy_sequence (props);
15499 if (NILP (face))
15500 face = mode_line_string_face;
15501 else
15502 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15503 props = Fplist_put (props, Qface, face);
15504 }
15505 Fadd_text_properties (make_number (0), make_number (len),
15506 props, lisp_string);
15507 }
15508 else
15509 {
15510 len = XFASTINT (Flength (lisp_string));
15511 if (precision > 0 && len > precision)
15512 {
15513 len = precision;
15514 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15515 precision = -1;
15516 }
15517 if (!NILP (mode_line_string_face))
15518 {
15519 Lisp_Object face;
15520 if (NILP (props))
15521 props = Ftext_properties_at (make_number (0), lisp_string);
15522 face = Fplist_get (props, Qface);
15523 if (NILP (face))
15524 face = mode_line_string_face;
15525 else
15526 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15527 props = Fcons (Qface, Fcons (face, Qnil));
15528 if (copy_string)
15529 lisp_string = Fcopy_sequence (lisp_string);
15530 }
15531 if (!NILP (props))
15532 Fadd_text_properties (make_number (0), make_number (len),
15533 props, lisp_string);
15534 }
15535
15536 if (len > 0)
15537 {
15538 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15539 n += len;
15540 }
15541
15542 if (field_width > len)
15543 {
15544 field_width -= len;
15545 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15546 if (!NILP (props))
15547 Fadd_text_properties (make_number (0), make_number (field_width),
15548 props, lisp_string);
15549 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15550 n += field_width;
15551 }
15552
15553 return n;
15554 }
15555
15556
15557 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15558 0, 3, 0,
15559 doc: /* Return the mode-line of selected window as a string.
15560 First optional arg FORMAT specifies a different format string (see
15561 `mode-line-format' for details) to use. If FORMAT is t, return
15562 the buffer's header-line. Second optional arg WINDOW specifies a
15563 different window to use as the context for the formatting.
15564 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15565 (format, window, no_props)
15566 Lisp_Object format, window, no_props;
15567 {
15568 struct it it;
15569 int len;
15570 struct window *w;
15571 struct buffer *old_buffer = NULL;
15572 enum face_id face_id = DEFAULT_FACE_ID;
15573
15574 if (NILP (window))
15575 window = selected_window;
15576 CHECK_WINDOW (window);
15577 w = XWINDOW (window);
15578 CHECK_BUFFER (w->buffer);
15579
15580 if (XBUFFER (w->buffer) != current_buffer)
15581 {
15582 old_buffer = current_buffer;
15583 set_buffer_internal_1 (XBUFFER (w->buffer));
15584 }
15585
15586 if (NILP (format) || EQ (format, Qt))
15587 {
15588 face_id = NILP (format)
15589 ? CURRENT_MODE_LINE_FACE_ID (w) :
15590 HEADER_LINE_FACE_ID;
15591 format = NILP (format)
15592 ? current_buffer->mode_line_format
15593 : current_buffer->header_line_format;
15594 }
15595
15596 init_iterator (&it, w, -1, -1, NULL, face_id);
15597
15598 if (NILP (no_props))
15599 {
15600 mode_line_string_face =
15601 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15602 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15603 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15604
15605 mode_line_string_face_prop =
15606 NILP (mode_line_string_face) ? Qnil :
15607 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15608
15609 /* We need a dummy last element in mode_line_string_list to
15610 indicate we are building the propertized mode-line string.
15611 Using mode_line_string_face_prop here GC protects it. */
15612 mode_line_string_list =
15613 Fcons (mode_line_string_face_prop, Qnil);
15614 frame_title_ptr = NULL;
15615 }
15616 else
15617 {
15618 mode_line_string_face_prop = Qnil;
15619 mode_line_string_list = Qnil;
15620 frame_title_ptr = frame_title_buf;
15621 }
15622
15623 push_frame_kboard (it.f);
15624 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15625 pop_frame_kboard ();
15626
15627 if (old_buffer)
15628 set_buffer_internal_1 (old_buffer);
15629
15630 if (NILP (no_props))
15631 {
15632 Lisp_Object str;
15633 mode_line_string_list = Fnreverse (mode_line_string_list);
15634 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15635 make_string ("", 0));
15636 mode_line_string_face_prop = Qnil;
15637 mode_line_string_list = Qnil;
15638 return str;
15639 }
15640
15641 len = frame_title_ptr - frame_title_buf;
15642 if (len > 0 && frame_title_ptr[-1] == '-')
15643 {
15644 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15645 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15646 ;
15647 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15648 if (len > frame_title_ptr - frame_title_buf)
15649 len = frame_title_ptr - frame_title_buf;
15650 }
15651
15652 frame_title_ptr = NULL;
15653 return make_string (frame_title_buf, len);
15654 }
15655
15656 /* Write a null-terminated, right justified decimal representation of
15657 the positive integer D to BUF using a minimal field width WIDTH. */
15658
15659 static void
15660 pint2str (buf, width, d)
15661 register char *buf;
15662 register int width;
15663 register int d;
15664 {
15665 register char *p = buf;
15666
15667 if (d <= 0)
15668 *p++ = '0';
15669 else
15670 {
15671 while (d > 0)
15672 {
15673 *p++ = d % 10 + '0';
15674 d /= 10;
15675 }
15676 }
15677
15678 for (width -= (int) (p - buf); width > 0; --width)
15679 *p++ = ' ';
15680 *p-- = '\0';
15681 while (p > buf)
15682 {
15683 d = *buf;
15684 *buf++ = *p;
15685 *p-- = d;
15686 }
15687 }
15688
15689 /* Write a null-terminated, right justified decimal and "human
15690 readable" representation of the nonnegative integer D to BUF using
15691 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15692
15693 static const char power_letter[] =
15694 {
15695 0, /* not used */
15696 'k', /* kilo */
15697 'M', /* mega */
15698 'G', /* giga */
15699 'T', /* tera */
15700 'P', /* peta */
15701 'E', /* exa */
15702 'Z', /* zetta */
15703 'Y' /* yotta */
15704 };
15705
15706 static void
15707 pint2hrstr (buf, width, d)
15708 char *buf;
15709 int width;
15710 int d;
15711 {
15712 /* We aim to represent the nonnegative integer D as
15713 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15714 int quotient = d;
15715 int remainder = 0;
15716 /* -1 means: do not use TENTHS. */
15717 int tenths = -1;
15718 int exponent = 0;
15719
15720 /* Length of QUOTIENT.TENTHS as a string. */
15721 int length;
15722
15723 char * psuffix;
15724 char * p;
15725
15726 if (1000 <= quotient)
15727 {
15728 /* Scale to the appropriate EXPONENT. */
15729 do
15730 {
15731 remainder = quotient % 1000;
15732 quotient /= 1000;
15733 exponent++;
15734 }
15735 while (1000 <= quotient);
15736
15737 /* Round to nearest and decide whether to use TENTHS or not. */
15738 if (quotient <= 9)
15739 {
15740 tenths = remainder / 100;
15741 if (50 <= remainder % 100)
15742 if (tenths < 9)
15743 tenths++;
15744 else
15745 {
15746 quotient++;
15747 if (quotient == 10)
15748 tenths = -1;
15749 else
15750 tenths = 0;
15751 }
15752 }
15753 else
15754 if (500 <= remainder)
15755 if (quotient < 999)
15756 quotient++;
15757 else
15758 {
15759 quotient = 1;
15760 exponent++;
15761 tenths = 0;
15762 }
15763 }
15764
15765 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15766 if (tenths == -1 && quotient <= 99)
15767 if (quotient <= 9)
15768 length = 1;
15769 else
15770 length = 2;
15771 else
15772 length = 3;
15773 p = psuffix = buf + max (width, length);
15774
15775 /* Print EXPONENT. */
15776 if (exponent)
15777 *psuffix++ = power_letter[exponent];
15778 *psuffix = '\0';
15779
15780 /* Print TENTHS. */
15781 if (tenths >= 0)
15782 {
15783 *--p = '0' + tenths;
15784 *--p = '.';
15785 }
15786
15787 /* Print QUOTIENT. */
15788 do
15789 {
15790 int digit = quotient % 10;
15791 *--p = '0' + digit;
15792 }
15793 while ((quotient /= 10) != 0);
15794
15795 /* Print leading spaces. */
15796 while (buf < p)
15797 *--p = ' ';
15798 }
15799
15800 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15801 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15802 type of CODING_SYSTEM. Return updated pointer into BUF. */
15803
15804 static unsigned char invalid_eol_type[] = "(*invalid*)";
15805
15806 static char *
15807 decode_mode_spec_coding (coding_system, buf, eol_flag)
15808 Lisp_Object coding_system;
15809 register char *buf;
15810 int eol_flag;
15811 {
15812 Lisp_Object val;
15813 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15814 const unsigned char *eol_str;
15815 int eol_str_len;
15816 /* The EOL conversion we are using. */
15817 Lisp_Object eoltype;
15818
15819 val = Fget (coding_system, Qcoding_system);
15820 eoltype = Qnil;
15821
15822 if (!VECTORP (val)) /* Not yet decided. */
15823 {
15824 if (multibyte)
15825 *buf++ = '-';
15826 if (eol_flag)
15827 eoltype = eol_mnemonic_undecided;
15828 /* Don't mention EOL conversion if it isn't decided. */
15829 }
15830 else
15831 {
15832 Lisp_Object eolvalue;
15833
15834 eolvalue = Fget (coding_system, Qeol_type);
15835
15836 if (multibyte)
15837 *buf++ = XFASTINT (AREF (val, 1));
15838
15839 if (eol_flag)
15840 {
15841 /* The EOL conversion that is normal on this system. */
15842
15843 if (NILP (eolvalue)) /* Not yet decided. */
15844 eoltype = eol_mnemonic_undecided;
15845 else if (VECTORP (eolvalue)) /* Not yet decided. */
15846 eoltype = eol_mnemonic_undecided;
15847 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15848 eoltype = (XFASTINT (eolvalue) == 0
15849 ? eol_mnemonic_unix
15850 : (XFASTINT (eolvalue) == 1
15851 ? eol_mnemonic_dos : eol_mnemonic_mac));
15852 }
15853 }
15854
15855 if (eol_flag)
15856 {
15857 /* Mention the EOL conversion if it is not the usual one. */
15858 if (STRINGP (eoltype))
15859 {
15860 eol_str = SDATA (eoltype);
15861 eol_str_len = SBYTES (eoltype);
15862 }
15863 else if (INTEGERP (eoltype)
15864 && CHAR_VALID_P (XINT (eoltype), 0))
15865 {
15866 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
15867 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
15868 eol_str = tmp;
15869 }
15870 else
15871 {
15872 eol_str = invalid_eol_type;
15873 eol_str_len = sizeof (invalid_eol_type) - 1;
15874 }
15875 bcopy (eol_str, buf, eol_str_len);
15876 buf += eol_str_len;
15877 }
15878
15879 return buf;
15880 }
15881
15882 /* Return a string for the output of a mode line %-spec for window W,
15883 generated by character C. PRECISION >= 0 means don't return a
15884 string longer than that value. FIELD_WIDTH > 0 means pad the
15885 string returned with spaces to that value. Return 1 in *MULTIBYTE
15886 if the result is multibyte text. */
15887
15888 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15889
15890 static char *
15891 decode_mode_spec (w, c, field_width, precision, multibyte)
15892 struct window *w;
15893 register int c;
15894 int field_width, precision;
15895 int *multibyte;
15896 {
15897 Lisp_Object obj;
15898 struct frame *f = XFRAME (WINDOW_FRAME (w));
15899 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
15900 struct buffer *b = XBUFFER (w->buffer);
15901
15902 obj = Qnil;
15903 *multibyte = 0;
15904
15905 switch (c)
15906 {
15907 case '*':
15908 if (!NILP (b->read_only))
15909 return "%";
15910 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15911 return "*";
15912 return "-";
15913
15914 case '+':
15915 /* This differs from %* only for a modified read-only buffer. */
15916 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15917 return "*";
15918 if (!NILP (b->read_only))
15919 return "%";
15920 return "-";
15921
15922 case '&':
15923 /* This differs from %* in ignoring read-only-ness. */
15924 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15925 return "*";
15926 return "-";
15927
15928 case '%':
15929 return "%";
15930
15931 case '[':
15932 {
15933 int i;
15934 char *p;
15935
15936 if (command_loop_level > 5)
15937 return "[[[... ";
15938 p = decode_mode_spec_buf;
15939 for (i = 0; i < command_loop_level; i++)
15940 *p++ = '[';
15941 *p = 0;
15942 return decode_mode_spec_buf;
15943 }
15944
15945 case ']':
15946 {
15947 int i;
15948 char *p;
15949
15950 if (command_loop_level > 5)
15951 return " ...]]]";
15952 p = decode_mode_spec_buf;
15953 for (i = 0; i < command_loop_level; i++)
15954 *p++ = ']';
15955 *p = 0;
15956 return decode_mode_spec_buf;
15957 }
15958
15959 case '-':
15960 {
15961 register int i;
15962
15963 /* Let lots_of_dashes be a string of infinite length. */
15964 if (!NILP (mode_line_string_list))
15965 return "--";
15966 if (field_width <= 0
15967 || field_width > sizeof (lots_of_dashes))
15968 {
15969 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
15970 decode_mode_spec_buf[i] = '-';
15971 decode_mode_spec_buf[i] = '\0';
15972 return decode_mode_spec_buf;
15973 }
15974 else
15975 return lots_of_dashes;
15976 }
15977
15978 case 'b':
15979 obj = b->name;
15980 break;
15981
15982 case 'c':
15983 {
15984 int col = (int) current_column (); /* iftc */
15985 w->column_number_displayed = make_number (col);
15986 pint2str (decode_mode_spec_buf, field_width, col);
15987 return decode_mode_spec_buf;
15988 }
15989
15990 case 'F':
15991 /* %F displays the frame name. */
15992 if (!NILP (f->title))
15993 return (char *) SDATA (f->title);
15994 if (f->explicit_name || ! FRAME_WINDOW_P (f))
15995 return (char *) SDATA (f->name);
15996 return "Emacs";
15997
15998 case 'f':
15999 obj = b->filename;
16000 break;
16001
16002 case 'i':
16003 {
16004 int size = ZV - BEGV;
16005 pint2str (decode_mode_spec_buf, field_width, size);
16006 return decode_mode_spec_buf;
16007 }
16008
16009 case 'I':
16010 {
16011 int size = ZV - BEGV;
16012 pint2hrstr (decode_mode_spec_buf, field_width, size);
16013 return decode_mode_spec_buf;
16014 }
16015
16016 case 'l':
16017 {
16018 int startpos = XMARKER (w->start)->charpos;
16019 int startpos_byte = marker_byte_position (w->start);
16020 int line, linepos, linepos_byte, topline;
16021 int nlines, junk;
16022 int height = WINDOW_TOTAL_LINES (w);
16023
16024 /* If we decided that this buffer isn't suitable for line numbers,
16025 don't forget that too fast. */
16026 if (EQ (w->base_line_pos, w->buffer))
16027 goto no_value;
16028 /* But do forget it, if the window shows a different buffer now. */
16029 else if (BUFFERP (w->base_line_pos))
16030 w->base_line_pos = Qnil;
16031
16032 /* If the buffer is very big, don't waste time. */
16033 if (INTEGERP (Vline_number_display_limit)
16034 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16035 {
16036 w->base_line_pos = Qnil;
16037 w->base_line_number = Qnil;
16038 goto no_value;
16039 }
16040
16041 if (!NILP (w->base_line_number)
16042 && !NILP (w->base_line_pos)
16043 && XFASTINT (w->base_line_pos) <= startpos)
16044 {
16045 line = XFASTINT (w->base_line_number);
16046 linepos = XFASTINT (w->base_line_pos);
16047 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16048 }
16049 else
16050 {
16051 line = 1;
16052 linepos = BUF_BEGV (b);
16053 linepos_byte = BUF_BEGV_BYTE (b);
16054 }
16055
16056 /* Count lines from base line to window start position. */
16057 nlines = display_count_lines (linepos, linepos_byte,
16058 startpos_byte,
16059 startpos, &junk);
16060
16061 topline = nlines + line;
16062
16063 /* Determine a new base line, if the old one is too close
16064 or too far away, or if we did not have one.
16065 "Too close" means it's plausible a scroll-down would
16066 go back past it. */
16067 if (startpos == BUF_BEGV (b))
16068 {
16069 w->base_line_number = make_number (topline);
16070 w->base_line_pos = make_number (BUF_BEGV (b));
16071 }
16072 else if (nlines < height + 25 || nlines > height * 3 + 50
16073 || linepos == BUF_BEGV (b))
16074 {
16075 int limit = BUF_BEGV (b);
16076 int limit_byte = BUF_BEGV_BYTE (b);
16077 int position;
16078 int distance = (height * 2 + 30) * line_number_display_limit_width;
16079
16080 if (startpos - distance > limit)
16081 {
16082 limit = startpos - distance;
16083 limit_byte = CHAR_TO_BYTE (limit);
16084 }
16085
16086 nlines = display_count_lines (startpos, startpos_byte,
16087 limit_byte,
16088 - (height * 2 + 30),
16089 &position);
16090 /* If we couldn't find the lines we wanted within
16091 line_number_display_limit_width chars per line,
16092 give up on line numbers for this window. */
16093 if (position == limit_byte && limit == startpos - distance)
16094 {
16095 w->base_line_pos = w->buffer;
16096 w->base_line_number = Qnil;
16097 goto no_value;
16098 }
16099
16100 w->base_line_number = make_number (topline - nlines);
16101 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16102 }
16103
16104 /* Now count lines from the start pos to point. */
16105 nlines = display_count_lines (startpos, startpos_byte,
16106 PT_BYTE, PT, &junk);
16107
16108 /* Record that we did display the line number. */
16109 line_number_displayed = 1;
16110
16111 /* Make the string to show. */
16112 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16113 return decode_mode_spec_buf;
16114 no_value:
16115 {
16116 char* p = decode_mode_spec_buf;
16117 int pad = field_width - 2;
16118 while (pad-- > 0)
16119 *p++ = ' ';
16120 *p++ = '?';
16121 *p++ = '?';
16122 *p = '\0';
16123 return decode_mode_spec_buf;
16124 }
16125 }
16126 break;
16127
16128 case 'm':
16129 obj = b->mode_name;
16130 break;
16131
16132 case 'n':
16133 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16134 return " Narrow";
16135 break;
16136
16137 case 'p':
16138 {
16139 int pos = marker_position (w->start);
16140 int total = BUF_ZV (b) - BUF_BEGV (b);
16141
16142 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16143 {
16144 if (pos <= BUF_BEGV (b))
16145 return "All";
16146 else
16147 return "Bottom";
16148 }
16149 else if (pos <= BUF_BEGV (b))
16150 return "Top";
16151 else
16152 {
16153 if (total > 1000000)
16154 /* Do it differently for a large value, to avoid overflow. */
16155 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16156 else
16157 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16158 /* We can't normally display a 3-digit number,
16159 so get us a 2-digit number that is close. */
16160 if (total == 100)
16161 total = 99;
16162 sprintf (decode_mode_spec_buf, "%2d%%", total);
16163 return decode_mode_spec_buf;
16164 }
16165 }
16166
16167 /* Display percentage of size above the bottom of the screen. */
16168 case 'P':
16169 {
16170 int toppos = marker_position (w->start);
16171 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16172 int total = BUF_ZV (b) - BUF_BEGV (b);
16173
16174 if (botpos >= BUF_ZV (b))
16175 {
16176 if (toppos <= BUF_BEGV (b))
16177 return "All";
16178 else
16179 return "Bottom";
16180 }
16181 else
16182 {
16183 if (total > 1000000)
16184 /* Do it differently for a large value, to avoid overflow. */
16185 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16186 else
16187 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16188 /* We can't normally display a 3-digit number,
16189 so get us a 2-digit number that is close. */
16190 if (total == 100)
16191 total = 99;
16192 if (toppos <= BUF_BEGV (b))
16193 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16194 else
16195 sprintf (decode_mode_spec_buf, "%2d%%", total);
16196 return decode_mode_spec_buf;
16197 }
16198 }
16199
16200 case 's':
16201 /* status of process */
16202 obj = Fget_buffer_process (w->buffer);
16203 if (NILP (obj))
16204 return "no process";
16205 #ifdef subprocesses
16206 obj = Fsymbol_name (Fprocess_status (obj));
16207 #endif
16208 break;
16209
16210 case 't': /* indicate TEXT or BINARY */
16211 #ifdef MODE_LINE_BINARY_TEXT
16212 return MODE_LINE_BINARY_TEXT (b);
16213 #else
16214 return "T";
16215 #endif
16216
16217 case 'z':
16218 /* coding-system (not including end-of-line format) */
16219 case 'Z':
16220 /* coding-system (including end-of-line type) */
16221 {
16222 int eol_flag = (c == 'Z');
16223 char *p = decode_mode_spec_buf;
16224
16225 if (! FRAME_WINDOW_P (f))
16226 {
16227 /* No need to mention EOL here--the terminal never needs
16228 to do EOL conversion. */
16229 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16230 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16231 }
16232 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16233 p, eol_flag);
16234
16235 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16236 #ifdef subprocesses
16237 obj = Fget_buffer_process (Fcurrent_buffer ());
16238 if (PROCESSP (obj))
16239 {
16240 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16241 p, eol_flag);
16242 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16243 p, eol_flag);
16244 }
16245 #endif /* subprocesses */
16246 #endif /* 0 */
16247 *p = 0;
16248 return decode_mode_spec_buf;
16249 }
16250 }
16251
16252 if (STRINGP (obj))
16253 {
16254 *multibyte = STRING_MULTIBYTE (obj);
16255 return (char *) SDATA (obj);
16256 }
16257 else
16258 return "";
16259 }
16260
16261
16262 /* Count up to COUNT lines starting from START / START_BYTE.
16263 But don't go beyond LIMIT_BYTE.
16264 Return the number of lines thus found (always nonnegative).
16265
16266 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16267
16268 static int
16269 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16270 int start, start_byte, limit_byte, count;
16271 int *byte_pos_ptr;
16272 {
16273 register unsigned char *cursor;
16274 unsigned char *base;
16275
16276 register int ceiling;
16277 register unsigned char *ceiling_addr;
16278 int orig_count = count;
16279
16280 /* If we are not in selective display mode,
16281 check only for newlines. */
16282 int selective_display = (!NILP (current_buffer->selective_display)
16283 && !INTEGERP (current_buffer->selective_display));
16284
16285 if (count > 0)
16286 {
16287 while (start_byte < limit_byte)
16288 {
16289 ceiling = BUFFER_CEILING_OF (start_byte);
16290 ceiling = min (limit_byte - 1, ceiling);
16291 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16292 base = (cursor = BYTE_POS_ADDR (start_byte));
16293 while (1)
16294 {
16295 if (selective_display)
16296 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16297 ;
16298 else
16299 while (*cursor != '\n' && ++cursor != ceiling_addr)
16300 ;
16301
16302 if (cursor != ceiling_addr)
16303 {
16304 if (--count == 0)
16305 {
16306 start_byte += cursor - base + 1;
16307 *byte_pos_ptr = start_byte;
16308 return orig_count;
16309 }
16310 else
16311 if (++cursor == ceiling_addr)
16312 break;
16313 }
16314 else
16315 break;
16316 }
16317 start_byte += cursor - base;
16318 }
16319 }
16320 else
16321 {
16322 while (start_byte > limit_byte)
16323 {
16324 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16325 ceiling = max (limit_byte, ceiling);
16326 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16327 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16328 while (1)
16329 {
16330 if (selective_display)
16331 while (--cursor != ceiling_addr
16332 && *cursor != '\n' && *cursor != 015)
16333 ;
16334 else
16335 while (--cursor != ceiling_addr && *cursor != '\n')
16336 ;
16337
16338 if (cursor != ceiling_addr)
16339 {
16340 if (++count == 0)
16341 {
16342 start_byte += cursor - base + 1;
16343 *byte_pos_ptr = start_byte;
16344 /* When scanning backwards, we should
16345 not count the newline posterior to which we stop. */
16346 return - orig_count - 1;
16347 }
16348 }
16349 else
16350 break;
16351 }
16352 /* Here we add 1 to compensate for the last decrement
16353 of CURSOR, which took it past the valid range. */
16354 start_byte += cursor - base + 1;
16355 }
16356 }
16357
16358 *byte_pos_ptr = limit_byte;
16359
16360 if (count < 0)
16361 return - orig_count + count;
16362 return orig_count - count;
16363
16364 }
16365
16366
16367 \f
16368 /***********************************************************************
16369 Displaying strings
16370 ***********************************************************************/
16371
16372 /* Display a NUL-terminated string, starting with index START.
16373
16374 If STRING is non-null, display that C string. Otherwise, the Lisp
16375 string LISP_STRING is displayed.
16376
16377 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16378 FACE_STRING. Display STRING or LISP_STRING with the face at
16379 FACE_STRING_POS in FACE_STRING:
16380
16381 Display the string in the environment given by IT, but use the
16382 standard display table, temporarily.
16383
16384 FIELD_WIDTH is the minimum number of output glyphs to produce.
16385 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16386 with spaces. If STRING has more characters, more than FIELD_WIDTH
16387 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16388
16389 PRECISION is the maximum number of characters to output from
16390 STRING. PRECISION < 0 means don't truncate the string.
16391
16392 This is roughly equivalent to printf format specifiers:
16393
16394 FIELD_WIDTH PRECISION PRINTF
16395 ----------------------------------------
16396 -1 -1 %s
16397 -1 10 %.10s
16398 10 -1 %10s
16399 20 10 %20.10s
16400
16401 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16402 display them, and < 0 means obey the current buffer's value of
16403 enable_multibyte_characters.
16404
16405 Value is the number of glyphs produced. */
16406
16407 static int
16408 display_string (string, lisp_string, face_string, face_string_pos,
16409 start, it, field_width, precision, max_x, multibyte)
16410 unsigned char *string;
16411 Lisp_Object lisp_string;
16412 Lisp_Object face_string;
16413 int face_string_pos;
16414 int start;
16415 struct it *it;
16416 int field_width, precision, max_x;
16417 int multibyte;
16418 {
16419 int hpos_at_start = it->hpos;
16420 int saved_face_id = it->face_id;
16421 struct glyph_row *row = it->glyph_row;
16422
16423 /* Initialize the iterator IT for iteration over STRING beginning
16424 with index START. */
16425 reseat_to_string (it, string, lisp_string, start,
16426 precision, field_width, multibyte);
16427
16428 /* If displaying STRING, set up the face of the iterator
16429 from LISP_STRING, if that's given. */
16430 if (STRINGP (face_string))
16431 {
16432 int endptr;
16433 struct face *face;
16434
16435 it->face_id
16436 = face_at_string_position (it->w, face_string, face_string_pos,
16437 0, it->region_beg_charpos,
16438 it->region_end_charpos,
16439 &endptr, it->base_face_id, 0);
16440 face = FACE_FROM_ID (it->f, it->face_id);
16441 it->face_box_p = face->box != FACE_NO_BOX;
16442 }
16443
16444 /* Set max_x to the maximum allowed X position. Don't let it go
16445 beyond the right edge of the window. */
16446 if (max_x <= 0)
16447 max_x = it->last_visible_x;
16448 else
16449 max_x = min (max_x, it->last_visible_x);
16450
16451 /* Skip over display elements that are not visible. because IT->w is
16452 hscrolled. */
16453 if (it->current_x < it->first_visible_x)
16454 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16455 MOVE_TO_POS | MOVE_TO_X);
16456
16457 row->ascent = it->max_ascent;
16458 row->height = it->max_ascent + it->max_descent;
16459 row->phys_ascent = it->max_phys_ascent;
16460 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16461
16462 /* This condition is for the case that we are called with current_x
16463 past last_visible_x. */
16464 while (it->current_x < max_x)
16465 {
16466 int x_before, x, n_glyphs_before, i, nglyphs;
16467
16468 /* Get the next display element. */
16469 if (!get_next_display_element (it))
16470 break;
16471
16472 /* Produce glyphs. */
16473 x_before = it->current_x;
16474 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16475 PRODUCE_GLYPHS (it);
16476
16477 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16478 i = 0;
16479 x = x_before;
16480 while (i < nglyphs)
16481 {
16482 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16483
16484 if (!it->truncate_lines_p
16485 && x + glyph->pixel_width > max_x)
16486 {
16487 /* End of continued line or max_x reached. */
16488 if (CHAR_GLYPH_PADDING_P (*glyph))
16489 {
16490 /* A wide character is unbreakable. */
16491 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16492 it->current_x = x_before;
16493 }
16494 else
16495 {
16496 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16497 it->current_x = x;
16498 }
16499 break;
16500 }
16501 else if (x + glyph->pixel_width > it->first_visible_x)
16502 {
16503 /* Glyph is at least partially visible. */
16504 ++it->hpos;
16505 if (x < it->first_visible_x)
16506 it->glyph_row->x = x - it->first_visible_x;
16507 }
16508 else
16509 {
16510 /* Glyph is off the left margin of the display area.
16511 Should not happen. */
16512 abort ();
16513 }
16514
16515 row->ascent = max (row->ascent, it->max_ascent);
16516 row->height = max (row->height, it->max_ascent + it->max_descent);
16517 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16518 row->phys_height = max (row->phys_height,
16519 it->max_phys_ascent + it->max_phys_descent);
16520 x += glyph->pixel_width;
16521 ++i;
16522 }
16523
16524 /* Stop if max_x reached. */
16525 if (i < nglyphs)
16526 break;
16527
16528 /* Stop at line ends. */
16529 if (ITERATOR_AT_END_OF_LINE_P (it))
16530 {
16531 it->continuation_lines_width = 0;
16532 break;
16533 }
16534
16535 set_iterator_to_next (it, 1);
16536
16537 /* Stop if truncating at the right edge. */
16538 if (it->truncate_lines_p
16539 && it->current_x >= it->last_visible_x)
16540 {
16541 /* Add truncation mark, but don't do it if the line is
16542 truncated at a padding space. */
16543 if (IT_CHARPOS (*it) < it->string_nchars)
16544 {
16545 if (!FRAME_WINDOW_P (it->f))
16546 {
16547 int i, n;
16548
16549 if (it->current_x > it->last_visible_x)
16550 {
16551 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16552 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16553 break;
16554 for (n = row->used[TEXT_AREA]; i < n; ++i)
16555 {
16556 row->used[TEXT_AREA] = i;
16557 produce_special_glyphs (it, IT_TRUNCATION);
16558 }
16559 }
16560 produce_special_glyphs (it, IT_TRUNCATION);
16561 }
16562 it->glyph_row->truncated_on_right_p = 1;
16563 }
16564 break;
16565 }
16566 }
16567
16568 /* Maybe insert a truncation at the left. */
16569 if (it->first_visible_x
16570 && IT_CHARPOS (*it) > 0)
16571 {
16572 if (!FRAME_WINDOW_P (it->f))
16573 insert_left_trunc_glyphs (it);
16574 it->glyph_row->truncated_on_left_p = 1;
16575 }
16576
16577 it->face_id = saved_face_id;
16578
16579 /* Value is number of columns displayed. */
16580 return it->hpos - hpos_at_start;
16581 }
16582
16583
16584 \f
16585 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16586 appears as an element of LIST or as the car of an element of LIST.
16587 If PROPVAL is a list, compare each element against LIST in that
16588 way, and return 1/2 if any element of PROPVAL is found in LIST.
16589 Otherwise return 0. This function cannot quit.
16590 The return value is 2 if the text is invisible but with an ellipsis
16591 and 1 if it's invisible and without an ellipsis. */
16592
16593 int
16594 invisible_p (propval, list)
16595 register Lisp_Object propval;
16596 Lisp_Object list;
16597 {
16598 register Lisp_Object tail, proptail;
16599
16600 for (tail = list; CONSP (tail); tail = XCDR (tail))
16601 {
16602 register Lisp_Object tem;
16603 tem = XCAR (tail);
16604 if (EQ (propval, tem))
16605 return 1;
16606 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16607 return NILP (XCDR (tem)) ? 1 : 2;
16608 }
16609
16610 if (CONSP (propval))
16611 {
16612 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16613 {
16614 Lisp_Object propelt;
16615 propelt = XCAR (proptail);
16616 for (tail = list; CONSP (tail); tail = XCDR (tail))
16617 {
16618 register Lisp_Object tem;
16619 tem = XCAR (tail);
16620 if (EQ (propelt, tem))
16621 return 1;
16622 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16623 return NILP (XCDR (tem)) ? 1 : 2;
16624 }
16625 }
16626 }
16627
16628 return 0;
16629 }
16630
16631 \f
16632 /***********************************************************************
16633 Glyph Display
16634 ***********************************************************************/
16635
16636 #ifdef HAVE_WINDOW_SYSTEM
16637
16638 #if GLYPH_DEBUG
16639
16640 void
16641 dump_glyph_string (s)
16642 struct glyph_string *s;
16643 {
16644 fprintf (stderr, "glyph string\n");
16645 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
16646 s->x, s->y, s->width, s->height);
16647 fprintf (stderr, " ybase = %d\n", s->ybase);
16648 fprintf (stderr, " hl = %d\n", s->hl);
16649 fprintf (stderr, " left overhang = %d, right = %d\n",
16650 s->left_overhang, s->right_overhang);
16651 fprintf (stderr, " nchars = %d\n", s->nchars);
16652 fprintf (stderr, " extends to end of line = %d\n",
16653 s->extends_to_end_of_line_p);
16654 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
16655 fprintf (stderr, " bg width = %d\n", s->background_width);
16656 }
16657
16658 #endif /* GLYPH_DEBUG */
16659
16660 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16661 of XChar2b structures for S; it can't be allocated in
16662 init_glyph_string because it must be allocated via `alloca'. W
16663 is the window on which S is drawn. ROW and AREA are the glyph row
16664 and area within the row from which S is constructed. START is the
16665 index of the first glyph structure covered by S. HL is a
16666 face-override for drawing S. */
16667
16668 #ifdef HAVE_NTGUI
16669 #define OPTIONAL_HDC(hdc) hdc,
16670 #define DECLARE_HDC(hdc) HDC hdc;
16671 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16672 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
16673 #endif
16674
16675 #ifndef OPTIONAL_HDC
16676 #define OPTIONAL_HDC(hdc)
16677 #define DECLARE_HDC(hdc)
16678 #define ALLOCATE_HDC(hdc, f)
16679 #define RELEASE_HDC(hdc, f)
16680 #endif
16681
16682 static void
16683 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
16684 struct glyph_string *s;
16685 DECLARE_HDC (hdc)
16686 XChar2b *char2b;
16687 struct window *w;
16688 struct glyph_row *row;
16689 enum glyph_row_area area;
16690 int start;
16691 enum draw_glyphs_face hl;
16692 {
16693 bzero (s, sizeof *s);
16694 s->w = w;
16695 s->f = XFRAME (w->frame);
16696 #ifdef HAVE_NTGUI
16697 s->hdc = hdc;
16698 #endif
16699 s->display = FRAME_X_DISPLAY (s->f);
16700 s->window = FRAME_X_WINDOW (s->f);
16701 s->char2b = char2b;
16702 s->hl = hl;
16703 s->row = row;
16704 s->area = area;
16705 s->first_glyph = row->glyphs[area] + start;
16706 s->height = row->height;
16707 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
16708
16709 /* Display the internal border below the tool-bar window. */
16710 if (s->w == XWINDOW (s->f->tool_bar_window))
16711 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
16712
16713 s->ybase = s->y + row->ascent;
16714 }
16715
16716
16717 /* Append the list of glyph strings with head H and tail T to the list
16718 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
16719
16720 static INLINE void
16721 append_glyph_string_lists (head, tail, h, t)
16722 struct glyph_string **head, **tail;
16723 struct glyph_string *h, *t;
16724 {
16725 if (h)
16726 {
16727 if (*head)
16728 (*tail)->next = h;
16729 else
16730 *head = h;
16731 h->prev = *tail;
16732 *tail = t;
16733 }
16734 }
16735
16736
16737 /* Prepend the list of glyph strings with head H and tail T to the
16738 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
16739 result. */
16740
16741 static INLINE void
16742 prepend_glyph_string_lists (head, tail, h, t)
16743 struct glyph_string **head, **tail;
16744 struct glyph_string *h, *t;
16745 {
16746 if (h)
16747 {
16748 if (*head)
16749 (*head)->prev = t;
16750 else
16751 *tail = t;
16752 t->next = *head;
16753 *head = h;
16754 }
16755 }
16756
16757
16758 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16759 Set *HEAD and *TAIL to the resulting list. */
16760
16761 static INLINE void
16762 append_glyph_string (head, tail, s)
16763 struct glyph_string **head, **tail;
16764 struct glyph_string *s;
16765 {
16766 s->next = s->prev = NULL;
16767 append_glyph_string_lists (head, tail, s, s);
16768 }
16769
16770
16771 /* Get face and two-byte form of character glyph GLYPH on frame F.
16772 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
16773 a pointer to a realized face that is ready for display. */
16774
16775 static INLINE struct face *
16776 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
16777 struct frame *f;
16778 struct glyph *glyph;
16779 XChar2b *char2b;
16780 int *two_byte_p;
16781 {
16782 struct face *face;
16783
16784 xassert (glyph->type == CHAR_GLYPH);
16785 face = FACE_FROM_ID (f, glyph->face_id);
16786
16787 if (two_byte_p)
16788 *two_byte_p = 0;
16789
16790 if (!glyph->multibyte_p)
16791 {
16792 /* Unibyte case. We don't have to encode, but we have to make
16793 sure to use a face suitable for unibyte. */
16794 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16795 }
16796 else if (glyph->u.ch < 128
16797 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
16798 {
16799 /* Case of ASCII in a face known to fit ASCII. */
16800 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16801 }
16802 else
16803 {
16804 int c1, c2, charset;
16805
16806 /* Split characters into bytes. If c2 is -1 afterwards, C is
16807 really a one-byte character so that byte1 is zero. */
16808 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
16809 if (c2 > 0)
16810 STORE_XCHAR2B (char2b, c1, c2);
16811 else
16812 STORE_XCHAR2B (char2b, 0, c1);
16813
16814 /* Maybe encode the character in *CHAR2B. */
16815 if (charset != CHARSET_ASCII)
16816 {
16817 struct font_info *font_info
16818 = FONT_INFO_FROM_ID (f, face->font_info_id);
16819 if (font_info)
16820 glyph->font_type
16821 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
16822 }
16823 }
16824
16825 /* Make sure X resources of the face are allocated. */
16826 xassert (face != NULL);
16827 PREPARE_FACE_FOR_DISPLAY (f, face);
16828 return face;
16829 }
16830
16831
16832 /* Fill glyph string S with composition components specified by S->cmp.
16833
16834 FACES is an array of faces for all components of this composition.
16835 S->gidx is the index of the first component for S.
16836 OVERLAPS_P non-zero means S should draw the foreground only, and
16837 use its physical height for clipping.
16838
16839 Value is the index of a component not in S. */
16840
16841 static int
16842 fill_composite_glyph_string (s, faces, overlaps_p)
16843 struct glyph_string *s;
16844 struct face **faces;
16845 int overlaps_p;
16846 {
16847 int i;
16848
16849 xassert (s);
16850
16851 s->for_overlaps_p = overlaps_p;
16852
16853 s->face = faces[s->gidx];
16854 s->font = s->face->font;
16855 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16856
16857 /* For all glyphs of this composition, starting at the offset
16858 S->gidx, until we reach the end of the definition or encounter a
16859 glyph that requires the different face, add it to S. */
16860 ++s->nchars;
16861 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
16862 ++s->nchars;
16863
16864 /* All glyph strings for the same composition has the same width,
16865 i.e. the width set for the first component of the composition. */
16866
16867 s->width = s->first_glyph->pixel_width;
16868
16869 /* If the specified font could not be loaded, use the frame's
16870 default font, but record the fact that we couldn't load it in
16871 the glyph string so that we can draw rectangles for the
16872 characters of the glyph string. */
16873 if (s->font == NULL)
16874 {
16875 s->font_not_found_p = 1;
16876 s->font = FRAME_FONT (s->f);
16877 }
16878
16879 /* Adjust base line for subscript/superscript text. */
16880 s->ybase += s->first_glyph->voffset;
16881
16882 xassert (s->face && s->face->gc);
16883
16884 /* This glyph string must always be drawn with 16-bit functions. */
16885 s->two_byte_p = 1;
16886
16887 return s->gidx + s->nchars;
16888 }
16889
16890
16891 /* Fill glyph string S from a sequence of character glyphs.
16892
16893 FACE_ID is the face id of the string. START is the index of the
16894 first glyph to consider, END is the index of the last + 1.
16895 OVERLAPS_P non-zero means S should draw the foreground only, and
16896 use its physical height for clipping.
16897
16898 Value is the index of the first glyph not in S. */
16899
16900 static int
16901 fill_glyph_string (s, face_id, start, end, overlaps_p)
16902 struct glyph_string *s;
16903 int face_id;
16904 int start, end, overlaps_p;
16905 {
16906 struct glyph *glyph, *last;
16907 int voffset;
16908 int glyph_not_available_p;
16909
16910 xassert (s->f == XFRAME (s->w->frame));
16911 xassert (s->nchars == 0);
16912 xassert (start >= 0 && end > start);
16913
16914 s->for_overlaps_p = overlaps_p,
16915 glyph = s->row->glyphs[s->area] + start;
16916 last = s->row->glyphs[s->area] + end;
16917 voffset = glyph->voffset;
16918
16919 glyph_not_available_p = glyph->glyph_not_available_p;
16920
16921 while (glyph < last
16922 && glyph->type == CHAR_GLYPH
16923 && glyph->voffset == voffset
16924 /* Same face id implies same font, nowadays. */
16925 && glyph->face_id == face_id
16926 && glyph->glyph_not_available_p == glyph_not_available_p)
16927 {
16928 int two_byte_p;
16929
16930 s->face = get_glyph_face_and_encoding (s->f, glyph,
16931 s->char2b + s->nchars,
16932 &two_byte_p);
16933 s->two_byte_p = two_byte_p;
16934 ++s->nchars;
16935 xassert (s->nchars <= end - start);
16936 s->width += glyph->pixel_width;
16937 ++glyph;
16938 }
16939
16940 s->font = s->face->font;
16941 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16942
16943 /* If the specified font could not be loaded, use the frame's font,
16944 but record the fact that we couldn't load it in
16945 S->font_not_found_p so that we can draw rectangles for the
16946 characters of the glyph string. */
16947 if (s->font == NULL || glyph_not_available_p)
16948 {
16949 s->font_not_found_p = 1;
16950 s->font = FRAME_FONT (s->f);
16951 }
16952
16953 /* Adjust base line for subscript/superscript text. */
16954 s->ybase += voffset;
16955
16956 xassert (s->face && s->face->gc);
16957 return glyph - s->row->glyphs[s->area];
16958 }
16959
16960
16961 /* Fill glyph string S from image glyph S->first_glyph. */
16962
16963 static void
16964 fill_image_glyph_string (s)
16965 struct glyph_string *s;
16966 {
16967 xassert (s->first_glyph->type == IMAGE_GLYPH);
16968 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
16969 xassert (s->img);
16970 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
16971 s->font = s->face->font;
16972 s->width = s->first_glyph->pixel_width;
16973
16974 /* Adjust base line for subscript/superscript text. */
16975 s->ybase += s->first_glyph->voffset;
16976 }
16977
16978
16979 /* Fill glyph string S from a sequence of stretch glyphs.
16980
16981 ROW is the glyph row in which the glyphs are found, AREA is the
16982 area within the row. START is the index of the first glyph to
16983 consider, END is the index of the last + 1.
16984
16985 Value is the index of the first glyph not in S. */
16986
16987 static int
16988 fill_stretch_glyph_string (s, row, area, start, end)
16989 struct glyph_string *s;
16990 struct glyph_row *row;
16991 enum glyph_row_area area;
16992 int start, end;
16993 {
16994 struct glyph *glyph, *last;
16995 int voffset, face_id;
16996
16997 xassert (s->first_glyph->type == STRETCH_GLYPH);
16998
16999 glyph = s->row->glyphs[s->area] + start;
17000 last = s->row->glyphs[s->area] + end;
17001 face_id = glyph->face_id;
17002 s->face = FACE_FROM_ID (s->f, face_id);
17003 s->font = s->face->font;
17004 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17005 s->width = glyph->pixel_width;
17006 voffset = glyph->voffset;
17007
17008 for (++glyph;
17009 (glyph < last
17010 && glyph->type == STRETCH_GLYPH
17011 && glyph->voffset == voffset
17012 && glyph->face_id == face_id);
17013 ++glyph)
17014 s->width += glyph->pixel_width;
17015
17016 /* Adjust base line for subscript/superscript text. */
17017 s->ybase += voffset;
17018
17019 /* The case that face->gc == 0 is handled when drawing the glyph
17020 string by calling PREPARE_FACE_FOR_DISPLAY. */
17021 xassert (s->face);
17022 return glyph - s->row->glyphs[s->area];
17023 }
17024
17025
17026 /* EXPORT for RIF:
17027 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17028 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17029 assumed to be zero. */
17030
17031 void
17032 x_get_glyph_overhangs (glyph, f, left, right)
17033 struct glyph *glyph;
17034 struct frame *f;
17035 int *left, *right;
17036 {
17037 *left = *right = 0;
17038
17039 if (glyph->type == CHAR_GLYPH)
17040 {
17041 XFontStruct *font;
17042 struct face *face;
17043 struct font_info *font_info;
17044 XChar2b char2b;
17045 XCharStruct *pcm;
17046
17047 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17048 font = face->font;
17049 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17050 if (font /* ++KFS: Should this be font_info ? */
17051 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17052 {
17053 if (pcm->rbearing > pcm->width)
17054 *right = pcm->rbearing - pcm->width;
17055 if (pcm->lbearing < 0)
17056 *left = -pcm->lbearing;
17057 }
17058 }
17059 }
17060
17061
17062 /* Return the index of the first glyph preceding glyph string S that
17063 is overwritten by S because of S's left overhang. Value is -1
17064 if no glyphs are overwritten. */
17065
17066 static int
17067 left_overwritten (s)
17068 struct glyph_string *s;
17069 {
17070 int k;
17071
17072 if (s->left_overhang)
17073 {
17074 int x = 0, i;
17075 struct glyph *glyphs = s->row->glyphs[s->area];
17076 int first = s->first_glyph - glyphs;
17077
17078 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17079 x -= glyphs[i].pixel_width;
17080
17081 k = i + 1;
17082 }
17083 else
17084 k = -1;
17085
17086 return k;
17087 }
17088
17089
17090 /* Return the index of the first glyph preceding glyph string S that
17091 is overwriting S because of its right overhang. Value is -1 if no
17092 glyph in front of S overwrites S. */
17093
17094 static int
17095 left_overwriting (s)
17096 struct glyph_string *s;
17097 {
17098 int i, k, x;
17099 struct glyph *glyphs = s->row->glyphs[s->area];
17100 int first = s->first_glyph - glyphs;
17101
17102 k = -1;
17103 x = 0;
17104 for (i = first - 1; i >= 0; --i)
17105 {
17106 int left, right;
17107 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17108 if (x + right > 0)
17109 k = i;
17110 x -= glyphs[i].pixel_width;
17111 }
17112
17113 return k;
17114 }
17115
17116
17117 /* Return the index of the last glyph following glyph string S that is
17118 not overwritten by S because of S's right overhang. Value is -1 if
17119 no such glyph is found. */
17120
17121 static int
17122 right_overwritten (s)
17123 struct glyph_string *s;
17124 {
17125 int k = -1;
17126
17127 if (s->right_overhang)
17128 {
17129 int x = 0, i;
17130 struct glyph *glyphs = s->row->glyphs[s->area];
17131 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17132 int end = s->row->used[s->area];
17133
17134 for (i = first; i < end && s->right_overhang > x; ++i)
17135 x += glyphs[i].pixel_width;
17136
17137 k = i;
17138 }
17139
17140 return k;
17141 }
17142
17143
17144 /* Return the index of the last glyph following glyph string S that
17145 overwrites S because of its left overhang. Value is negative
17146 if no such glyph is found. */
17147
17148 static int
17149 right_overwriting (s)
17150 struct glyph_string *s;
17151 {
17152 int i, k, x;
17153 int end = s->row->used[s->area];
17154 struct glyph *glyphs = s->row->glyphs[s->area];
17155 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17156
17157 k = -1;
17158 x = 0;
17159 for (i = first; i < end; ++i)
17160 {
17161 int left, right;
17162 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17163 if (x - left < 0)
17164 k = i;
17165 x += glyphs[i].pixel_width;
17166 }
17167
17168 return k;
17169 }
17170
17171
17172 /* Get face and two-byte form of character C in face FACE_ID on frame
17173 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17174 means we want to display multibyte text. DISPLAY_P non-zero means
17175 make sure that X resources for the face returned are allocated.
17176 Value is a pointer to a realized face that is ready for display if
17177 DISPLAY_P is non-zero. */
17178
17179 static INLINE struct face *
17180 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17181 struct frame *f;
17182 int c, face_id;
17183 XChar2b *char2b;
17184 int multibyte_p, display_p;
17185 {
17186 struct face *face = FACE_FROM_ID (f, face_id);
17187
17188 if (!multibyte_p)
17189 {
17190 /* Unibyte case. We don't have to encode, but we have to make
17191 sure to use a face suitable for unibyte. */
17192 STORE_XCHAR2B (char2b, 0, c);
17193 face_id = FACE_FOR_CHAR (f, face, c);
17194 face = FACE_FROM_ID (f, face_id);
17195 }
17196 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17197 {
17198 /* Case of ASCII in a face known to fit ASCII. */
17199 STORE_XCHAR2B (char2b, 0, c);
17200 }
17201 else
17202 {
17203 int c1, c2, charset;
17204
17205 /* Split characters into bytes. If c2 is -1 afterwards, C is
17206 really a one-byte character so that byte1 is zero. */
17207 SPLIT_CHAR (c, charset, c1, c2);
17208 if (c2 > 0)
17209 STORE_XCHAR2B (char2b, c1, c2);
17210 else
17211 STORE_XCHAR2B (char2b, 0, c1);
17212
17213 /* Maybe encode the character in *CHAR2B. */
17214 if (face->font != NULL)
17215 {
17216 struct font_info *font_info
17217 = FONT_INFO_FROM_ID (f, face->font_info_id);
17218 if (font_info)
17219 rif->encode_char (c, char2b, font_info, 0);
17220 }
17221 }
17222
17223 /* Make sure X resources of the face are allocated. */
17224 #ifdef HAVE_X_WINDOWS
17225 if (display_p)
17226 #endif
17227 {
17228 xassert (face != NULL);
17229 PREPARE_FACE_FOR_DISPLAY (f, face);
17230 }
17231
17232 return face;
17233 }
17234
17235
17236 /* Set background width of glyph string S. START is the index of the
17237 first glyph following S. LAST_X is the right-most x-position + 1
17238 in the drawing area. */
17239
17240 static INLINE void
17241 set_glyph_string_background_width (s, start, last_x)
17242 struct glyph_string *s;
17243 int start;
17244 int last_x;
17245 {
17246 /* If the face of this glyph string has to be drawn to the end of
17247 the drawing area, set S->extends_to_end_of_line_p. */
17248 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17249
17250 if (start == s->row->used[s->area]
17251 && s->area == TEXT_AREA
17252 && ((s->hl == DRAW_NORMAL_TEXT
17253 && (s->row->fill_line_p
17254 || s->face->background != default_face->background
17255 || s->face->stipple != default_face->stipple
17256 || s->row->mouse_face_p))
17257 || s->hl == DRAW_MOUSE_FACE
17258 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17259 && s->row->fill_line_p)))
17260 s->extends_to_end_of_line_p = 1;
17261
17262 /* If S extends its face to the end of the line, set its
17263 background_width to the distance to the right edge of the drawing
17264 area. */
17265 if (s->extends_to_end_of_line_p)
17266 s->background_width = last_x - s->x + 1;
17267 else
17268 s->background_width = s->width;
17269 }
17270
17271
17272 /* Compute overhangs and x-positions for glyph string S and its
17273 predecessors, or successors. X is the starting x-position for S.
17274 BACKWARD_P non-zero means process predecessors. */
17275
17276 static void
17277 compute_overhangs_and_x (s, x, backward_p)
17278 struct glyph_string *s;
17279 int x;
17280 int backward_p;
17281 {
17282 if (backward_p)
17283 {
17284 while (s)
17285 {
17286 if (rif->compute_glyph_string_overhangs)
17287 rif->compute_glyph_string_overhangs (s);
17288 x -= s->width;
17289 s->x = x;
17290 s = s->prev;
17291 }
17292 }
17293 else
17294 {
17295 while (s)
17296 {
17297 if (rif->compute_glyph_string_overhangs)
17298 rif->compute_glyph_string_overhangs (s);
17299 s->x = x;
17300 x += s->width;
17301 s = s->next;
17302 }
17303 }
17304 }
17305
17306
17307
17308 /* The following macros are only called from draw_glyphs below.
17309 They reference the following parameters of that function directly:
17310 `w', `row', `area', and `overlap_p'
17311 as well as the following local variables:
17312 `s', `f', and `hdc' (in W32) */
17313
17314 #ifdef HAVE_NTGUI
17315 /* On W32, silently add local `hdc' variable to argument list of
17316 init_glyph_string. */
17317 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17318 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17319 #else
17320 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17321 init_glyph_string (s, char2b, w, row, area, start, hl)
17322 #endif
17323
17324 /* Add a glyph string for a stretch glyph to the list of strings
17325 between HEAD and TAIL. START is the index of the stretch glyph in
17326 row area AREA of glyph row ROW. END is the index of the last glyph
17327 in that glyph row area. X is the current output position assigned
17328 to the new glyph string constructed. HL overrides that face of the
17329 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17330 is the right-most x-position of the drawing area. */
17331
17332 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17333 and below -- keep them on one line. */
17334 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17335 do \
17336 { \
17337 s = (struct glyph_string *) alloca (sizeof *s); \
17338 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17339 START = fill_stretch_glyph_string (s, row, area, START, END); \
17340 append_glyph_string (&HEAD, &TAIL, s); \
17341 s->x = (X); \
17342 } \
17343 while (0)
17344
17345
17346 /* Add a glyph string for an image glyph to the list of strings
17347 between HEAD and TAIL. START is the index of the image glyph in
17348 row area AREA of glyph row ROW. END is the index of the last glyph
17349 in that glyph row area. X is the current output position assigned
17350 to the new glyph string constructed. HL overrides that face of the
17351 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17352 is the right-most x-position of the drawing area. */
17353
17354 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17355 do \
17356 { \
17357 s = (struct glyph_string *) alloca (sizeof *s); \
17358 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17359 fill_image_glyph_string (s); \
17360 append_glyph_string (&HEAD, &TAIL, s); \
17361 ++START; \
17362 s->x = (X); \
17363 } \
17364 while (0)
17365
17366
17367 /* Add a glyph string for a sequence of character glyphs to the list
17368 of strings between HEAD and TAIL. START is the index of the first
17369 glyph in row area AREA of glyph row ROW that is part of the new
17370 glyph string. END is the index of the last glyph in that glyph row
17371 area. X is the current output position assigned to the new glyph
17372 string constructed. HL overrides that face of the glyph; e.g. it
17373 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17374 right-most x-position of the drawing area. */
17375
17376 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17377 do \
17378 { \
17379 int c, face_id; \
17380 XChar2b *char2b; \
17381 \
17382 c = (row)->glyphs[area][START].u.ch; \
17383 face_id = (row)->glyphs[area][START].face_id; \
17384 \
17385 s = (struct glyph_string *) alloca (sizeof *s); \
17386 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17387 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17388 append_glyph_string (&HEAD, &TAIL, s); \
17389 s->x = (X); \
17390 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17391 } \
17392 while (0)
17393
17394
17395 /* Add a glyph string for a composite sequence to the list of strings
17396 between HEAD and TAIL. START is the index of the first glyph in
17397 row area AREA of glyph row ROW that is part of the new glyph
17398 string. END is the index of the last glyph in that glyph row area.
17399 X is the current output position assigned to the new glyph string
17400 constructed. HL overrides that face of the glyph; e.g. it is
17401 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17402 x-position of the drawing area. */
17403
17404 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17405 do { \
17406 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17407 int face_id = (row)->glyphs[area][START].face_id; \
17408 struct face *base_face = FACE_FROM_ID (f, face_id); \
17409 struct composition *cmp = composition_table[cmp_id]; \
17410 int glyph_len = cmp->glyph_len; \
17411 XChar2b *char2b; \
17412 struct face **faces; \
17413 struct glyph_string *first_s = NULL; \
17414 int n; \
17415 \
17416 base_face = base_face->ascii_face; \
17417 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17418 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17419 /* At first, fill in `char2b' and `faces'. */ \
17420 for (n = 0; n < glyph_len; n++) \
17421 { \
17422 int c = COMPOSITION_GLYPH (cmp, n); \
17423 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17424 faces[n] = FACE_FROM_ID (f, this_face_id); \
17425 get_char_face_and_encoding (f, c, this_face_id, \
17426 char2b + n, 1, 1); \
17427 } \
17428 \
17429 /* Make glyph_strings for each glyph sequence that is drawable by \
17430 the same face, and append them to HEAD/TAIL. */ \
17431 for (n = 0; n < cmp->glyph_len;) \
17432 { \
17433 s = (struct glyph_string *) alloca (sizeof *s); \
17434 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17435 append_glyph_string (&(HEAD), &(TAIL), s); \
17436 s->cmp = cmp; \
17437 s->gidx = n; \
17438 s->x = (X); \
17439 \
17440 if (n == 0) \
17441 first_s = s; \
17442 \
17443 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17444 } \
17445 \
17446 ++START; \
17447 s = first_s; \
17448 } while (0)
17449
17450
17451 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17452 of AREA of glyph row ROW on window W between indices START and END.
17453 HL overrides the face for drawing glyph strings, e.g. it is
17454 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17455 x-positions of the drawing area.
17456
17457 This is an ugly monster macro construct because we must use alloca
17458 to allocate glyph strings (because draw_glyphs can be called
17459 asynchronously). */
17460
17461 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17462 do \
17463 { \
17464 HEAD = TAIL = NULL; \
17465 while (START < END) \
17466 { \
17467 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17468 switch (first_glyph->type) \
17469 { \
17470 case CHAR_GLYPH: \
17471 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17472 HL, X, LAST_X); \
17473 break; \
17474 \
17475 case COMPOSITE_GLYPH: \
17476 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17477 HL, X, LAST_X); \
17478 break; \
17479 \
17480 case STRETCH_GLYPH: \
17481 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17482 HL, X, LAST_X); \
17483 break; \
17484 \
17485 case IMAGE_GLYPH: \
17486 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17487 HL, X, LAST_X); \
17488 break; \
17489 \
17490 default: \
17491 abort (); \
17492 } \
17493 \
17494 set_glyph_string_background_width (s, START, LAST_X); \
17495 (X) += s->width; \
17496 } \
17497 } \
17498 while (0)
17499
17500
17501 /* Draw glyphs between START and END in AREA of ROW on window W,
17502 starting at x-position X. X is relative to AREA in W. HL is a
17503 face-override with the following meaning:
17504
17505 DRAW_NORMAL_TEXT draw normally
17506 DRAW_CURSOR draw in cursor face
17507 DRAW_MOUSE_FACE draw in mouse face.
17508 DRAW_INVERSE_VIDEO draw in mode line face
17509 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17510 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17511
17512 If OVERLAPS_P is non-zero, draw only the foreground of characters
17513 and clip to the physical height of ROW.
17514
17515 Value is the x-position reached, relative to AREA of W. */
17516
17517 static int
17518 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17519 struct window *w;
17520 int x;
17521 struct glyph_row *row;
17522 enum glyph_row_area area;
17523 int start, end;
17524 enum draw_glyphs_face hl;
17525 int overlaps_p;
17526 {
17527 struct glyph_string *head, *tail;
17528 struct glyph_string *s;
17529 int last_x, area_width;
17530 int x_reached;
17531 int i, j;
17532 struct frame *f = XFRAME (WINDOW_FRAME (w));
17533 DECLARE_HDC (hdc);
17534
17535 ALLOCATE_HDC (hdc, f);
17536
17537 /* Let's rather be paranoid than getting a SEGV. */
17538 end = min (end, row->used[area]);
17539 start = max (0, start);
17540 start = min (end, start);
17541
17542 /* Translate X to frame coordinates. Set last_x to the right
17543 end of the drawing area. */
17544 if (row->full_width_p)
17545 {
17546 /* X is relative to the left edge of W, without scroll bars
17547 or fringes. */
17548 x += WINDOW_LEFT_EDGE_X (w);
17549 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
17550 }
17551 else
17552 {
17553 int area_left = window_box_left (w, area);
17554 x += area_left;
17555 area_width = window_box_width (w, area);
17556 last_x = area_left + area_width;
17557 }
17558
17559 /* Build a doubly-linked list of glyph_string structures between
17560 head and tail from what we have to draw. Note that the macro
17561 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17562 the reason we use a separate variable `i'. */
17563 i = start;
17564 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17565 if (tail)
17566 x_reached = tail->x + tail->background_width;
17567 else
17568 x_reached = x;
17569
17570 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17571 the row, redraw some glyphs in front or following the glyph
17572 strings built above. */
17573 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17574 {
17575 int dummy_x = 0;
17576 struct glyph_string *h, *t;
17577
17578 /* Compute overhangs for all glyph strings. */
17579 if (rif->compute_glyph_string_overhangs)
17580 for (s = head; s; s = s->next)
17581 rif->compute_glyph_string_overhangs (s);
17582
17583 /* Prepend glyph strings for glyphs in front of the first glyph
17584 string that are overwritten because of the first glyph
17585 string's left overhang. The background of all strings
17586 prepended must be drawn because the first glyph string
17587 draws over it. */
17588 i = left_overwritten (head);
17589 if (i >= 0)
17590 {
17591 j = i;
17592 BUILD_GLYPH_STRINGS (j, start, h, t,
17593 DRAW_NORMAL_TEXT, dummy_x, last_x);
17594 start = i;
17595 compute_overhangs_and_x (t, head->x, 1);
17596 prepend_glyph_string_lists (&head, &tail, h, t);
17597 }
17598
17599 /* Prepend glyph strings for glyphs in front of the first glyph
17600 string that overwrite that glyph string because of their
17601 right overhang. For these strings, only the foreground must
17602 be drawn, because it draws over the glyph string at `head'.
17603 The background must not be drawn because this would overwrite
17604 right overhangs of preceding glyphs for which no glyph
17605 strings exist. */
17606 i = left_overwriting (head);
17607 if (i >= 0)
17608 {
17609 BUILD_GLYPH_STRINGS (i, start, h, t,
17610 DRAW_NORMAL_TEXT, dummy_x, last_x);
17611 for (s = h; s; s = s->next)
17612 s->background_filled_p = 1;
17613 compute_overhangs_and_x (t, head->x, 1);
17614 prepend_glyph_string_lists (&head, &tail, h, t);
17615 }
17616
17617 /* Append glyphs strings for glyphs following the last glyph
17618 string tail that are overwritten by tail. The background of
17619 these strings has to be drawn because tail's foreground draws
17620 over it. */
17621 i = right_overwritten (tail);
17622 if (i >= 0)
17623 {
17624 BUILD_GLYPH_STRINGS (end, i, h, t,
17625 DRAW_NORMAL_TEXT, x, last_x);
17626 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17627 append_glyph_string_lists (&head, &tail, h, t);
17628 }
17629
17630 /* Append glyph strings for glyphs following the last glyph
17631 string tail that overwrite tail. The foreground of such
17632 glyphs has to be drawn because it writes into the background
17633 of tail. The background must not be drawn because it could
17634 paint over the foreground of following glyphs. */
17635 i = right_overwriting (tail);
17636 if (i >= 0)
17637 {
17638 BUILD_GLYPH_STRINGS (end, i, h, t,
17639 DRAW_NORMAL_TEXT, x, last_x);
17640 for (s = h; s; s = s->next)
17641 s->background_filled_p = 1;
17642 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17643 append_glyph_string_lists (&head, &tail, h, t);
17644 }
17645 }
17646
17647 /* Draw all strings. */
17648 for (s = head; s; s = s->next)
17649 rif->draw_glyph_string (s);
17650
17651 if (area == TEXT_AREA
17652 && !row->full_width_p
17653 /* When drawing overlapping rows, only the glyph strings'
17654 foreground is drawn, which doesn't erase a cursor
17655 completely. */
17656 && !overlaps_p)
17657 {
17658 int x0 = head ? head->x : x;
17659 int x1 = tail ? tail->x + tail->background_width : x;
17660
17661 int text_left = window_box_left (w, TEXT_AREA);
17662 x0 -= text_left;
17663 x1 -= text_left;
17664
17665 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
17666 row->y, MATRIX_ROW_BOTTOM_Y (row));
17667 }
17668
17669 /* Value is the x-position up to which drawn, relative to AREA of W.
17670 This doesn't include parts drawn because of overhangs. */
17671 if (row->full_width_p)
17672 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
17673 else
17674 x_reached -= window_box_left (w, area);
17675
17676 RELEASE_HDC (hdc, f);
17677
17678 return x_reached;
17679 }
17680
17681
17682 /* Store one glyph for IT->char_to_display in IT->glyph_row.
17683 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17684
17685 static INLINE void
17686 append_glyph (it)
17687 struct it *it;
17688 {
17689 struct glyph *glyph;
17690 enum glyph_row_area area = it->area;
17691
17692 xassert (it->glyph_row);
17693 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
17694
17695 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17696 if (glyph < it->glyph_row->glyphs[area + 1])
17697 {
17698 glyph->charpos = CHARPOS (it->position);
17699 glyph->object = it->object;
17700 glyph->pixel_width = it->pixel_width;
17701 glyph->ascent = it->ascent;
17702 glyph->descent = it->descent;
17703 glyph->voffset = it->voffset;
17704 glyph->type = CHAR_GLYPH;
17705 glyph->multibyte_p = it->multibyte_p;
17706 glyph->left_box_line_p = it->start_of_box_run_p;
17707 glyph->right_box_line_p = it->end_of_box_run_p;
17708 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17709 || it->phys_descent > it->descent);
17710 glyph->padding_p = 0;
17711 glyph->glyph_not_available_p = it->glyph_not_available_p;
17712 glyph->face_id = it->face_id;
17713 glyph->u.ch = it->char_to_display;
17714 glyph->font_type = FONT_TYPE_UNKNOWN;
17715 ++it->glyph_row->used[area];
17716 }
17717 }
17718
17719 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17720 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17721
17722 static INLINE void
17723 append_composite_glyph (it)
17724 struct it *it;
17725 {
17726 struct glyph *glyph;
17727 enum glyph_row_area area = it->area;
17728
17729 xassert (it->glyph_row);
17730
17731 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17732 if (glyph < it->glyph_row->glyphs[area + 1])
17733 {
17734 glyph->charpos = CHARPOS (it->position);
17735 glyph->object = it->object;
17736 glyph->pixel_width = it->pixel_width;
17737 glyph->ascent = it->ascent;
17738 glyph->descent = it->descent;
17739 glyph->voffset = it->voffset;
17740 glyph->type = COMPOSITE_GLYPH;
17741 glyph->multibyte_p = it->multibyte_p;
17742 glyph->left_box_line_p = it->start_of_box_run_p;
17743 glyph->right_box_line_p = it->end_of_box_run_p;
17744 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17745 || it->phys_descent > it->descent);
17746 glyph->padding_p = 0;
17747 glyph->glyph_not_available_p = 0;
17748 glyph->face_id = it->face_id;
17749 glyph->u.cmp_id = it->cmp_id;
17750 glyph->font_type = FONT_TYPE_UNKNOWN;
17751 ++it->glyph_row->used[area];
17752 }
17753 }
17754
17755
17756 /* Change IT->ascent and IT->height according to the setting of
17757 IT->voffset. */
17758
17759 static INLINE void
17760 take_vertical_position_into_account (it)
17761 struct it *it;
17762 {
17763 if (it->voffset)
17764 {
17765 if (it->voffset < 0)
17766 /* Increase the ascent so that we can display the text higher
17767 in the line. */
17768 it->ascent += abs (it->voffset);
17769 else
17770 /* Increase the descent so that we can display the text lower
17771 in the line. */
17772 it->descent += it->voffset;
17773 }
17774 }
17775
17776
17777 /* Produce glyphs/get display metrics for the image IT is loaded with.
17778 See the description of struct display_iterator in dispextern.h for
17779 an overview of struct display_iterator. */
17780
17781 static void
17782 produce_image_glyph (it)
17783 struct it *it;
17784 {
17785 struct image *img;
17786 struct face *face;
17787 int face_ascent, glyph_ascent;
17788
17789 xassert (it->what == IT_IMAGE);
17790
17791 face = FACE_FROM_ID (it->f, it->face_id);
17792 img = IMAGE_FROM_ID (it->f, it->image_id);
17793 xassert (img);
17794
17795 /* Make sure X resources of the face and image are loaded. */
17796 PREPARE_FACE_FOR_DISPLAY (it->f, face);
17797 prepare_image_for_display (it->f, img);
17798
17799 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face);
17800 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
17801 it->pixel_width = img->width + 2 * img->hmargin;
17802
17803 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
17804 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
17805 if (face_ascent > it->ascent)
17806 it->ascent = it->phys_ascent = face_ascent;
17807
17808 it->nglyphs = 1;
17809
17810 if (face->box != FACE_NO_BOX)
17811 {
17812 if (face->box_line_width > 0)
17813 {
17814 it->ascent += face->box_line_width;
17815 it->descent += face->box_line_width;
17816 }
17817
17818 if (it->start_of_box_run_p)
17819 it->pixel_width += abs (face->box_line_width);
17820 if (it->end_of_box_run_p)
17821 it->pixel_width += abs (face->box_line_width);
17822 }
17823
17824 take_vertical_position_into_account (it);
17825
17826 if (it->glyph_row)
17827 {
17828 struct glyph *glyph;
17829 enum glyph_row_area area = it->area;
17830
17831 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17832 if (glyph < it->glyph_row->glyphs[area + 1])
17833 {
17834 glyph->charpos = CHARPOS (it->position);
17835 glyph->object = it->object;
17836 glyph->pixel_width = it->pixel_width;
17837 glyph->ascent = glyph_ascent;
17838 glyph->descent = it->descent;
17839 glyph->voffset = it->voffset;
17840 glyph->type = IMAGE_GLYPH;
17841 glyph->multibyte_p = it->multibyte_p;
17842 glyph->left_box_line_p = it->start_of_box_run_p;
17843 glyph->right_box_line_p = it->end_of_box_run_p;
17844 glyph->overlaps_vertically_p = 0;
17845 glyph->padding_p = 0;
17846 glyph->glyph_not_available_p = 0;
17847 glyph->face_id = it->face_id;
17848 glyph->u.img_id = img->id;
17849 glyph->font_type = FONT_TYPE_UNKNOWN;
17850 ++it->glyph_row->used[area];
17851 }
17852 }
17853 }
17854
17855
17856 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
17857 of the glyph, WIDTH and HEIGHT are the width and height of the
17858 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
17859
17860 static void
17861 append_stretch_glyph (it, object, width, height, ascent)
17862 struct it *it;
17863 Lisp_Object object;
17864 int width, height;
17865 int ascent;
17866 {
17867 struct glyph *glyph;
17868 enum glyph_row_area area = it->area;
17869
17870 xassert (ascent >= 0 && ascent <= height);
17871
17872 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17873 if (glyph < it->glyph_row->glyphs[area + 1])
17874 {
17875 glyph->charpos = CHARPOS (it->position);
17876 glyph->object = object;
17877 glyph->pixel_width = width;
17878 glyph->ascent = ascent;
17879 glyph->descent = height - ascent;
17880 glyph->voffset = it->voffset;
17881 glyph->type = STRETCH_GLYPH;
17882 glyph->multibyte_p = it->multibyte_p;
17883 glyph->left_box_line_p = it->start_of_box_run_p;
17884 glyph->right_box_line_p = it->end_of_box_run_p;
17885 glyph->overlaps_vertically_p = 0;
17886 glyph->padding_p = 0;
17887 glyph->glyph_not_available_p = 0;
17888 glyph->face_id = it->face_id;
17889 glyph->u.stretch.ascent = ascent;
17890 glyph->u.stretch.height = height;
17891 glyph->font_type = FONT_TYPE_UNKNOWN;
17892 ++it->glyph_row->used[area];
17893 }
17894 }
17895
17896
17897 /* Calculate a width or height in pixels from a specification using
17898 the following elements:
17899
17900 SPEC ::=
17901 NUM - a (fractional) multiple of the default font width/height
17902 (NUM) - specifies exactly NUM pixels
17903 UNIT - a fixed number of pixels, see below.
17904 ELEMENT - size of a display element in pixels, see below.
17905 (NUM . SPEC) - equals NUM * SPEC
17906 (+ SPEC SPEC ...) - add pixel values
17907 (- SPEC SPEC ...) - subtract pixel values
17908 (- SPEC) - negate pixel value
17909
17910 NUM ::=
17911 INT or FLOAT - a number constant
17912 SYMBOL - use symbol's (buffer local) variable binding.
17913
17914 UNIT ::=
17915 in - pixels per inch *)
17916 mm - pixels per 1/1000 meter *)
17917 cm - pixels per 1/100 meter *)
17918 width - width of current font in pixels.
17919 height - height of current font in pixels.
17920
17921 *) using the ratio(s) defined in display-pixels-per-inch.
17922
17923 ELEMENT ::=
17924
17925 left-fringe - left fringe width in pixels
17926 (left-fringe . nil) - left fringe width if inside margins, else 0
17927 (left-fringe . t) - left fringe width if outside margins, else 0
17928
17929 right-fringe - right fringe width in pixels
17930 (right-fringe . nil) - right fringe width if inside margins, else 0
17931 (right-fringe . t) - right fringe width if outside margins, else 0
17932
17933 left-margin - left margin width in pixels
17934 right-margin - right margin width in pixels
17935
17936 scroll-bar - scroll-bar area width in pixels
17937 (scroll-bar . left) - scroll-bar width if on left, else 0
17938 (scroll-bar . right) - scroll-bar width if on right, else 0
17939
17940 Examples:
17941
17942 Pixels corresponding to 5 inches:
17943 (5 . in)
17944
17945 Total width of non-text areas on left side of window:
17946 (+ left-fringe left-margin (scroll-bar . left))
17947
17948 Total width of fringes if inside display margins:
17949 (+ (left-fringe) (right-fringe))
17950
17951 Width of left margin minus width of 1 character in the default font:
17952 (- left-margin 1)
17953
17954 Width of left margin minus width of 2 characters in the current font:
17955 (- left-margin (2 . width))
17956
17957 Width of left fringe plus left margin minus one pixel:
17958 (- (+ left-fringe left-margin) (1))
17959 (+ left-fringe left-margin (- (1)))
17960 (+ left-fringe left-margin (-1))
17961
17962 */
17963
17964 #define NUMVAL(X) \
17965 ((INTEGERP (X) || FLOATP (X)) \
17966 ? XFLOATINT (X) \
17967 : - 1)
17968
17969 static int
17970 calc_pixel_width_or_height (res, it, prop, font, width_p)
17971 double *res;
17972 struct it *it;
17973 Lisp_Object prop;
17974 XFontStruct *font;
17975 int width_p;
17976 {
17977 double pixels;
17978
17979 #define OK_PIXELS(val) ((*res = (val)), 1)
17980
17981 if (SYMBOLP (prop))
17982 {
17983 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17984 {
17985 char *unit = SDATA (SYMBOL_NAME (prop));
17986
17987 if (unit[0] == 'i' && unit[1] == 'n')
17988 pixels = 1.0;
17989 else if (unit[0] == 'm' && unit[1] == 'm')
17990 pixels = 25.4;
17991 else if (unit[0] == 'c' && unit[1] == 'm')
17992 pixels = 2.54;
17993 else
17994 pixels = 0;
17995 if (pixels > 0)
17996 {
17997 double ppi;
17998 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17999 || (CONSP (Vdisplay_pixels_per_inch)
18000 && (ppi = (width_p
18001 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
18002 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
18003 ppi > 0)))
18004 return OK_PIXELS (ppi / pixels);
18005
18006 return 0;
18007 }
18008 }
18009
18010 if (EQ (prop, Qheight))
18011 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
18012 if (EQ (prop, Qwidth))
18013 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
18014 if (EQ (prop, Qleft_fringe))
18015 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
18016 if (EQ (prop, Qright_fringe))
18017 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
18018 if (EQ (prop, Qleft_margin))
18019 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
18020 if (EQ (prop, Qright_margin))
18021 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
18022 if (EQ (prop, Qscroll_bar))
18023 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
18024
18025 prop = Fbuffer_local_value (prop, it->w->buffer);
18026 }
18027
18028 if (INTEGERP (prop) || FLOATP (prop))
18029 {
18030 int base_unit = (width_p
18031 ? FRAME_COLUMN_WIDTH (it->f)
18032 : FRAME_LINE_HEIGHT (it->f));
18033 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18034 }
18035
18036 if (CONSP (prop))
18037 {
18038 Lisp_Object car = XCAR (prop);
18039 Lisp_Object cdr = XCDR (prop);
18040
18041 if (SYMBOLP (car))
18042 {
18043 if (EQ (car, Qplus) || EQ (car, Qminus))
18044 {
18045 int first = 1;
18046 double px;
18047
18048 pixels = 0;
18049 while (CONSP (cdr))
18050 {
18051 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr), font, width_p))
18052 return 0;
18053 if (first)
18054 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18055 else
18056 pixels += px;
18057 cdr = XCDR (cdr);
18058 }
18059 if (EQ (car, Qminus))
18060 pixels = -pixels;
18061 return OK_PIXELS (pixels);
18062 }
18063
18064 if (EQ (car, Qleft_fringe))
18065 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18066 == !NILP (cdr))
18067 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
18068 : 0);
18069 if (EQ (car, Qright_fringe))
18070 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18071 == !NILP (cdr))
18072 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18073 : 0);
18074 if (EQ (car, Qscroll_bar))
18075 return OK_PIXELS ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18076 == EQ (cdr, Qleft))
18077 ? WINDOW_SCROLL_BAR_AREA_WIDTH (it->w)
18078 : 0);
18079
18080 car = Fbuffer_local_value (car, it->w->buffer);
18081 }
18082
18083 if (INTEGERP (car) || FLOATP (car))
18084 {
18085 double fact;
18086 pixels = XFLOATINT (car);
18087 if (NILP (cdr))
18088 return OK_PIXELS (pixels);
18089 if (calc_pixel_width_or_height (&fact, it, cdr, font, width_p))
18090 return OK_PIXELS (pixels * fact);
18091 return 0;
18092 }
18093
18094 return 0;
18095 }
18096
18097 return 0;
18098 }
18099
18100 /* Produce a stretch glyph for iterator IT. IT->object is the value
18101 of the glyph property displayed. The value must be a list
18102 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18103 being recognized:
18104
18105 1. `:width WIDTH' specifies that the space should be WIDTH *
18106 canonical char width wide. WIDTH may be an integer or floating
18107 point number.
18108
18109 2. `:relative-width FACTOR' specifies that the width of the stretch
18110 should be computed from the width of the first character having the
18111 `glyph' property, and should be FACTOR times that width.
18112
18113 3. `:align-to HPOS' specifies that the space should be wide enough
18114 to reach HPOS, a value in canonical character units.
18115
18116 Exactly one of the above pairs must be present.
18117
18118 4. `:height HEIGHT' specifies that the height of the stretch produced
18119 should be HEIGHT, measured in canonical character units.
18120
18121 5. `:relative-height FACTOR' specifies that the height of the
18122 stretch should be FACTOR times the height of the characters having
18123 the glyph property.
18124
18125 Either none or exactly one of 4 or 5 must be present.
18126
18127 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18128 of the stretch should be used for the ascent of the stretch.
18129 ASCENT must be in the range 0 <= ASCENT <= 100. */
18130
18131 static void
18132 produce_stretch_glyph (it)
18133 struct it *it;
18134 {
18135 /* (space :width WIDTH :height HEIGHT ...) */
18136 Lisp_Object prop, plist;
18137 int width = 0, height = 0;
18138 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18139 int ascent = 0;
18140 double tem;
18141 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18142 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18143
18144 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18145
18146 /* List should start with `space'. */
18147 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18148 plist = XCDR (it->object);
18149
18150 /* Compute the width of the stretch. */
18151 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18152 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18153 {
18154 /* Absolute width `:width WIDTH' specified and valid. */
18155 zero_width_ok_p = 1;
18156 width = (int)tem;
18157 }
18158 else if (prop = Fplist_get (plist, QCrelative_width),
18159 NUMVAL (prop) > 0)
18160 {
18161 /* Relative width `:relative-width FACTOR' specified and valid.
18162 Compute the width of the characters having the `glyph'
18163 property. */
18164 struct it it2;
18165 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18166
18167 it2 = *it;
18168 if (it->multibyte_p)
18169 {
18170 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18171 - IT_BYTEPOS (*it));
18172 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18173 }
18174 else
18175 it2.c = *p, it2.len = 1;
18176
18177 it2.glyph_row = NULL;
18178 it2.what = IT_CHARACTER;
18179 x_produce_glyphs (&it2);
18180 width = NUMVAL (prop) * it2.pixel_width;
18181 }
18182 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18183 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18184 {
18185 width = max (0, (int)tem - it->current_x);
18186 zero_width_ok_p = 1;
18187 }
18188 else
18189 /* Nothing specified -> width defaults to canonical char width. */
18190 width = FRAME_COLUMN_WIDTH (it->f);
18191
18192 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18193 width = 1;
18194
18195 /* Compute height. */
18196 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18197 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18198 {
18199 height = (int)tem;
18200 zero_height_ok_p = 1;
18201 }
18202 else if (prop = Fplist_get (plist, QCrelative_height),
18203 NUMVAL (prop) > 0)
18204 height = FONT_HEIGHT (font) * NUMVAL (prop);
18205 else
18206 height = FONT_HEIGHT (font);
18207
18208 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18209 height = 1;
18210
18211 /* Compute percentage of height used for ascent. If
18212 `:ascent ASCENT' is present and valid, use that. Otherwise,
18213 derive the ascent from the font in use. */
18214 if (prop = Fplist_get (plist, QCascent),
18215 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18216 ascent = height * NUMVAL (prop) / 100.0;
18217 else if (!NILP (prop)
18218 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18219 ascent = min (max (0, (int)tem), height);
18220 else
18221 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18222
18223 if (width > 0 && height > 0 && it->glyph_row)
18224 {
18225 Lisp_Object object = it->stack[it->sp - 1].string;
18226 if (!STRINGP (object))
18227 object = it->w->buffer;
18228 append_stretch_glyph (it, object, width, height, ascent);
18229 }
18230
18231 it->pixel_width = width;
18232 it->ascent = it->phys_ascent = ascent;
18233 it->descent = it->phys_descent = height - it->ascent;
18234 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18235
18236 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18237 {
18238 if (face->box_line_width > 0)
18239 {
18240 it->ascent += face->box_line_width;
18241 it->descent += face->box_line_width;
18242 }
18243
18244 if (it->start_of_box_run_p)
18245 it->pixel_width += abs (face->box_line_width);
18246 if (it->end_of_box_run_p)
18247 it->pixel_width += abs (face->box_line_width);
18248 }
18249
18250 take_vertical_position_into_account (it);
18251 }
18252
18253 /* RIF:
18254 Produce glyphs/get display metrics for the display element IT is
18255 loaded with. See the description of struct display_iterator in
18256 dispextern.h for an overview of struct display_iterator. */
18257
18258 void
18259 x_produce_glyphs (it)
18260 struct it *it;
18261 {
18262 it->glyph_not_available_p = 0;
18263
18264 if (it->what == IT_CHARACTER)
18265 {
18266 XChar2b char2b;
18267 XFontStruct *font;
18268 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18269 XCharStruct *pcm;
18270 int font_not_found_p;
18271 struct font_info *font_info;
18272 int boff; /* baseline offset */
18273 /* We may change it->multibyte_p upon unibyte<->multibyte
18274 conversion. So, save the current value now and restore it
18275 later.
18276
18277 Note: It seems that we don't have to record multibyte_p in
18278 struct glyph because the character code itself tells if or
18279 not the character is multibyte. Thus, in the future, we must
18280 consider eliminating the field `multibyte_p' in the struct
18281 glyph. */
18282 int saved_multibyte_p = it->multibyte_p;
18283
18284 /* Maybe translate single-byte characters to multibyte, or the
18285 other way. */
18286 it->char_to_display = it->c;
18287 if (!ASCII_BYTE_P (it->c))
18288 {
18289 if (unibyte_display_via_language_environment
18290 && SINGLE_BYTE_CHAR_P (it->c)
18291 && (it->c >= 0240
18292 || !NILP (Vnonascii_translation_table)))
18293 {
18294 it->char_to_display = unibyte_char_to_multibyte (it->c);
18295 it->multibyte_p = 1;
18296 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18297 face = FACE_FROM_ID (it->f, it->face_id);
18298 }
18299 else if (!SINGLE_BYTE_CHAR_P (it->c)
18300 && !it->multibyte_p)
18301 {
18302 it->multibyte_p = 1;
18303 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18304 face = FACE_FROM_ID (it->f, it->face_id);
18305 }
18306 }
18307
18308 /* Get font to use. Encode IT->char_to_display. */
18309 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18310 &char2b, it->multibyte_p, 0);
18311 font = face->font;
18312
18313 /* When no suitable font found, use the default font. */
18314 font_not_found_p = font == NULL;
18315 if (font_not_found_p)
18316 {
18317 font = FRAME_FONT (it->f);
18318 boff = FRAME_BASELINE_OFFSET (it->f);
18319 font_info = NULL;
18320 }
18321 else
18322 {
18323 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18324 boff = font_info->baseline_offset;
18325 if (font_info->vertical_centering)
18326 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18327 }
18328
18329 if (it->char_to_display >= ' '
18330 && (!it->multibyte_p || it->char_to_display < 128))
18331 {
18332 /* Either unibyte or ASCII. */
18333 int stretched_p;
18334
18335 it->nglyphs = 1;
18336
18337 pcm = rif->per_char_metric (font, &char2b,
18338 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18339 it->ascent = FONT_BASE (font) + boff;
18340 it->descent = FONT_DESCENT (font) - boff;
18341
18342 if (pcm)
18343 {
18344 it->phys_ascent = pcm->ascent + boff;
18345 it->phys_descent = pcm->descent - boff;
18346 it->pixel_width = pcm->width;
18347 }
18348 else
18349 {
18350 it->glyph_not_available_p = 1;
18351 it->phys_ascent = FONT_BASE (font) + boff;
18352 it->phys_descent = FONT_DESCENT (font) - boff;
18353 it->pixel_width = FONT_WIDTH (font);
18354 }
18355
18356 /* If this is a space inside a region of text with
18357 `space-width' property, change its width. */
18358 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18359 if (stretched_p)
18360 it->pixel_width *= XFLOATINT (it->space_width);
18361
18362 /* If face has a box, add the box thickness to the character
18363 height. If character has a box line to the left and/or
18364 right, add the box line width to the character's width. */
18365 if (face->box != FACE_NO_BOX)
18366 {
18367 int thick = face->box_line_width;
18368
18369 if (thick > 0)
18370 {
18371 it->ascent += thick;
18372 it->descent += thick;
18373 }
18374 else
18375 thick = -thick;
18376
18377 if (it->start_of_box_run_p)
18378 it->pixel_width += thick;
18379 if (it->end_of_box_run_p)
18380 it->pixel_width += thick;
18381 }
18382
18383 /* If face has an overline, add the height of the overline
18384 (1 pixel) and a 1 pixel margin to the character height. */
18385 if (face->overline_p)
18386 it->ascent += 2;
18387
18388 take_vertical_position_into_account (it);
18389
18390 /* If we have to actually produce glyphs, do it. */
18391 if (it->glyph_row)
18392 {
18393 if (stretched_p)
18394 {
18395 /* Translate a space with a `space-width' property
18396 into a stretch glyph. */
18397 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18398 / FONT_HEIGHT (font));
18399 append_stretch_glyph (it, it->object, it->pixel_width,
18400 it->ascent + it->descent, ascent);
18401 }
18402 else
18403 append_glyph (it);
18404
18405 /* If characters with lbearing or rbearing are displayed
18406 in this line, record that fact in a flag of the
18407 glyph row. This is used to optimize X output code. */
18408 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18409 it->glyph_row->contains_overlapping_glyphs_p = 1;
18410 }
18411 }
18412 else if (it->char_to_display == '\n')
18413 {
18414 /* A newline has no width but we need the height of the line. */
18415 it->pixel_width = 0;
18416 it->nglyphs = 0;
18417 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18418 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18419
18420 if (face->box != FACE_NO_BOX
18421 && face->box_line_width > 0)
18422 {
18423 it->ascent += face->box_line_width;
18424 it->descent += face->box_line_width;
18425 }
18426 }
18427 else if (it->char_to_display == '\t')
18428 {
18429 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
18430 int x = it->current_x + it->continuation_lines_width;
18431 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
18432
18433 /* If the distance from the current position to the next tab
18434 stop is less than a canonical character width, use the
18435 tab stop after that. */
18436 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
18437 next_tab_x += tab_width;
18438
18439 it->pixel_width = next_tab_x - x;
18440 it->nglyphs = 1;
18441 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18442 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18443
18444 if (it->glyph_row)
18445 {
18446 append_stretch_glyph (it, it->object, it->pixel_width,
18447 it->ascent + it->descent, it->ascent);
18448 }
18449 }
18450 else
18451 {
18452 /* A multi-byte character. Assume that the display width of the
18453 character is the width of the character multiplied by the
18454 width of the font. */
18455
18456 /* If we found a font, this font should give us the right
18457 metrics. If we didn't find a font, use the frame's
18458 default font and calculate the width of the character
18459 from the charset width; this is what old redisplay code
18460 did. */
18461
18462 pcm = rif->per_char_metric (font, &char2b,
18463 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18464
18465 if (font_not_found_p || !pcm)
18466 {
18467 int charset = CHAR_CHARSET (it->char_to_display);
18468
18469 it->glyph_not_available_p = 1;
18470 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
18471 * CHARSET_WIDTH (charset));
18472 it->phys_ascent = FONT_BASE (font) + boff;
18473 it->phys_descent = FONT_DESCENT (font) - boff;
18474 }
18475 else
18476 {
18477 it->pixel_width = pcm->width;
18478 it->phys_ascent = pcm->ascent + boff;
18479 it->phys_descent = pcm->descent - boff;
18480 if (it->glyph_row
18481 && (pcm->lbearing < 0
18482 || pcm->rbearing > pcm->width))
18483 it->glyph_row->contains_overlapping_glyphs_p = 1;
18484 }
18485 it->nglyphs = 1;
18486 it->ascent = FONT_BASE (font) + boff;
18487 it->descent = FONT_DESCENT (font) - boff;
18488 if (face->box != FACE_NO_BOX)
18489 {
18490 int thick = face->box_line_width;
18491
18492 if (thick > 0)
18493 {
18494 it->ascent += thick;
18495 it->descent += thick;
18496 }
18497 else
18498 thick = - thick;
18499
18500 if (it->start_of_box_run_p)
18501 it->pixel_width += thick;
18502 if (it->end_of_box_run_p)
18503 it->pixel_width += thick;
18504 }
18505
18506 /* If face has an overline, add the height of the overline
18507 (1 pixel) and a 1 pixel margin to the character height. */
18508 if (face->overline_p)
18509 it->ascent += 2;
18510
18511 take_vertical_position_into_account (it);
18512
18513 if (it->glyph_row)
18514 append_glyph (it);
18515 }
18516 it->multibyte_p = saved_multibyte_p;
18517 }
18518 else if (it->what == IT_COMPOSITION)
18519 {
18520 /* Note: A composition is represented as one glyph in the
18521 glyph matrix. There are no padding glyphs. */
18522 XChar2b char2b;
18523 XFontStruct *font;
18524 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18525 XCharStruct *pcm;
18526 int font_not_found_p;
18527 struct font_info *font_info;
18528 int boff; /* baseline offset */
18529 struct composition *cmp = composition_table[it->cmp_id];
18530
18531 /* Maybe translate single-byte characters to multibyte. */
18532 it->char_to_display = it->c;
18533 if (unibyte_display_via_language_environment
18534 && SINGLE_BYTE_CHAR_P (it->c)
18535 && (it->c >= 0240
18536 || (it->c >= 0200
18537 && !NILP (Vnonascii_translation_table))))
18538 {
18539 it->char_to_display = unibyte_char_to_multibyte (it->c);
18540 }
18541
18542 /* Get face and font to use. Encode IT->char_to_display. */
18543 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18544 face = FACE_FROM_ID (it->f, it->face_id);
18545 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18546 &char2b, it->multibyte_p, 0);
18547 font = face->font;
18548
18549 /* When no suitable font found, use the default font. */
18550 font_not_found_p = font == NULL;
18551 if (font_not_found_p)
18552 {
18553 font = FRAME_FONT (it->f);
18554 boff = FRAME_BASELINE_OFFSET (it->f);
18555 font_info = NULL;
18556 }
18557 else
18558 {
18559 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18560 boff = font_info->baseline_offset;
18561 if (font_info->vertical_centering)
18562 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18563 }
18564
18565 /* There are no padding glyphs, so there is only one glyph to
18566 produce for the composition. Important is that pixel_width,
18567 ascent and descent are the values of what is drawn by
18568 draw_glyphs (i.e. the values of the overall glyphs composed). */
18569 it->nglyphs = 1;
18570
18571 /* If we have not yet calculated pixel size data of glyphs of
18572 the composition for the current face font, calculate them
18573 now. Theoretically, we have to check all fonts for the
18574 glyphs, but that requires much time and memory space. So,
18575 here we check only the font of the first glyph. This leads
18576 to incorrect display very rarely, and C-l (recenter) can
18577 correct the display anyway. */
18578 if (cmp->font != (void *) font)
18579 {
18580 /* Ascent and descent of the font of the first character of
18581 this composition (adjusted by baseline offset). Ascent
18582 and descent of overall glyphs should not be less than
18583 them respectively. */
18584 int font_ascent = FONT_BASE (font) + boff;
18585 int font_descent = FONT_DESCENT (font) - boff;
18586 /* Bounding box of the overall glyphs. */
18587 int leftmost, rightmost, lowest, highest;
18588 int i, width, ascent, descent;
18589
18590 cmp->font = (void *) font;
18591
18592 /* Initialize the bounding box. */
18593 if (font_info
18594 && (pcm = rif->per_char_metric (font, &char2b,
18595 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
18596 {
18597 width = pcm->width;
18598 ascent = pcm->ascent;
18599 descent = pcm->descent;
18600 }
18601 else
18602 {
18603 width = FONT_WIDTH (font);
18604 ascent = FONT_BASE (font);
18605 descent = FONT_DESCENT (font);
18606 }
18607
18608 rightmost = width;
18609 lowest = - descent + boff;
18610 highest = ascent + boff;
18611 leftmost = 0;
18612
18613 if (font_info
18614 && font_info->default_ascent
18615 && CHAR_TABLE_P (Vuse_default_ascent)
18616 && !NILP (Faref (Vuse_default_ascent,
18617 make_number (it->char_to_display))))
18618 highest = font_info->default_ascent + boff;
18619
18620 /* Draw the first glyph at the normal position. It may be
18621 shifted to right later if some other glyphs are drawn at
18622 the left. */
18623 cmp->offsets[0] = 0;
18624 cmp->offsets[1] = boff;
18625
18626 /* Set cmp->offsets for the remaining glyphs. */
18627 for (i = 1; i < cmp->glyph_len; i++)
18628 {
18629 int left, right, btm, top;
18630 int ch = COMPOSITION_GLYPH (cmp, i);
18631 int face_id = FACE_FOR_CHAR (it->f, face, ch);
18632
18633 face = FACE_FROM_ID (it->f, face_id);
18634 get_char_face_and_encoding (it->f, ch, face->id,
18635 &char2b, it->multibyte_p, 0);
18636 font = face->font;
18637 if (font == NULL)
18638 {
18639 font = FRAME_FONT (it->f);
18640 boff = FRAME_BASELINE_OFFSET (it->f);
18641 font_info = NULL;
18642 }
18643 else
18644 {
18645 font_info
18646 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18647 boff = font_info->baseline_offset;
18648 if (font_info->vertical_centering)
18649 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18650 }
18651
18652 if (font_info
18653 && (pcm = rif->per_char_metric (font, &char2b,
18654 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
18655 {
18656 width = pcm->width;
18657 ascent = pcm->ascent;
18658 descent = pcm->descent;
18659 }
18660 else
18661 {
18662 width = FONT_WIDTH (font);
18663 ascent = 1;
18664 descent = 0;
18665 }
18666
18667 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
18668 {
18669 /* Relative composition with or without
18670 alternate chars. */
18671 left = (leftmost + rightmost - width) / 2;
18672 btm = - descent + boff;
18673 if (font_info && font_info->relative_compose
18674 && (! CHAR_TABLE_P (Vignore_relative_composition)
18675 || NILP (Faref (Vignore_relative_composition,
18676 make_number (ch)))))
18677 {
18678
18679 if (- descent >= font_info->relative_compose)
18680 /* One extra pixel between two glyphs. */
18681 btm = highest + 1;
18682 else if (ascent <= 0)
18683 /* One extra pixel between two glyphs. */
18684 btm = lowest - 1 - ascent - descent;
18685 }
18686 }
18687 else
18688 {
18689 /* A composition rule is specified by an integer
18690 value that encodes global and new reference
18691 points (GREF and NREF). GREF and NREF are
18692 specified by numbers as below:
18693
18694 0---1---2 -- ascent
18695 | |
18696 | |
18697 | |
18698 9--10--11 -- center
18699 | |
18700 ---3---4---5--- baseline
18701 | |
18702 6---7---8 -- descent
18703 */
18704 int rule = COMPOSITION_RULE (cmp, i);
18705 int gref, nref, grefx, grefy, nrefx, nrefy;
18706
18707 COMPOSITION_DECODE_RULE (rule, gref, nref);
18708 grefx = gref % 3, nrefx = nref % 3;
18709 grefy = gref / 3, nrefy = nref / 3;
18710
18711 left = (leftmost
18712 + grefx * (rightmost - leftmost) / 2
18713 - nrefx * width / 2);
18714 btm = ((grefy == 0 ? highest
18715 : grefy == 1 ? 0
18716 : grefy == 2 ? lowest
18717 : (highest + lowest) / 2)
18718 - (nrefy == 0 ? ascent + descent
18719 : nrefy == 1 ? descent - boff
18720 : nrefy == 2 ? 0
18721 : (ascent + descent) / 2));
18722 }
18723
18724 cmp->offsets[i * 2] = left;
18725 cmp->offsets[i * 2 + 1] = btm + descent;
18726
18727 /* Update the bounding box of the overall glyphs. */
18728 right = left + width;
18729 top = btm + descent + ascent;
18730 if (left < leftmost)
18731 leftmost = left;
18732 if (right > rightmost)
18733 rightmost = right;
18734 if (top > highest)
18735 highest = top;
18736 if (btm < lowest)
18737 lowest = btm;
18738 }
18739
18740 /* If there are glyphs whose x-offsets are negative,
18741 shift all glyphs to the right and make all x-offsets
18742 non-negative. */
18743 if (leftmost < 0)
18744 {
18745 for (i = 0; i < cmp->glyph_len; i++)
18746 cmp->offsets[i * 2] -= leftmost;
18747 rightmost -= leftmost;
18748 }
18749
18750 cmp->pixel_width = rightmost;
18751 cmp->ascent = highest;
18752 cmp->descent = - lowest;
18753 if (cmp->ascent < font_ascent)
18754 cmp->ascent = font_ascent;
18755 if (cmp->descent < font_descent)
18756 cmp->descent = font_descent;
18757 }
18758
18759 it->pixel_width = cmp->pixel_width;
18760 it->ascent = it->phys_ascent = cmp->ascent;
18761 it->descent = it->phys_descent = cmp->descent;
18762
18763 if (face->box != FACE_NO_BOX)
18764 {
18765 int thick = face->box_line_width;
18766
18767 if (thick > 0)
18768 {
18769 it->ascent += thick;
18770 it->descent += thick;
18771 }
18772 else
18773 thick = - thick;
18774
18775 if (it->start_of_box_run_p)
18776 it->pixel_width += thick;
18777 if (it->end_of_box_run_p)
18778 it->pixel_width += thick;
18779 }
18780
18781 /* If face has an overline, add the height of the overline
18782 (1 pixel) and a 1 pixel margin to the character height. */
18783 if (face->overline_p)
18784 it->ascent += 2;
18785
18786 take_vertical_position_into_account (it);
18787
18788 if (it->glyph_row)
18789 append_composite_glyph (it);
18790 }
18791 else if (it->what == IT_IMAGE)
18792 produce_image_glyph (it);
18793 else if (it->what == IT_STRETCH)
18794 produce_stretch_glyph (it);
18795
18796 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18797 because this isn't true for images with `:ascent 100'. */
18798 xassert (it->ascent >= 0 && it->descent >= 0);
18799 if (it->area == TEXT_AREA)
18800 it->current_x += it->pixel_width;
18801
18802 it->descent += it->extra_line_spacing;
18803
18804 it->max_ascent = max (it->max_ascent, it->ascent);
18805 it->max_descent = max (it->max_descent, it->descent);
18806 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
18807 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
18808 }
18809
18810 /* EXPORT for RIF:
18811 Output LEN glyphs starting at START at the nominal cursor position.
18812 Advance the nominal cursor over the text. The global variable
18813 updated_window contains the window being updated, updated_row is
18814 the glyph row being updated, and updated_area is the area of that
18815 row being updated. */
18816
18817 void
18818 x_write_glyphs (start, len)
18819 struct glyph *start;
18820 int len;
18821 {
18822 int x, hpos;
18823
18824 xassert (updated_window && updated_row);
18825 BLOCK_INPUT;
18826
18827 /* Write glyphs. */
18828
18829 hpos = start - updated_row->glyphs[updated_area];
18830 x = draw_glyphs (updated_window, output_cursor.x,
18831 updated_row, updated_area,
18832 hpos, hpos + len,
18833 DRAW_NORMAL_TEXT, 0);
18834
18835 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18836 if (updated_area == TEXT_AREA
18837 && updated_window->phys_cursor_on_p
18838 && updated_window->phys_cursor.vpos == output_cursor.vpos
18839 && updated_window->phys_cursor.hpos >= hpos
18840 && updated_window->phys_cursor.hpos < hpos + len)
18841 updated_window->phys_cursor_on_p = 0;
18842
18843 UNBLOCK_INPUT;
18844
18845 /* Advance the output cursor. */
18846 output_cursor.hpos += len;
18847 output_cursor.x = x;
18848 }
18849
18850
18851 /* EXPORT for RIF:
18852 Insert LEN glyphs from START at the nominal cursor position. */
18853
18854 void
18855 x_insert_glyphs (start, len)
18856 struct glyph *start;
18857 int len;
18858 {
18859 struct frame *f;
18860 struct window *w;
18861 int line_height, shift_by_width, shifted_region_width;
18862 struct glyph_row *row;
18863 struct glyph *glyph;
18864 int frame_x, frame_y, hpos;
18865
18866 xassert (updated_window && updated_row);
18867 BLOCK_INPUT;
18868 w = updated_window;
18869 f = XFRAME (WINDOW_FRAME (w));
18870
18871 /* Get the height of the line we are in. */
18872 row = updated_row;
18873 line_height = row->height;
18874
18875 /* Get the width of the glyphs to insert. */
18876 shift_by_width = 0;
18877 for (glyph = start; glyph < start + len; ++glyph)
18878 shift_by_width += glyph->pixel_width;
18879
18880 /* Get the width of the region to shift right. */
18881 shifted_region_width = (window_box_width (w, updated_area)
18882 - output_cursor.x
18883 - shift_by_width);
18884
18885 /* Shift right. */
18886 frame_x = window_box_left (w, updated_area) + output_cursor.x;
18887 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
18888
18889 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
18890 line_height, shift_by_width);
18891
18892 /* Write the glyphs. */
18893 hpos = start - row->glyphs[updated_area];
18894 draw_glyphs (w, output_cursor.x, row, updated_area,
18895 hpos, hpos + len,
18896 DRAW_NORMAL_TEXT, 0);
18897
18898 /* Advance the output cursor. */
18899 output_cursor.hpos += len;
18900 output_cursor.x += shift_by_width;
18901 UNBLOCK_INPUT;
18902 }
18903
18904
18905 /* EXPORT for RIF:
18906 Erase the current text line from the nominal cursor position
18907 (inclusive) to pixel column TO_X (exclusive). The idea is that
18908 everything from TO_X onward is already erased.
18909
18910 TO_X is a pixel position relative to updated_area of
18911 updated_window. TO_X == -1 means clear to the end of this area. */
18912
18913 void
18914 x_clear_end_of_line (to_x)
18915 int to_x;
18916 {
18917 struct frame *f;
18918 struct window *w = updated_window;
18919 int max_x, min_y, max_y;
18920 int from_x, from_y, to_y;
18921
18922 xassert (updated_window && updated_row);
18923 f = XFRAME (w->frame);
18924
18925 if (updated_row->full_width_p)
18926 max_x = WINDOW_TOTAL_WIDTH (w);
18927 else
18928 max_x = window_box_width (w, updated_area);
18929 max_y = window_text_bottom_y (w);
18930
18931 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
18932 of window. For TO_X > 0, truncate to end of drawing area. */
18933 if (to_x == 0)
18934 return;
18935 else if (to_x < 0)
18936 to_x = max_x;
18937 else
18938 to_x = min (to_x, max_x);
18939
18940 to_y = min (max_y, output_cursor.y + updated_row->height);
18941
18942 /* Notice if the cursor will be cleared by this operation. */
18943 if (!updated_row->full_width_p)
18944 notice_overwritten_cursor (w, updated_area,
18945 output_cursor.x, -1,
18946 updated_row->y,
18947 MATRIX_ROW_BOTTOM_Y (updated_row));
18948
18949 from_x = output_cursor.x;
18950
18951 /* Translate to frame coordinates. */
18952 if (updated_row->full_width_p)
18953 {
18954 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
18955 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
18956 }
18957 else
18958 {
18959 int area_left = window_box_left (w, updated_area);
18960 from_x += area_left;
18961 to_x += area_left;
18962 }
18963
18964 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18965 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
18966 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
18967
18968 /* Prevent inadvertently clearing to end of the X window. */
18969 if (to_x > from_x && to_y > from_y)
18970 {
18971 BLOCK_INPUT;
18972 rif->clear_frame_area (f, from_x, from_y,
18973 to_x - from_x, to_y - from_y);
18974 UNBLOCK_INPUT;
18975 }
18976 }
18977
18978 #endif /* HAVE_WINDOW_SYSTEM */
18979
18980
18981 \f
18982 /***********************************************************************
18983 Cursor types
18984 ***********************************************************************/
18985
18986 /* Value is the internal representation of the specified cursor type
18987 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
18988 of the bar cursor. */
18989
18990 static enum text_cursor_kinds
18991 get_specified_cursor_type (arg, width)
18992 Lisp_Object arg;
18993 int *width;
18994 {
18995 enum text_cursor_kinds type;
18996
18997 if (NILP (arg))
18998 return NO_CURSOR;
18999
19000 if (EQ (arg, Qbox))
19001 return FILLED_BOX_CURSOR;
19002
19003 if (EQ (arg, Qhollow))
19004 return HOLLOW_BOX_CURSOR;
19005
19006 if (EQ (arg, Qbar))
19007 {
19008 *width = 2;
19009 return BAR_CURSOR;
19010 }
19011
19012 if (CONSP (arg)
19013 && EQ (XCAR (arg), Qbar)
19014 && INTEGERP (XCDR (arg))
19015 && XINT (XCDR (arg)) >= 0)
19016 {
19017 *width = XINT (XCDR (arg));
19018 return BAR_CURSOR;
19019 }
19020
19021 if (EQ (arg, Qhbar))
19022 {
19023 *width = 2;
19024 return HBAR_CURSOR;
19025 }
19026
19027 if (CONSP (arg)
19028 && EQ (XCAR (arg), Qhbar)
19029 && INTEGERP (XCDR (arg))
19030 && XINT (XCDR (arg)) >= 0)
19031 {
19032 *width = XINT (XCDR (arg));
19033 return HBAR_CURSOR;
19034 }
19035
19036 /* Treat anything unknown as "hollow box cursor".
19037 It was bad to signal an error; people have trouble fixing
19038 .Xdefaults with Emacs, when it has something bad in it. */
19039 type = HOLLOW_BOX_CURSOR;
19040
19041 return type;
19042 }
19043
19044 /* Set the default cursor types for specified frame. */
19045 void
19046 set_frame_cursor_types (f, arg)
19047 struct frame *f;
19048 Lisp_Object arg;
19049 {
19050 int width;
19051 Lisp_Object tem;
19052
19053 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19054 FRAME_CURSOR_WIDTH (f) = width;
19055
19056 /* By default, set up the blink-off state depending on the on-state. */
19057
19058 tem = Fassoc (arg, Vblink_cursor_alist);
19059 if (!NILP (tem))
19060 {
19061 FRAME_BLINK_OFF_CURSOR (f)
19062 = get_specified_cursor_type (XCDR (tem), &width);
19063 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19064 }
19065 else
19066 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19067 }
19068
19069
19070 /* Return the cursor we want to be displayed in window W. Return
19071 width of bar/hbar cursor through WIDTH arg. Return with
19072 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19073 (i.e. if the `system caret' should track this cursor).
19074
19075 In a mini-buffer window, we want the cursor only to appear if we
19076 are reading input from this window. For the selected window, we
19077 want the cursor type given by the frame parameter or buffer local
19078 setting of cursor-type. If explicitly marked off, draw no cursor.
19079 In all other cases, we want a hollow box cursor. */
19080
19081 static enum text_cursor_kinds
19082 get_window_cursor_type (w, glyph, width, active_cursor)
19083 struct window *w;
19084 struct glyph *glyph;
19085 int *width;
19086 int *active_cursor;
19087 {
19088 struct frame *f = XFRAME (w->frame);
19089 struct buffer *b = XBUFFER (w->buffer);
19090 int cursor_type = DEFAULT_CURSOR;
19091 Lisp_Object alt_cursor;
19092 int non_selected = 0;
19093
19094 *active_cursor = 1;
19095
19096 /* Echo area */
19097 if (cursor_in_echo_area
19098 && FRAME_HAS_MINIBUF_P (f)
19099 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19100 {
19101 if (w == XWINDOW (echo_area_window))
19102 {
19103 *width = FRAME_CURSOR_WIDTH (f);
19104 return FRAME_DESIRED_CURSOR (f);
19105 }
19106
19107 *active_cursor = 0;
19108 non_selected = 1;
19109 }
19110
19111 /* Nonselected window or nonselected frame. */
19112 else if (w != XWINDOW (f->selected_window)
19113 #ifdef HAVE_WINDOW_SYSTEM
19114 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19115 #endif
19116 )
19117 {
19118 *active_cursor = 0;
19119
19120 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19121 return NO_CURSOR;
19122
19123 non_selected = 1;
19124 }
19125
19126 /* Never display a cursor in a window in which cursor-type is nil. */
19127 if (NILP (b->cursor_type))
19128 return NO_CURSOR;
19129
19130 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19131 if (non_selected)
19132 {
19133 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19134 return get_specified_cursor_type (alt_cursor, width);
19135 }
19136
19137 /* Get the normal cursor type for this window. */
19138 if (EQ (b->cursor_type, Qt))
19139 {
19140 cursor_type = FRAME_DESIRED_CURSOR (f);
19141 *width = FRAME_CURSOR_WIDTH (f);
19142 }
19143 else
19144 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19145
19146 /* Use normal cursor if not blinked off. */
19147 if (!w->cursor_off_p)
19148 {
19149 if (glyph->type == IMAGE_GLYPH) {
19150 if (cursor_type == FILLED_BOX_CURSOR)
19151 cursor_type = HOLLOW_BOX_CURSOR;
19152 }
19153 return cursor_type;
19154 }
19155
19156 /* Cursor is blinked off, so determine how to "toggle" it. */
19157
19158 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19159 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19160 return get_specified_cursor_type (XCDR (alt_cursor), width);
19161
19162 /* Then see if frame has specified a specific blink off cursor type. */
19163 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19164 {
19165 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19166 return FRAME_BLINK_OFF_CURSOR (f);
19167 }
19168
19169 #if 0
19170 /* Some people liked having a permanently visible blinking cursor,
19171 while others had very strong opinions against it. So it was
19172 decided to remove it. KFS 2003-09-03 */
19173
19174 /* Finally perform built-in cursor blinking:
19175 filled box <-> hollow box
19176 wide [h]bar <-> narrow [h]bar
19177 narrow [h]bar <-> no cursor
19178 other type <-> no cursor */
19179
19180 if (cursor_type == FILLED_BOX_CURSOR)
19181 return HOLLOW_BOX_CURSOR;
19182
19183 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19184 {
19185 *width = 1;
19186 return cursor_type;
19187 }
19188 #endif
19189
19190 return NO_CURSOR;
19191 }
19192
19193
19194 #ifdef HAVE_WINDOW_SYSTEM
19195
19196 /* Notice when the text cursor of window W has been completely
19197 overwritten by a drawing operation that outputs glyphs in AREA
19198 starting at X0 and ending at X1 in the line starting at Y0 and
19199 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19200 the rest of the line after X0 has been written. Y coordinates
19201 are window-relative. */
19202
19203 static void
19204 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19205 struct window *w;
19206 enum glyph_row_area area;
19207 int x0, y0, x1, y1;
19208 {
19209 if (area == TEXT_AREA && w->phys_cursor_on_p)
19210 {
19211 int cx0 = w->phys_cursor.x;
19212 int cx1 = cx0 + w->phys_cursor_width;
19213 int cy0 = w->phys_cursor.y;
19214 int cy1 = cy0 + w->phys_cursor_height;
19215
19216 if (x0 <= cx0 && (x1 < 0 || x1 >= cx1))
19217 {
19218 /* The cursor image will be completely removed from the
19219 screen if the output area intersects the cursor area in
19220 y-direction. When we draw in [y0 y1[, and some part of
19221 the cursor is at y < y0, that part must have been drawn
19222 before. When scrolling, the cursor is erased before
19223 actually scrolling, so we don't come here. When not
19224 scrolling, the rows above the old cursor row must have
19225 changed, and in this case these rows must have written
19226 over the cursor image.
19227
19228 Likewise if part of the cursor is below y1, with the
19229 exception of the cursor being in the first blank row at
19230 the buffer and window end because update_text_area
19231 doesn't draw that row. (Except when it does, but
19232 that's handled in update_text_area.) */
19233
19234 if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1))
19235 && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p)
19236 w->phys_cursor_on_p = 0;
19237 }
19238 }
19239 }
19240
19241 #endif /* HAVE_WINDOW_SYSTEM */
19242
19243 \f
19244 /************************************************************************
19245 Mouse Face
19246 ************************************************************************/
19247
19248 #ifdef HAVE_WINDOW_SYSTEM
19249
19250 /* EXPORT for RIF:
19251 Fix the display of area AREA of overlapping row ROW in window W. */
19252
19253 void
19254 x_fix_overlapping_area (w, row, area)
19255 struct window *w;
19256 struct glyph_row *row;
19257 enum glyph_row_area area;
19258 {
19259 int i, x;
19260
19261 BLOCK_INPUT;
19262
19263 x = 0;
19264 for (i = 0; i < row->used[area];)
19265 {
19266 if (row->glyphs[area][i].overlaps_vertically_p)
19267 {
19268 int start = i, start_x = x;
19269
19270 do
19271 {
19272 x += row->glyphs[area][i].pixel_width;
19273 ++i;
19274 }
19275 while (i < row->used[area]
19276 && row->glyphs[area][i].overlaps_vertically_p);
19277
19278 draw_glyphs (w, start_x, row, area,
19279 start, i,
19280 DRAW_NORMAL_TEXT, 1);
19281 }
19282 else
19283 {
19284 x += row->glyphs[area][i].pixel_width;
19285 ++i;
19286 }
19287 }
19288
19289 UNBLOCK_INPUT;
19290 }
19291
19292
19293 /* EXPORT:
19294 Draw the cursor glyph of window W in glyph row ROW. See the
19295 comment of draw_glyphs for the meaning of HL. */
19296
19297 void
19298 draw_phys_cursor_glyph (w, row, hl)
19299 struct window *w;
19300 struct glyph_row *row;
19301 enum draw_glyphs_face hl;
19302 {
19303 /* If cursor hpos is out of bounds, don't draw garbage. This can
19304 happen in mini-buffer windows when switching between echo area
19305 glyphs and mini-buffer. */
19306 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19307 {
19308 int on_p = w->phys_cursor_on_p;
19309 int x1;
19310 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19311 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19312 hl, 0);
19313 w->phys_cursor_on_p = on_p;
19314
19315 if (hl == DRAW_CURSOR)
19316 w->phys_cursor_width = x1 - w->phys_cursor.x;
19317 /* When we erase the cursor, and ROW is overlapped by other
19318 rows, make sure that these overlapping parts of other rows
19319 are redrawn. */
19320 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19321 {
19322 if (row > w->current_matrix->rows
19323 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19324 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19325
19326 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19327 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19328 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19329 }
19330 }
19331 }
19332
19333
19334 /* EXPORT:
19335 Erase the image of a cursor of window W from the screen. */
19336
19337 void
19338 erase_phys_cursor (w)
19339 struct window *w;
19340 {
19341 struct frame *f = XFRAME (w->frame);
19342 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19343 int hpos = w->phys_cursor.hpos;
19344 int vpos = w->phys_cursor.vpos;
19345 int mouse_face_here_p = 0;
19346 struct glyph_matrix *active_glyphs = w->current_matrix;
19347 struct glyph_row *cursor_row;
19348 struct glyph *cursor_glyph;
19349 enum draw_glyphs_face hl;
19350
19351 /* No cursor displayed or row invalidated => nothing to do on the
19352 screen. */
19353 if (w->phys_cursor_type == NO_CURSOR)
19354 goto mark_cursor_off;
19355
19356 /* VPOS >= active_glyphs->nrows means that window has been resized.
19357 Don't bother to erase the cursor. */
19358 if (vpos >= active_glyphs->nrows)
19359 goto mark_cursor_off;
19360
19361 /* If row containing cursor is marked invalid, there is nothing we
19362 can do. */
19363 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19364 if (!cursor_row->enabled_p)
19365 goto mark_cursor_off;
19366
19367 /* If row is completely invisible, don't attempt to delete a cursor which
19368 isn't there. This can happen if cursor is at top of a window, and
19369 we switch to a buffer with a header line in that window. */
19370 if (cursor_row->visible_height <= 0)
19371 goto mark_cursor_off;
19372
19373 /* This can happen when the new row is shorter than the old one.
19374 In this case, either draw_glyphs or clear_end_of_line
19375 should have cleared the cursor. Note that we wouldn't be
19376 able to erase the cursor in this case because we don't have a
19377 cursor glyph at hand. */
19378 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19379 goto mark_cursor_off;
19380
19381 /* If the cursor is in the mouse face area, redisplay that when
19382 we clear the cursor. */
19383 if (! NILP (dpyinfo->mouse_face_window)
19384 && w == XWINDOW (dpyinfo->mouse_face_window)
19385 && (vpos > dpyinfo->mouse_face_beg_row
19386 || (vpos == dpyinfo->mouse_face_beg_row
19387 && hpos >= dpyinfo->mouse_face_beg_col))
19388 && (vpos < dpyinfo->mouse_face_end_row
19389 || (vpos == dpyinfo->mouse_face_end_row
19390 && hpos < dpyinfo->mouse_face_end_col))
19391 /* Don't redraw the cursor's spot in mouse face if it is at the
19392 end of a line (on a newline). The cursor appears there, but
19393 mouse highlighting does not. */
19394 && cursor_row->used[TEXT_AREA] > hpos)
19395 mouse_face_here_p = 1;
19396
19397 /* Maybe clear the display under the cursor. */
19398 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19399 {
19400 int x, y;
19401 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
19402
19403 cursor_glyph = get_phys_cursor_glyph (w);
19404 if (cursor_glyph == NULL)
19405 goto mark_cursor_off;
19406
19407 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
19408 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
19409
19410 rif->clear_frame_area (f, x, y,
19411 cursor_glyph->pixel_width, cursor_row->visible_height);
19412 }
19413
19414 /* Erase the cursor by redrawing the character underneath it. */
19415 if (mouse_face_here_p)
19416 hl = DRAW_MOUSE_FACE;
19417 else
19418 hl = DRAW_NORMAL_TEXT;
19419 draw_phys_cursor_glyph (w, cursor_row, hl);
19420
19421 mark_cursor_off:
19422 w->phys_cursor_on_p = 0;
19423 w->phys_cursor_type = NO_CURSOR;
19424 }
19425
19426
19427 /* EXPORT:
19428 Display or clear cursor of window W. If ON is zero, clear the
19429 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19430 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19431
19432 void
19433 display_and_set_cursor (w, on, hpos, vpos, x, y)
19434 struct window *w;
19435 int on, hpos, vpos, x, y;
19436 {
19437 struct frame *f = XFRAME (w->frame);
19438 int new_cursor_type;
19439 int new_cursor_width;
19440 int active_cursor;
19441 struct glyph_matrix *current_glyphs;
19442 struct glyph_row *glyph_row;
19443 struct glyph *glyph;
19444
19445 /* This is pointless on invisible frames, and dangerous on garbaged
19446 windows and frames; in the latter case, the frame or window may
19447 be in the midst of changing its size, and x and y may be off the
19448 window. */
19449 if (! FRAME_VISIBLE_P (f)
19450 || FRAME_GARBAGED_P (f)
19451 || vpos >= w->current_matrix->nrows
19452 || hpos >= w->current_matrix->matrix_w)
19453 return;
19454
19455 /* If cursor is off and we want it off, return quickly. */
19456 if (!on && !w->phys_cursor_on_p)
19457 return;
19458
19459 current_glyphs = w->current_matrix;
19460 glyph_row = MATRIX_ROW (current_glyphs, vpos);
19461 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
19462
19463 /* If cursor row is not enabled, we don't really know where to
19464 display the cursor. */
19465 if (!glyph_row->enabled_p)
19466 {
19467 w->phys_cursor_on_p = 0;
19468 return;
19469 }
19470
19471 xassert (interrupt_input_blocked);
19472
19473 /* Set new_cursor_type to the cursor we want to be displayed. */
19474 new_cursor_type = get_window_cursor_type (w, glyph,
19475 &new_cursor_width, &active_cursor);
19476
19477 /* If cursor is currently being shown and we don't want it to be or
19478 it is in the wrong place, or the cursor type is not what we want,
19479 erase it. */
19480 if (w->phys_cursor_on_p
19481 && (!on
19482 || w->phys_cursor.x != x
19483 || w->phys_cursor.y != y
19484 || new_cursor_type != w->phys_cursor_type
19485 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19486 && new_cursor_width != w->phys_cursor_width)))
19487 erase_phys_cursor (w);
19488
19489 /* Don't check phys_cursor_on_p here because that flag is only set
19490 to zero in some cases where we know that the cursor has been
19491 completely erased, to avoid the extra work of erasing the cursor
19492 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19493 still not be visible, or it has only been partly erased. */
19494 if (on)
19495 {
19496 w->phys_cursor_ascent = glyph_row->ascent;
19497 w->phys_cursor_height = glyph_row->height;
19498
19499 /* Set phys_cursor_.* before x_draw_.* is called because some
19500 of them may need the information. */
19501 w->phys_cursor.x = x;
19502 w->phys_cursor.y = glyph_row->y;
19503 w->phys_cursor.hpos = hpos;
19504 w->phys_cursor.vpos = vpos;
19505 }
19506
19507 rif->draw_window_cursor (w, glyph_row, x, y,
19508 new_cursor_type, new_cursor_width,
19509 on, active_cursor);
19510 }
19511
19512
19513 /* Switch the display of W's cursor on or off, according to the value
19514 of ON. */
19515
19516 static void
19517 update_window_cursor (w, on)
19518 struct window *w;
19519 int on;
19520 {
19521 /* Don't update cursor in windows whose frame is in the process
19522 of being deleted. */
19523 if (w->current_matrix)
19524 {
19525 BLOCK_INPUT;
19526 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
19527 w->phys_cursor.x, w->phys_cursor.y);
19528 UNBLOCK_INPUT;
19529 }
19530 }
19531
19532
19533 /* Call update_window_cursor with parameter ON_P on all leaf windows
19534 in the window tree rooted at W. */
19535
19536 static void
19537 update_cursor_in_window_tree (w, on_p)
19538 struct window *w;
19539 int on_p;
19540 {
19541 while (w)
19542 {
19543 if (!NILP (w->hchild))
19544 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
19545 else if (!NILP (w->vchild))
19546 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
19547 else
19548 update_window_cursor (w, on_p);
19549
19550 w = NILP (w->next) ? 0 : XWINDOW (w->next);
19551 }
19552 }
19553
19554
19555 /* EXPORT:
19556 Display the cursor on window W, or clear it, according to ON_P.
19557 Don't change the cursor's position. */
19558
19559 void
19560 x_update_cursor (f, on_p)
19561 struct frame *f;
19562 int on_p;
19563 {
19564 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
19565 }
19566
19567
19568 /* EXPORT:
19569 Clear the cursor of window W to background color, and mark the
19570 cursor as not shown. This is used when the text where the cursor
19571 is is about to be rewritten. */
19572
19573 void
19574 x_clear_cursor (w)
19575 struct window *w;
19576 {
19577 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
19578 update_window_cursor (w, 0);
19579 }
19580
19581
19582 /* EXPORT:
19583 Display the active region described by mouse_face_* according to DRAW. */
19584
19585 void
19586 show_mouse_face (dpyinfo, draw)
19587 Display_Info *dpyinfo;
19588 enum draw_glyphs_face draw;
19589 {
19590 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
19591 struct frame *f = XFRAME (WINDOW_FRAME (w));
19592
19593 if (/* If window is in the process of being destroyed, don't bother
19594 to do anything. */
19595 w->current_matrix != NULL
19596 /* Don't update mouse highlight if hidden */
19597 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
19598 /* Recognize when we are called to operate on rows that don't exist
19599 anymore. This can happen when a window is split. */
19600 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
19601 {
19602 int phys_cursor_on_p = w->phys_cursor_on_p;
19603 struct glyph_row *row, *first, *last;
19604
19605 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
19606 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
19607
19608 for (row = first; row <= last && row->enabled_p; ++row)
19609 {
19610 int start_hpos, end_hpos, start_x;
19611
19612 /* For all but the first row, the highlight starts at column 0. */
19613 if (row == first)
19614 {
19615 start_hpos = dpyinfo->mouse_face_beg_col;
19616 start_x = dpyinfo->mouse_face_beg_x;
19617 }
19618 else
19619 {
19620 start_hpos = 0;
19621 start_x = 0;
19622 }
19623
19624 if (row == last)
19625 end_hpos = dpyinfo->mouse_face_end_col;
19626 else
19627 end_hpos = row->used[TEXT_AREA];
19628
19629 if (end_hpos > start_hpos)
19630 {
19631 draw_glyphs (w, start_x, row, TEXT_AREA,
19632 start_hpos, end_hpos,
19633 draw, 0);
19634
19635 row->mouse_face_p
19636 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
19637 }
19638 }
19639
19640 /* When we've written over the cursor, arrange for it to
19641 be displayed again. */
19642 if (phys_cursor_on_p && !w->phys_cursor_on_p)
19643 {
19644 BLOCK_INPUT;
19645 display_and_set_cursor (w, 1,
19646 w->phys_cursor.hpos, w->phys_cursor.vpos,
19647 w->phys_cursor.x, w->phys_cursor.y);
19648 UNBLOCK_INPUT;
19649 }
19650 }
19651
19652 /* Change the mouse cursor. */
19653 if (draw == DRAW_NORMAL_TEXT)
19654 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
19655 else if (draw == DRAW_MOUSE_FACE)
19656 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
19657 else
19658 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
19659 }
19660
19661 /* EXPORT:
19662 Clear out the mouse-highlighted active region.
19663 Redraw it un-highlighted first. Value is non-zero if mouse
19664 face was actually drawn unhighlighted. */
19665
19666 int
19667 clear_mouse_face (dpyinfo)
19668 Display_Info *dpyinfo;
19669 {
19670 int cleared = 0;
19671
19672 if (!NILP (dpyinfo->mouse_face_window))
19673 {
19674 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
19675 cleared = 1;
19676 }
19677
19678 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
19679 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
19680 dpyinfo->mouse_face_window = Qnil;
19681 dpyinfo->mouse_face_overlay = Qnil;
19682 return cleared;
19683 }
19684
19685
19686 /* EXPORT:
19687 Non-zero if physical cursor of window W is within mouse face. */
19688
19689 int
19690 cursor_in_mouse_face_p (w)
19691 struct window *w;
19692 {
19693 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
19694 int in_mouse_face = 0;
19695
19696 if (WINDOWP (dpyinfo->mouse_face_window)
19697 && XWINDOW (dpyinfo->mouse_face_window) == w)
19698 {
19699 int hpos = w->phys_cursor.hpos;
19700 int vpos = w->phys_cursor.vpos;
19701
19702 if (vpos >= dpyinfo->mouse_face_beg_row
19703 && vpos <= dpyinfo->mouse_face_end_row
19704 && (vpos > dpyinfo->mouse_face_beg_row
19705 || hpos >= dpyinfo->mouse_face_beg_col)
19706 && (vpos < dpyinfo->mouse_face_end_row
19707 || hpos < dpyinfo->mouse_face_end_col
19708 || dpyinfo->mouse_face_past_end))
19709 in_mouse_face = 1;
19710 }
19711
19712 return in_mouse_face;
19713 }
19714
19715
19716
19717 \f
19718 /* Find the glyph matrix position of buffer position CHARPOS in window
19719 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19720 current glyphs must be up to date. If CHARPOS is above window
19721 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19722 of last line in W. In the row containing CHARPOS, stop before glyphs
19723 having STOP as object. */
19724
19725 #if 1 /* This is a version of fast_find_position that's more correct
19726 in the presence of hscrolling, for example. I didn't install
19727 it right away because the problem fixed is minor, it failed
19728 in 20.x as well, and I think it's too risky to install
19729 so near the release of 21.1. 2001-09-25 gerd. */
19730
19731 static int
19732 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
19733 struct window *w;
19734 int charpos;
19735 int *hpos, *vpos, *x, *y;
19736 Lisp_Object stop;
19737 {
19738 struct glyph_row *row, *first;
19739 struct glyph *glyph, *end;
19740 int past_end = 0;
19741
19742 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19743 row = row_containing_pos (w, charpos, first, NULL, 0);
19744 if (row == NULL)
19745 {
19746 if (charpos < MATRIX_ROW_START_CHARPOS (first))
19747 {
19748 *x = *y = *hpos = *vpos = 0;
19749 return 0;
19750 }
19751 else
19752 {
19753 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
19754 past_end = 1;
19755 }
19756 }
19757
19758 *x = row->x;
19759 *y = row->y;
19760 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19761
19762 glyph = row->glyphs[TEXT_AREA];
19763 end = glyph + row->used[TEXT_AREA];
19764
19765 /* Skip over glyphs not having an object at the start of the row.
19766 These are special glyphs like truncation marks on terminal
19767 frames. */
19768 if (row->displays_text_p)
19769 while (glyph < end
19770 && INTEGERP (glyph->object)
19771 && !EQ (stop, glyph->object)
19772 && glyph->charpos < 0)
19773 {
19774 *x += glyph->pixel_width;
19775 ++glyph;
19776 }
19777
19778 while (glyph < end
19779 && !INTEGERP (glyph->object)
19780 && !EQ (stop, glyph->object)
19781 && (!BUFFERP (glyph->object)
19782 || glyph->charpos < charpos))
19783 {
19784 *x += glyph->pixel_width;
19785 ++glyph;
19786 }
19787
19788 *hpos = glyph - row->glyphs[TEXT_AREA];
19789 return past_end;
19790 }
19791
19792 #else /* not 1 */
19793
19794 static int
19795 fast_find_position (w, pos, hpos, vpos, x, y, stop)
19796 struct window *w;
19797 int pos;
19798 int *hpos, *vpos, *x, *y;
19799 Lisp_Object stop;
19800 {
19801 int i;
19802 int lastcol;
19803 int maybe_next_line_p = 0;
19804 int line_start_position;
19805 int yb = window_text_bottom_y (w);
19806 struct glyph_row *row, *best_row;
19807 int row_vpos, best_row_vpos;
19808 int current_x;
19809
19810 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19811 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19812
19813 while (row->y < yb)
19814 {
19815 if (row->used[TEXT_AREA])
19816 line_start_position = row->glyphs[TEXT_AREA]->charpos;
19817 else
19818 line_start_position = 0;
19819
19820 if (line_start_position > pos)
19821 break;
19822 /* If the position sought is the end of the buffer,
19823 don't include the blank lines at the bottom of the window. */
19824 else if (line_start_position == pos
19825 && pos == BUF_ZV (XBUFFER (w->buffer)))
19826 {
19827 maybe_next_line_p = 1;
19828 break;
19829 }
19830 else if (line_start_position > 0)
19831 {
19832 best_row = row;
19833 best_row_vpos = row_vpos;
19834 }
19835
19836 if (row->y + row->height >= yb)
19837 break;
19838
19839 ++row;
19840 ++row_vpos;
19841 }
19842
19843 /* Find the right column within BEST_ROW. */
19844 lastcol = 0;
19845 current_x = best_row->x;
19846 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
19847 {
19848 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
19849 int charpos = glyph->charpos;
19850
19851 if (BUFFERP (glyph->object))
19852 {
19853 if (charpos == pos)
19854 {
19855 *hpos = i;
19856 *vpos = best_row_vpos;
19857 *x = current_x;
19858 *y = best_row->y;
19859 return 1;
19860 }
19861 else if (charpos > pos)
19862 break;
19863 }
19864 else if (EQ (glyph->object, stop))
19865 break;
19866
19867 if (charpos > 0)
19868 lastcol = i;
19869 current_x += glyph->pixel_width;
19870 }
19871
19872 /* If we're looking for the end of the buffer,
19873 and we didn't find it in the line we scanned,
19874 use the start of the following line. */
19875 if (maybe_next_line_p)
19876 {
19877 ++best_row;
19878 ++best_row_vpos;
19879 lastcol = 0;
19880 current_x = best_row->x;
19881 }
19882
19883 *vpos = best_row_vpos;
19884 *hpos = lastcol + 1;
19885 *x = current_x;
19886 *y = best_row->y;
19887 return 0;
19888 }
19889
19890 #endif /* not 1 */
19891
19892
19893 /* Find the position of the glyph for position POS in OBJECT in
19894 window W's current matrix, and return in *X, *Y the pixel
19895 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
19896
19897 RIGHT_P non-zero means return the position of the right edge of the
19898 glyph, RIGHT_P zero means return the left edge position.
19899
19900 If no glyph for POS exists in the matrix, return the position of
19901 the glyph with the next smaller position that is in the matrix, if
19902 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
19903 exists in the matrix, return the position of the glyph with the
19904 next larger position in OBJECT.
19905
19906 Value is non-zero if a glyph was found. */
19907
19908 static int
19909 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
19910 struct window *w;
19911 int pos;
19912 Lisp_Object object;
19913 int *hpos, *vpos, *x, *y;
19914 int right_p;
19915 {
19916 int yb = window_text_bottom_y (w);
19917 struct glyph_row *r;
19918 struct glyph *best_glyph = NULL;
19919 struct glyph_row *best_row = NULL;
19920 int best_x = 0;
19921
19922 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19923 r->enabled_p && r->y < yb;
19924 ++r)
19925 {
19926 struct glyph *g = r->glyphs[TEXT_AREA];
19927 struct glyph *e = g + r->used[TEXT_AREA];
19928 int gx;
19929
19930 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
19931 if (EQ (g->object, object))
19932 {
19933 if (g->charpos == pos)
19934 {
19935 best_glyph = g;
19936 best_x = gx;
19937 best_row = r;
19938 goto found;
19939 }
19940 else if (best_glyph == NULL
19941 || ((abs (g->charpos - pos)
19942 < abs (best_glyph->charpos - pos))
19943 && (right_p
19944 ? g->charpos < pos
19945 : g->charpos > pos)))
19946 {
19947 best_glyph = g;
19948 best_x = gx;
19949 best_row = r;
19950 }
19951 }
19952 }
19953
19954 found:
19955
19956 if (best_glyph)
19957 {
19958 *x = best_x;
19959 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
19960
19961 if (right_p)
19962 {
19963 *x += best_glyph->pixel_width;
19964 ++*hpos;
19965 }
19966
19967 *y = best_row->y;
19968 *vpos = best_row - w->current_matrix->rows;
19969 }
19970
19971 return best_glyph != NULL;
19972 }
19973
19974
19975 /* See if position X, Y is within a hot-spot of an image. */
19976
19977 static int
19978 on_hot_spot_p (hot_spot, x, y)
19979 Lisp_Object hot_spot;
19980 int x, y;
19981 {
19982 if (!CONSP (hot_spot))
19983 return 0;
19984
19985 if (EQ (XCAR (hot_spot), Qrect))
19986 {
19987 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
19988 Lisp_Object rect = XCDR (hot_spot);
19989 Lisp_Object tem;
19990 if (!CONSP (rect))
19991 return 0;
19992 if (!CONSP (XCAR (rect)))
19993 return 0;
19994 if (!CONSP (XCDR (rect)))
19995 return 0;
19996 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
19997 return 0;
19998 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
19999 return 0;
20000 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20001 return 0;
20002 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20003 return 0;
20004 return 1;
20005 }
20006 else if (EQ (XCAR (hot_spot), Qcircle))
20007 {
20008 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20009 Lisp_Object circ = XCDR (hot_spot);
20010 Lisp_Object lr, lx0, ly0;
20011 if (CONSP (circ)
20012 && CONSP (XCAR (circ))
20013 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20014 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20015 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20016 {
20017 double r = XFLOATINT (lr);
20018 double dx = XINT (lx0) - x;
20019 double dy = XINT (ly0) - y;
20020 return (dx * dx + dy * dy <= r * r);
20021 }
20022 }
20023 else if (EQ (XCAR (hot_spot), Qpoly))
20024 {
20025 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20026 if (VECTORP (XCDR (hot_spot)))
20027 {
20028 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20029 Lisp_Object *poly = v->contents;
20030 int n = v->size;
20031 int i;
20032 int inside = 0;
20033 Lisp_Object lx, ly;
20034 int x0, y0;
20035
20036 /* Need an even number of coordinates, and at least 3 edges. */
20037 if (n < 6 || n & 1)
20038 return 0;
20039
20040 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20041 If count is odd, we are inside polygon. Pixels on edges
20042 may or may not be included depending on actual geometry of the
20043 polygon. */
20044 if ((lx = poly[n-2], !INTEGERP (lx))
20045 || (ly = poly[n-1], !INTEGERP (lx)))
20046 return 0;
20047 x0 = XINT (lx), y0 = XINT (ly);
20048 for (i = 0; i < n; i += 2)
20049 {
20050 int x1 = x0, y1 = y0;
20051 if ((lx = poly[i], !INTEGERP (lx))
20052 || (ly = poly[i+1], !INTEGERP (ly)))
20053 return 0;
20054 x0 = XINT (lx), y0 = XINT (ly);
20055
20056 /* Does this segment cross the X line? */
20057 if (x0 >= x)
20058 {
20059 if (x1 >= x)
20060 continue;
20061 }
20062 else if (x1 < x)
20063 continue;
20064 if (y > y0 && y > y1)
20065 continue;
20066 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20067 inside = !inside;
20068 }
20069 return inside;
20070 }
20071 }
20072 else
20073 return 0;
20074 }
20075
20076 Lisp_Object
20077 find_hot_spot (map, x, y)
20078 Lisp_Object map;
20079 int x, y;
20080 {
20081 while (CONSP (map))
20082 {
20083 if (CONSP (XCAR (map))
20084 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20085 return XCAR (map);
20086 map = XCDR (map);
20087 }
20088
20089 return Qnil;
20090 }
20091
20092 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20093 3, 3, 0,
20094 doc: /* Lookup in image map MAP coordinates X and Y.
20095 An image map is an alist where each element has the format (AREA ID PLIST).
20096 An AREA is specified as either a rectangle, a circle, or a polygon:
20097 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20098 pixel coordinates of the upper left and bottom right corners.
20099 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20100 and the radius of the circle; r may be a float or integer.
20101 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20102 vector describes one corner in the polygon.
20103 Returns the alist element for the first matching AREA in MAP. */)
20104 (map, x, y)
20105 Lisp_Object map;
20106 Lisp_Object x, y;
20107 {
20108 int ix, iy;
20109 if (NILP (map))
20110 return Qnil;
20111
20112 if (!INTEGERP (x))
20113 wrong_type_argument (Qintegerp, x);
20114 if (!INTEGERP (y))
20115 wrong_type_argument (Qintegerp, y);
20116
20117 return find_hot_spot (map, XINT (x), XINT (y));
20118 }
20119
20120
20121 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20122 static void
20123 define_frame_cursor1 (f, cursor, pointer)
20124 struct frame *f;
20125 Cursor cursor;
20126 Lisp_Object pointer;
20127 {
20128 if (!NILP (pointer))
20129 {
20130 if (EQ (pointer, Qarrow))
20131 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20132 else if (EQ (pointer, Qhand))
20133 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20134 else if (EQ (pointer, Qtext))
20135 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20136 else if (EQ (pointer, intern ("hdrag")))
20137 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20138 #ifdef HAVE_X_WINDOWS
20139 else if (EQ (pointer, intern ("vdrag")))
20140 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20141 #endif
20142 else if (EQ (pointer, intern ("hourglass")))
20143 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20144 else if (EQ (pointer, Qmodeline))
20145 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20146 else
20147 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20148 }
20149
20150 #ifndef HAVE_CARBON
20151 if (cursor != No_Cursor)
20152 #else
20153 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20154 #endif
20155 rif->define_frame_cursor (f, cursor);
20156 }
20157
20158 /* Take proper action when mouse has moved to the mode or header line
20159 or marginal area AREA of window W, x-position X and y-position Y.
20160 X is relative to the start of the text display area of W, so the
20161 width of bitmap areas and scroll bars must be subtracted to get a
20162 position relative to the start of the mode line. */
20163
20164 static void
20165 note_mode_line_or_margin_highlight (w, x, y, area)
20166 struct window *w;
20167 int x, y;
20168 enum window_part area;
20169 {
20170 struct frame *f = XFRAME (w->frame);
20171 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20172 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20173 Lisp_Object pointer = Qnil;
20174 int charpos, dx, dy, width, height;
20175 Lisp_Object string, object = Qnil;
20176 Lisp_Object pos, help, image;
20177
20178 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20179 string = mode_line_string (w, area, &x, &y, &charpos,
20180 &object, &dx, &dy, &width, &height);
20181 else
20182 {
20183 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20184 string = marginal_area_string (w, area, &x, &y, &charpos,
20185 &object, &dx, &dy, &width, &height);
20186 }
20187
20188 help = Qnil;
20189
20190 if (IMAGEP (object))
20191 {
20192 Lisp_Object image_map, hotspot;
20193 if ((image_map = Fplist_get (XCDR (object), QCmap),
20194 !NILP (image_map))
20195 && (hotspot = find_hot_spot (image_map, dx, dy),
20196 CONSP (hotspot))
20197 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20198 {
20199 Lisp_Object area_id, plist;
20200
20201 area_id = XCAR (hotspot);
20202 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20203 If so, we could look for mouse-enter, mouse-leave
20204 properties in PLIST (and do something...). */
20205 if ((plist = XCDR (hotspot), CONSP (plist)))
20206 {
20207 pointer = Fplist_get (plist, Qpointer);
20208 if (NILP (pointer))
20209 pointer = Qhand;
20210 help = Fplist_get (plist, Qhelp_echo);
20211 if (!NILP (help))
20212 {
20213 help_echo_string = help;
20214 /* Is this correct? ++kfs */
20215 XSETWINDOW (help_echo_window, w);
20216 help_echo_object = w->buffer;
20217 help_echo_pos = charpos;
20218 }
20219 }
20220 if (NILP (pointer))
20221 pointer = Fplist_get (XCDR (object), QCpointer);
20222 }
20223 }
20224
20225 if (STRINGP (string))
20226 {
20227 pos = make_number (charpos);
20228 /* If we're on a string with `help-echo' text property, arrange
20229 for the help to be displayed. This is done by setting the
20230 global variable help_echo_string to the help string. */
20231 help = Fget_text_property (pos, Qhelp_echo, string);
20232 if (!NILP (help))
20233 {
20234 help_echo_string = help;
20235 XSETWINDOW (help_echo_window, w);
20236 help_echo_object = string;
20237 help_echo_pos = charpos;
20238 }
20239
20240 if (NILP (pointer))
20241 pointer = Fget_text_property (pos, Qpointer, string);
20242
20243 /* Change the mouse pointer according to what is under X/Y. */
20244 if (NILP (pointer) && area == ON_MODE_LINE)
20245 {
20246 Lisp_Object map;
20247 map = Fget_text_property (pos, Qlocal_map, string);
20248 if (!KEYMAPP (map))
20249 map = Fget_text_property (pos, Qkeymap, string);
20250 if (!KEYMAPP (map))
20251 cursor = dpyinfo->vertical_scroll_bar_cursor;
20252 }
20253 }
20254
20255 define_frame_cursor1 (f, cursor, pointer);
20256 }
20257
20258
20259 /* EXPORT:
20260 Take proper action when the mouse has moved to position X, Y on
20261 frame F as regards highlighting characters that have mouse-face
20262 properties. Also de-highlighting chars where the mouse was before.
20263 X and Y can be negative or out of range. */
20264
20265 void
20266 note_mouse_highlight (f, x, y)
20267 struct frame *f;
20268 int x, y;
20269 {
20270 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20271 enum window_part part;
20272 Lisp_Object window;
20273 struct window *w;
20274 Cursor cursor = No_Cursor;
20275 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20276 struct buffer *b;
20277
20278 /* When a menu is active, don't highlight because this looks odd. */
20279 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20280 if (popup_activated ())
20281 return;
20282 #endif
20283
20284 if (NILP (Vmouse_highlight)
20285 || !f->glyphs_initialized_p)
20286 return;
20287
20288 dpyinfo->mouse_face_mouse_x = x;
20289 dpyinfo->mouse_face_mouse_y = y;
20290 dpyinfo->mouse_face_mouse_frame = f;
20291
20292 if (dpyinfo->mouse_face_defer)
20293 return;
20294
20295 if (gc_in_progress)
20296 {
20297 dpyinfo->mouse_face_deferred_gc = 1;
20298 return;
20299 }
20300
20301 /* Which window is that in? */
20302 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20303
20304 /* If we were displaying active text in another window, clear that. */
20305 if (! EQ (window, dpyinfo->mouse_face_window))
20306 clear_mouse_face (dpyinfo);
20307
20308 /* Not on a window -> return. */
20309 if (!WINDOWP (window))
20310 return;
20311
20312 /* Reset help_echo_string. It will get recomputed below. */
20313 help_echo_string = Qnil;
20314
20315 /* Convert to window-relative pixel coordinates. */
20316 w = XWINDOW (window);
20317 frame_to_window_pixel_xy (w, &x, &y);
20318
20319 /* Handle tool-bar window differently since it doesn't display a
20320 buffer. */
20321 if (EQ (window, f->tool_bar_window))
20322 {
20323 note_tool_bar_highlight (f, x, y);
20324 return;
20325 }
20326
20327 /* Mouse is on the mode, header line or margin? */
20328 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20329 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20330 {
20331 note_mode_line_or_margin_highlight (w, x, y, part);
20332 return;
20333 }
20334
20335 if (part == ON_VERTICAL_BORDER)
20336 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20337 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
20338 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20339 else
20340 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20341
20342 /* Are we in a window whose display is up to date?
20343 And verify the buffer's text has not changed. */
20344 b = XBUFFER (w->buffer);
20345 if (part == ON_TEXT
20346 && EQ (w->window_end_valid, w->buffer)
20347 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20348 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20349 {
20350 int hpos, vpos, pos, i, dx, dy, area;
20351 struct glyph *glyph;
20352 Lisp_Object object;
20353 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20354 Lisp_Object *overlay_vec = NULL;
20355 int len, noverlays;
20356 struct buffer *obuf;
20357 int obegv, ozv, same_region;
20358
20359 /* Find the glyph under X/Y. */
20360 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20361
20362 /* Look for :pointer property on image. */
20363 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20364 {
20365 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20366 if (img != NULL && IMAGEP (img->spec))
20367 {
20368 Lisp_Object image_map, hotspot;
20369 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20370 !NILP (image_map))
20371 && (hotspot = find_hot_spot (image_map, dx, dy),
20372 CONSP (hotspot))
20373 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20374 {
20375 Lisp_Object area_id, plist;
20376
20377 area_id = XCAR (hotspot);
20378 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20379 If so, we could look for mouse-enter, mouse-leave
20380 properties in PLIST (and do something...). */
20381 if ((plist = XCDR (hotspot), CONSP (plist)))
20382 {
20383 pointer = Fplist_get (plist, Qpointer);
20384 if (NILP (pointer))
20385 pointer = Qhand;
20386 help_echo_string = Fplist_get (plist, Qhelp_echo);
20387 if (!NILP (help_echo_string))
20388 {
20389 help_echo_window = window;
20390 help_echo_object = glyph->object;
20391 help_echo_pos = glyph->charpos;
20392 }
20393 }
20394 }
20395 if (NILP (pointer))
20396 pointer = Fplist_get (XCDR (img->spec), QCpointer);
20397 }
20398 }
20399
20400 /* Clear mouse face if X/Y not over text. */
20401 if (glyph == NULL
20402 || area != TEXT_AREA
20403 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
20404 {
20405 if (clear_mouse_face (dpyinfo))
20406 cursor = No_Cursor;
20407 if (NILP (pointer))
20408 {
20409 if (area != TEXT_AREA)
20410 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20411 else
20412 pointer = Vvoid_text_area_pointer;
20413 }
20414 goto set_cursor;
20415 }
20416
20417 pos = glyph->charpos;
20418 object = glyph->object;
20419 if (!STRINGP (object) && !BUFFERP (object))
20420 goto set_cursor;
20421
20422 /* If we get an out-of-range value, return now; avoid an error. */
20423 if (BUFFERP (object) && pos > BUF_Z (b))
20424 goto set_cursor;
20425
20426 /* Make the window's buffer temporarily current for
20427 overlays_at and compute_char_face. */
20428 obuf = current_buffer;
20429 current_buffer = b;
20430 obegv = BEGV;
20431 ozv = ZV;
20432 BEGV = BEG;
20433 ZV = Z;
20434
20435 /* Is this char mouse-active or does it have help-echo? */
20436 position = make_number (pos);
20437
20438 if (BUFFERP (object))
20439 {
20440 /* Put all the overlays we want in a vector in overlay_vec.
20441 Store the length in len. If there are more than 10, make
20442 enough space for all, and try again. */
20443 len = 10;
20444 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20445 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
20446 if (noverlays > len)
20447 {
20448 len = noverlays;
20449 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20450 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
20451 }
20452
20453 /* Sort overlays into increasing priority order. */
20454 noverlays = sort_overlays (overlay_vec, noverlays, w);
20455 }
20456 else
20457 noverlays = 0;
20458
20459 same_region = (EQ (window, dpyinfo->mouse_face_window)
20460 && vpos >= dpyinfo->mouse_face_beg_row
20461 && vpos <= dpyinfo->mouse_face_end_row
20462 && (vpos > dpyinfo->mouse_face_beg_row
20463 || hpos >= dpyinfo->mouse_face_beg_col)
20464 && (vpos < dpyinfo->mouse_face_end_row
20465 || hpos < dpyinfo->mouse_face_end_col
20466 || dpyinfo->mouse_face_past_end));
20467
20468 if (same_region)
20469 cursor = No_Cursor;
20470
20471 /* Check mouse-face highlighting. */
20472 if (! same_region
20473 /* If there exists an overlay with mouse-face overlapping
20474 the one we are currently highlighting, we have to
20475 check if we enter the overlapping overlay, and then
20476 highlight only that. */
20477 || (OVERLAYP (dpyinfo->mouse_face_overlay)
20478 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
20479 {
20480 /* Find the highest priority overlay that has a mouse-face
20481 property. */
20482 overlay = Qnil;
20483 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
20484 {
20485 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
20486 if (!NILP (mouse_face))
20487 overlay = overlay_vec[i];
20488 }
20489
20490 /* If we're actually highlighting the same overlay as
20491 before, there's no need to do that again. */
20492 if (!NILP (overlay)
20493 && EQ (overlay, dpyinfo->mouse_face_overlay))
20494 goto check_help_echo;
20495
20496 dpyinfo->mouse_face_overlay = overlay;
20497
20498 /* Clear the display of the old active region, if any. */
20499 if (clear_mouse_face (dpyinfo))
20500 cursor = No_Cursor;
20501
20502 /* If no overlay applies, get a text property. */
20503 if (NILP (overlay))
20504 mouse_face = Fget_text_property (position, Qmouse_face, object);
20505
20506 /* Handle the overlay case. */
20507 if (!NILP (overlay))
20508 {
20509 /* Find the range of text around this char that
20510 should be active. */
20511 Lisp_Object before, after;
20512 int ignore;
20513
20514 before = Foverlay_start (overlay);
20515 after = Foverlay_end (overlay);
20516 /* Record this as the current active region. */
20517 fast_find_position (w, XFASTINT (before),
20518 &dpyinfo->mouse_face_beg_col,
20519 &dpyinfo->mouse_face_beg_row,
20520 &dpyinfo->mouse_face_beg_x,
20521 &dpyinfo->mouse_face_beg_y, Qnil);
20522
20523 dpyinfo->mouse_face_past_end
20524 = !fast_find_position (w, XFASTINT (after),
20525 &dpyinfo->mouse_face_end_col,
20526 &dpyinfo->mouse_face_end_row,
20527 &dpyinfo->mouse_face_end_x,
20528 &dpyinfo->mouse_face_end_y, Qnil);
20529 dpyinfo->mouse_face_window = window;
20530
20531 dpyinfo->mouse_face_face_id
20532 = face_at_buffer_position (w, pos, 0, 0,
20533 &ignore, pos + 1,
20534 !dpyinfo->mouse_face_hidden);
20535
20536 /* Display it as active. */
20537 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20538 cursor = No_Cursor;
20539 }
20540 /* Handle the text property case. */
20541 else if (!NILP (mouse_face) && BUFFERP (object))
20542 {
20543 /* Find the range of text around this char that
20544 should be active. */
20545 Lisp_Object before, after, beginning, end;
20546 int ignore;
20547
20548 beginning = Fmarker_position (w->start);
20549 end = make_number (BUF_Z (XBUFFER (object))
20550 - XFASTINT (w->window_end_pos));
20551 before
20552 = Fprevious_single_property_change (make_number (pos + 1),
20553 Qmouse_face,
20554 object, beginning);
20555 after
20556 = Fnext_single_property_change (position, Qmouse_face,
20557 object, end);
20558
20559 /* Record this as the current active region. */
20560 fast_find_position (w, XFASTINT (before),
20561 &dpyinfo->mouse_face_beg_col,
20562 &dpyinfo->mouse_face_beg_row,
20563 &dpyinfo->mouse_face_beg_x,
20564 &dpyinfo->mouse_face_beg_y, Qnil);
20565 dpyinfo->mouse_face_past_end
20566 = !fast_find_position (w, XFASTINT (after),
20567 &dpyinfo->mouse_face_end_col,
20568 &dpyinfo->mouse_face_end_row,
20569 &dpyinfo->mouse_face_end_x,
20570 &dpyinfo->mouse_face_end_y, Qnil);
20571 dpyinfo->mouse_face_window = window;
20572
20573 if (BUFFERP (object))
20574 dpyinfo->mouse_face_face_id
20575 = face_at_buffer_position (w, pos, 0, 0,
20576 &ignore, pos + 1,
20577 !dpyinfo->mouse_face_hidden);
20578
20579 /* Display it as active. */
20580 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20581 cursor = No_Cursor;
20582 }
20583 else if (!NILP (mouse_face) && STRINGP (object))
20584 {
20585 Lisp_Object b, e;
20586 int ignore;
20587
20588 b = Fprevious_single_property_change (make_number (pos + 1),
20589 Qmouse_face,
20590 object, Qnil);
20591 e = Fnext_single_property_change (position, Qmouse_face,
20592 object, Qnil);
20593 if (NILP (b))
20594 b = make_number (0);
20595 if (NILP (e))
20596 e = make_number (SCHARS (object) - 1);
20597 fast_find_string_pos (w, XINT (b), object,
20598 &dpyinfo->mouse_face_beg_col,
20599 &dpyinfo->mouse_face_beg_row,
20600 &dpyinfo->mouse_face_beg_x,
20601 &dpyinfo->mouse_face_beg_y, 0);
20602 fast_find_string_pos (w, XINT (e), object,
20603 &dpyinfo->mouse_face_end_col,
20604 &dpyinfo->mouse_face_end_row,
20605 &dpyinfo->mouse_face_end_x,
20606 &dpyinfo->mouse_face_end_y, 1);
20607 dpyinfo->mouse_face_past_end = 0;
20608 dpyinfo->mouse_face_window = window;
20609 dpyinfo->mouse_face_face_id
20610 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
20611 glyph->face_id, 1);
20612 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20613 cursor = No_Cursor;
20614 }
20615 else if (STRINGP (object) && NILP (mouse_face))
20616 {
20617 /* A string which doesn't have mouse-face, but
20618 the text ``under'' it might have. */
20619 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
20620 int start = MATRIX_ROW_START_CHARPOS (r);
20621
20622 pos = string_buffer_position (w, object, start);
20623 if (pos > 0)
20624 mouse_face = get_char_property_and_overlay (make_number (pos),
20625 Qmouse_face,
20626 w->buffer,
20627 &overlay);
20628 if (!NILP (mouse_face) && !NILP (overlay))
20629 {
20630 Lisp_Object before = Foverlay_start (overlay);
20631 Lisp_Object after = Foverlay_end (overlay);
20632 int ignore;
20633
20634 /* Note that we might not be able to find position
20635 BEFORE in the glyph matrix if the overlay is
20636 entirely covered by a `display' property. In
20637 this case, we overshoot. So let's stop in
20638 the glyph matrix before glyphs for OBJECT. */
20639 fast_find_position (w, XFASTINT (before),
20640 &dpyinfo->mouse_face_beg_col,
20641 &dpyinfo->mouse_face_beg_row,
20642 &dpyinfo->mouse_face_beg_x,
20643 &dpyinfo->mouse_face_beg_y,
20644 object);
20645
20646 dpyinfo->mouse_face_past_end
20647 = !fast_find_position (w, XFASTINT (after),
20648 &dpyinfo->mouse_face_end_col,
20649 &dpyinfo->mouse_face_end_row,
20650 &dpyinfo->mouse_face_end_x,
20651 &dpyinfo->mouse_face_end_y,
20652 Qnil);
20653 dpyinfo->mouse_face_window = window;
20654 dpyinfo->mouse_face_face_id
20655 = face_at_buffer_position (w, pos, 0, 0,
20656 &ignore, pos + 1,
20657 !dpyinfo->mouse_face_hidden);
20658
20659 /* Display it as active. */
20660 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20661 cursor = No_Cursor;
20662 }
20663 }
20664 }
20665
20666 check_help_echo:
20667
20668 /* Look for a `help-echo' property. */
20669 if (NILP (help_echo_string)) {
20670 Lisp_Object help, overlay;
20671
20672 /* Check overlays first. */
20673 help = overlay = Qnil;
20674 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
20675 {
20676 overlay = overlay_vec[i];
20677 help = Foverlay_get (overlay, Qhelp_echo);
20678 }
20679
20680 if (!NILP (help))
20681 {
20682 help_echo_string = help;
20683 help_echo_window = window;
20684 help_echo_object = overlay;
20685 help_echo_pos = pos;
20686 }
20687 else
20688 {
20689 Lisp_Object object = glyph->object;
20690 int charpos = glyph->charpos;
20691
20692 /* Try text properties. */
20693 if (STRINGP (object)
20694 && charpos >= 0
20695 && charpos < SCHARS (object))
20696 {
20697 help = Fget_text_property (make_number (charpos),
20698 Qhelp_echo, object);
20699 if (NILP (help))
20700 {
20701 /* If the string itself doesn't specify a help-echo,
20702 see if the buffer text ``under'' it does. */
20703 struct glyph_row *r
20704 = MATRIX_ROW (w->current_matrix, vpos);
20705 int start = MATRIX_ROW_START_CHARPOS (r);
20706 int pos = string_buffer_position (w, object, start);
20707 if (pos > 0)
20708 {
20709 help = Fget_char_property (make_number (pos),
20710 Qhelp_echo, w->buffer);
20711 if (!NILP (help))
20712 {
20713 charpos = pos;
20714 object = w->buffer;
20715 }
20716 }
20717 }
20718 }
20719 else if (BUFFERP (object)
20720 && charpos >= BEGV
20721 && charpos < ZV)
20722 help = Fget_text_property (make_number (charpos), Qhelp_echo,
20723 object);
20724
20725 if (!NILP (help))
20726 {
20727 help_echo_string = help;
20728 help_echo_window = window;
20729 help_echo_object = object;
20730 help_echo_pos = charpos;
20731 }
20732 }
20733 }
20734
20735 /* Look for a `pointer' property. */
20736 if (NILP (pointer))
20737 {
20738 /* Check overlays first. */
20739 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
20740 pointer = Foverlay_get (overlay_vec[i], Qpointer);
20741
20742 if (NILP (pointer))
20743 {
20744 Lisp_Object object = glyph->object;
20745 int charpos = glyph->charpos;
20746
20747 /* Try text properties. */
20748 if (STRINGP (object)
20749 && charpos >= 0
20750 && charpos < SCHARS (object))
20751 {
20752 pointer = Fget_text_property (make_number (charpos),
20753 Qpointer, object);
20754 if (NILP (pointer))
20755 {
20756 /* If the string itself doesn't specify a pointer,
20757 see if the buffer text ``under'' it does. */
20758 struct glyph_row *r
20759 = MATRIX_ROW (w->current_matrix, vpos);
20760 int start = MATRIX_ROW_START_CHARPOS (r);
20761 int pos = string_buffer_position (w, object, start);
20762 if (pos > 0)
20763 pointer = Fget_char_property (make_number (pos),
20764 Qpointer, w->buffer);
20765 }
20766 }
20767 else if (BUFFERP (object)
20768 && charpos >= BEGV
20769 && charpos < ZV)
20770 pointer = Fget_text_property (make_number (charpos),
20771 Qpointer, object);
20772 }
20773 }
20774
20775 BEGV = obegv;
20776 ZV = ozv;
20777 current_buffer = obuf;
20778 }
20779
20780 set_cursor:
20781
20782 define_frame_cursor1 (f, cursor, pointer);
20783 }
20784
20785
20786 /* EXPORT for RIF:
20787 Clear any mouse-face on window W. This function is part of the
20788 redisplay interface, and is called from try_window_id and similar
20789 functions to ensure the mouse-highlight is off. */
20790
20791 void
20792 x_clear_window_mouse_face (w)
20793 struct window *w;
20794 {
20795 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20796 Lisp_Object window;
20797
20798 BLOCK_INPUT;
20799 XSETWINDOW (window, w);
20800 if (EQ (window, dpyinfo->mouse_face_window))
20801 clear_mouse_face (dpyinfo);
20802 UNBLOCK_INPUT;
20803 }
20804
20805
20806 /* EXPORT:
20807 Just discard the mouse face information for frame F, if any.
20808 This is used when the size of F is changed. */
20809
20810 void
20811 cancel_mouse_face (f)
20812 struct frame *f;
20813 {
20814 Lisp_Object window;
20815 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20816
20817 window = dpyinfo->mouse_face_window;
20818 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
20819 {
20820 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20821 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20822 dpyinfo->mouse_face_window = Qnil;
20823 }
20824 }
20825
20826
20827 #endif /* HAVE_WINDOW_SYSTEM */
20828
20829 \f
20830 /***********************************************************************
20831 Exposure Events
20832 ***********************************************************************/
20833
20834 #ifdef HAVE_WINDOW_SYSTEM
20835
20836 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20837 which intersects rectangle R. R is in window-relative coordinates. */
20838
20839 static void
20840 expose_area (w, row, r, area)
20841 struct window *w;
20842 struct glyph_row *row;
20843 XRectangle *r;
20844 enum glyph_row_area area;
20845 {
20846 struct glyph *first = row->glyphs[area];
20847 struct glyph *end = row->glyphs[area] + row->used[area];
20848 struct glyph *last;
20849 int first_x, start_x, x;
20850
20851 if (area == TEXT_AREA && row->fill_line_p)
20852 /* If row extends face to end of line write the whole line. */
20853 draw_glyphs (w, 0, row, area,
20854 0, row->used[area],
20855 DRAW_NORMAL_TEXT, 0);
20856 else
20857 {
20858 /* Set START_X to the window-relative start position for drawing glyphs of
20859 AREA. The first glyph of the text area can be partially visible.
20860 The first glyphs of other areas cannot. */
20861 start_x = window_box_left_offset (w, area);
20862 x = start_x;
20863 if (area == TEXT_AREA)
20864 x += row->x;
20865
20866 /* Find the first glyph that must be redrawn. */
20867 while (first < end
20868 && x + first->pixel_width < r->x)
20869 {
20870 x += first->pixel_width;
20871 ++first;
20872 }
20873
20874 /* Find the last one. */
20875 last = first;
20876 first_x = x;
20877 while (last < end
20878 && x < r->x + r->width)
20879 {
20880 x += last->pixel_width;
20881 ++last;
20882 }
20883
20884 /* Repaint. */
20885 if (last > first)
20886 draw_glyphs (w, first_x - start_x, row, area,
20887 first - row->glyphs[area], last - row->glyphs[area],
20888 DRAW_NORMAL_TEXT, 0);
20889 }
20890 }
20891
20892
20893 /* Redraw the parts of the glyph row ROW on window W intersecting
20894 rectangle R. R is in window-relative coordinates. Value is
20895 non-zero if mouse-face was overwritten. */
20896
20897 static int
20898 expose_line (w, row, r)
20899 struct window *w;
20900 struct glyph_row *row;
20901 XRectangle *r;
20902 {
20903 xassert (row->enabled_p);
20904
20905 if (row->mode_line_p || w->pseudo_window_p)
20906 draw_glyphs (w, 0, row, TEXT_AREA,
20907 0, row->used[TEXT_AREA],
20908 DRAW_NORMAL_TEXT, 0);
20909 else
20910 {
20911 if (row->used[LEFT_MARGIN_AREA])
20912 expose_area (w, row, r, LEFT_MARGIN_AREA);
20913 if (row->used[TEXT_AREA])
20914 expose_area (w, row, r, TEXT_AREA);
20915 if (row->used[RIGHT_MARGIN_AREA])
20916 expose_area (w, row, r, RIGHT_MARGIN_AREA);
20917 draw_row_fringe_bitmaps (w, row);
20918 }
20919
20920 return row->mouse_face_p;
20921 }
20922
20923
20924 /* Redraw those parts of glyphs rows during expose event handling that
20925 overlap other rows. Redrawing of an exposed line writes over parts
20926 of lines overlapping that exposed line; this function fixes that.
20927
20928 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
20929 row in W's current matrix that is exposed and overlaps other rows.
20930 LAST_OVERLAPPING_ROW is the last such row. */
20931
20932 static void
20933 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
20934 struct window *w;
20935 struct glyph_row *first_overlapping_row;
20936 struct glyph_row *last_overlapping_row;
20937 {
20938 struct glyph_row *row;
20939
20940 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
20941 if (row->overlapping_p)
20942 {
20943 xassert (row->enabled_p && !row->mode_line_p);
20944
20945 if (row->used[LEFT_MARGIN_AREA])
20946 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
20947
20948 if (row->used[TEXT_AREA])
20949 x_fix_overlapping_area (w, row, TEXT_AREA);
20950
20951 if (row->used[RIGHT_MARGIN_AREA])
20952 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
20953 }
20954 }
20955
20956
20957 /* Return non-zero if W's cursor intersects rectangle R. */
20958
20959 static int
20960 phys_cursor_in_rect_p (w, r)
20961 struct window *w;
20962 XRectangle *r;
20963 {
20964 XRectangle cr, result;
20965 struct glyph *cursor_glyph;
20966
20967 cursor_glyph = get_phys_cursor_glyph (w);
20968 if (cursor_glyph)
20969 {
20970 /* r is relative to W's box, but w->phys_cursor.x is relative
20971 to left edge of W's TEXT area. Adjust it. */
20972 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
20973 cr.y = w->phys_cursor.y;
20974 cr.width = cursor_glyph->pixel_width;
20975 cr.height = w->phys_cursor_height;
20976 /* ++KFS: W32 version used W32-specific IntersectRect here, but
20977 I assume the effect is the same -- and this is portable. */
20978 return x_intersect_rectangles (&cr, r, &result);
20979 }
20980 else
20981 return 0;
20982 }
20983
20984
20985 /* EXPORT:
20986 Draw a vertical window border to the right of window W if W doesn't
20987 have vertical scroll bars. */
20988
20989 void
20990 x_draw_vertical_border (w)
20991 struct window *w;
20992 {
20993 /* We could do better, if we knew what type of scroll-bar the adjacent
20994 windows (on either side) have... But we don't :-(
20995 However, I think this works ok. ++KFS 2003-04-25 */
20996
20997 /* Redraw borders between horizontally adjacent windows. Don't
20998 do it for frames with vertical scroll bars because either the
20999 right scroll bar of a window, or the left scroll bar of its
21000 neighbor will suffice as a border. */
21001 if (!WINDOW_RIGHTMOST_P (w)
21002 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21003 {
21004 int x0, x1, y0, y1;
21005
21006 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21007 y1 -= 1;
21008
21009 rif->draw_vertical_window_border (w, x1, y0, y1);
21010 }
21011 else if (!WINDOW_LEFTMOST_P (w)
21012 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21013 {
21014 int x0, x1, y0, y1;
21015
21016 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21017 y1 -= 1;
21018
21019 rif->draw_vertical_window_border (w, x0, y0, y1);
21020 }
21021 }
21022
21023
21024 /* Redraw the part of window W intersection rectangle FR. Pixel
21025 coordinates in FR are frame-relative. Call this function with
21026 input blocked. Value is non-zero if the exposure overwrites
21027 mouse-face. */
21028
21029 static int
21030 expose_window (w, fr)
21031 struct window *w;
21032 XRectangle *fr;
21033 {
21034 struct frame *f = XFRAME (w->frame);
21035 XRectangle wr, r;
21036 int mouse_face_overwritten_p = 0;
21037
21038 /* If window is not yet fully initialized, do nothing. This can
21039 happen when toolkit scroll bars are used and a window is split.
21040 Reconfiguring the scroll bar will generate an expose for a newly
21041 created window. */
21042 if (w->current_matrix == NULL)
21043 return 0;
21044
21045 /* When we're currently updating the window, display and current
21046 matrix usually don't agree. Arrange for a thorough display
21047 later. */
21048 if (w == updated_window)
21049 {
21050 SET_FRAME_GARBAGED (f);
21051 return 0;
21052 }
21053
21054 /* Frame-relative pixel rectangle of W. */
21055 wr.x = WINDOW_LEFT_EDGE_X (w);
21056 wr.y = WINDOW_TOP_EDGE_Y (w);
21057 wr.width = WINDOW_TOTAL_WIDTH (w);
21058 wr.height = WINDOW_TOTAL_HEIGHT (w);
21059
21060 if (x_intersect_rectangles (fr, &wr, &r))
21061 {
21062 int yb = window_text_bottom_y (w);
21063 struct glyph_row *row;
21064 int cursor_cleared_p;
21065 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21066
21067 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21068 r.x, r.y, r.width, r.height));
21069
21070 /* Convert to window coordinates. */
21071 r.x -= WINDOW_LEFT_EDGE_X (w);
21072 r.y -= WINDOW_TOP_EDGE_Y (w);
21073
21074 /* Turn off the cursor. */
21075 if (!w->pseudo_window_p
21076 && phys_cursor_in_rect_p (w, &r))
21077 {
21078 x_clear_cursor (w);
21079 cursor_cleared_p = 1;
21080 }
21081 else
21082 cursor_cleared_p = 0;
21083
21084 /* Update lines intersecting rectangle R. */
21085 first_overlapping_row = last_overlapping_row = NULL;
21086 for (row = w->current_matrix->rows;
21087 row->enabled_p;
21088 ++row)
21089 {
21090 int y0 = row->y;
21091 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21092
21093 if ((y0 >= r.y && y0 < r.y + r.height)
21094 || (y1 > r.y && y1 < r.y + r.height)
21095 || (r.y >= y0 && r.y < y1)
21096 || (r.y + r.height > y0 && r.y + r.height < y1))
21097 {
21098 if (row->overlapping_p)
21099 {
21100 if (first_overlapping_row == NULL)
21101 first_overlapping_row = row;
21102 last_overlapping_row = row;
21103 }
21104
21105 if (expose_line (w, row, &r))
21106 mouse_face_overwritten_p = 1;
21107 }
21108
21109 if (y1 >= yb)
21110 break;
21111 }
21112
21113 /* Display the mode line if there is one. */
21114 if (WINDOW_WANTS_MODELINE_P (w)
21115 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21116 row->enabled_p)
21117 && row->y < r.y + r.height)
21118 {
21119 if (expose_line (w, row, &r))
21120 mouse_face_overwritten_p = 1;
21121 }
21122
21123 if (!w->pseudo_window_p)
21124 {
21125 /* Fix the display of overlapping rows. */
21126 if (first_overlapping_row)
21127 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21128
21129 /* Draw border between windows. */
21130 x_draw_vertical_border (w);
21131
21132 /* Turn the cursor on again. */
21133 if (cursor_cleared_p)
21134 update_window_cursor (w, 1);
21135 }
21136 }
21137
21138 #ifdef HAVE_CARBON
21139 /* Display scroll bar for this window. */
21140 if (!NILP (w->vertical_scroll_bar))
21141 {
21142 /* ++KFS:
21143 If this doesn't work here (maybe some header files are missing),
21144 make a function in macterm.c and call it to do the job! */
21145 ControlHandle ch
21146 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21147
21148 Draw1Control (ch);
21149 }
21150 #endif
21151
21152 return mouse_face_overwritten_p;
21153 }
21154
21155
21156
21157 /* Redraw (parts) of all windows in the window tree rooted at W that
21158 intersect R. R contains frame pixel coordinates. Value is
21159 non-zero if the exposure overwrites mouse-face. */
21160
21161 static int
21162 expose_window_tree (w, r)
21163 struct window *w;
21164 XRectangle *r;
21165 {
21166 struct frame *f = XFRAME (w->frame);
21167 int mouse_face_overwritten_p = 0;
21168
21169 while (w && !FRAME_GARBAGED_P (f))
21170 {
21171 if (!NILP (w->hchild))
21172 mouse_face_overwritten_p
21173 |= expose_window_tree (XWINDOW (w->hchild), r);
21174 else if (!NILP (w->vchild))
21175 mouse_face_overwritten_p
21176 |= expose_window_tree (XWINDOW (w->vchild), r);
21177 else
21178 mouse_face_overwritten_p |= expose_window (w, r);
21179
21180 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21181 }
21182
21183 return mouse_face_overwritten_p;
21184 }
21185
21186
21187 /* EXPORT:
21188 Redisplay an exposed area of frame F. X and Y are the upper-left
21189 corner of the exposed rectangle. W and H are width and height of
21190 the exposed area. All are pixel values. W or H zero means redraw
21191 the entire frame. */
21192
21193 void
21194 expose_frame (f, x, y, w, h)
21195 struct frame *f;
21196 int x, y, w, h;
21197 {
21198 XRectangle r;
21199 int mouse_face_overwritten_p = 0;
21200
21201 TRACE ((stderr, "expose_frame "));
21202
21203 /* No need to redraw if frame will be redrawn soon. */
21204 if (FRAME_GARBAGED_P (f))
21205 {
21206 TRACE ((stderr, " garbaged\n"));
21207 return;
21208 }
21209
21210 #ifdef HAVE_CARBON
21211 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21212 or deactivated here, for unknown reasons, activated scroll bars
21213 are shown in deactivated frames in some instances. */
21214 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21215 activate_scroll_bars (f);
21216 else
21217 deactivate_scroll_bars (f);
21218 #endif
21219
21220 /* If basic faces haven't been realized yet, there is no point in
21221 trying to redraw anything. This can happen when we get an expose
21222 event while Emacs is starting, e.g. by moving another window. */
21223 if (FRAME_FACE_CACHE (f) == NULL
21224 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21225 {
21226 TRACE ((stderr, " no faces\n"));
21227 return;
21228 }
21229
21230 if (w == 0 || h == 0)
21231 {
21232 r.x = r.y = 0;
21233 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21234 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21235 }
21236 else
21237 {
21238 r.x = x;
21239 r.y = y;
21240 r.width = w;
21241 r.height = h;
21242 }
21243
21244 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21245 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21246
21247 if (WINDOWP (f->tool_bar_window))
21248 mouse_face_overwritten_p
21249 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21250
21251 #ifdef HAVE_X_WINDOWS
21252 #ifndef MSDOS
21253 #ifndef USE_X_TOOLKIT
21254 if (WINDOWP (f->menu_bar_window))
21255 mouse_face_overwritten_p
21256 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21257 #endif /* not USE_X_TOOLKIT */
21258 #endif
21259 #endif
21260
21261 /* Some window managers support a focus-follows-mouse style with
21262 delayed raising of frames. Imagine a partially obscured frame,
21263 and moving the mouse into partially obscured mouse-face on that
21264 frame. The visible part of the mouse-face will be highlighted,
21265 then the WM raises the obscured frame. With at least one WM, KDE
21266 2.1, Emacs is not getting any event for the raising of the frame
21267 (even tried with SubstructureRedirectMask), only Expose events.
21268 These expose events will draw text normally, i.e. not
21269 highlighted. Which means we must redo the highlight here.
21270 Subsume it under ``we love X''. --gerd 2001-08-15 */
21271 /* Included in Windows version because Windows most likely does not
21272 do the right thing if any third party tool offers
21273 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21274 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21275 {
21276 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21277 if (f == dpyinfo->mouse_face_mouse_frame)
21278 {
21279 int x = dpyinfo->mouse_face_mouse_x;
21280 int y = dpyinfo->mouse_face_mouse_y;
21281 clear_mouse_face (dpyinfo);
21282 note_mouse_highlight (f, x, y);
21283 }
21284 }
21285 }
21286
21287
21288 /* EXPORT:
21289 Determine the intersection of two rectangles R1 and R2. Return
21290 the intersection in *RESULT. Value is non-zero if RESULT is not
21291 empty. */
21292
21293 int
21294 x_intersect_rectangles (r1, r2, result)
21295 XRectangle *r1, *r2, *result;
21296 {
21297 XRectangle *left, *right;
21298 XRectangle *upper, *lower;
21299 int intersection_p = 0;
21300
21301 /* Rearrange so that R1 is the left-most rectangle. */
21302 if (r1->x < r2->x)
21303 left = r1, right = r2;
21304 else
21305 left = r2, right = r1;
21306
21307 /* X0 of the intersection is right.x0, if this is inside R1,
21308 otherwise there is no intersection. */
21309 if (right->x <= left->x + left->width)
21310 {
21311 result->x = right->x;
21312
21313 /* The right end of the intersection is the minimum of the
21314 the right ends of left and right. */
21315 result->width = (min (left->x + left->width, right->x + right->width)
21316 - result->x);
21317
21318 /* Same game for Y. */
21319 if (r1->y < r2->y)
21320 upper = r1, lower = r2;
21321 else
21322 upper = r2, lower = r1;
21323
21324 /* The upper end of the intersection is lower.y0, if this is inside
21325 of upper. Otherwise, there is no intersection. */
21326 if (lower->y <= upper->y + upper->height)
21327 {
21328 result->y = lower->y;
21329
21330 /* The lower end of the intersection is the minimum of the lower
21331 ends of upper and lower. */
21332 result->height = (min (lower->y + lower->height,
21333 upper->y + upper->height)
21334 - result->y);
21335 intersection_p = 1;
21336 }
21337 }
21338
21339 return intersection_p;
21340 }
21341
21342 #endif /* HAVE_WINDOW_SYSTEM */
21343
21344 \f
21345 /***********************************************************************
21346 Initialization
21347 ***********************************************************************/
21348
21349 void
21350 syms_of_xdisp ()
21351 {
21352 Vwith_echo_area_save_vector = Qnil;
21353 staticpro (&Vwith_echo_area_save_vector);
21354
21355 Vmessage_stack = Qnil;
21356 staticpro (&Vmessage_stack);
21357
21358 Qinhibit_redisplay = intern ("inhibit-redisplay");
21359 staticpro (&Qinhibit_redisplay);
21360
21361 message_dolog_marker1 = Fmake_marker ();
21362 staticpro (&message_dolog_marker1);
21363 message_dolog_marker2 = Fmake_marker ();
21364 staticpro (&message_dolog_marker2);
21365 message_dolog_marker3 = Fmake_marker ();
21366 staticpro (&message_dolog_marker3);
21367
21368 #if GLYPH_DEBUG
21369 defsubr (&Sdump_frame_glyph_matrix);
21370 defsubr (&Sdump_glyph_matrix);
21371 defsubr (&Sdump_glyph_row);
21372 defsubr (&Sdump_tool_bar_row);
21373 defsubr (&Strace_redisplay);
21374 defsubr (&Strace_to_stderr);
21375 #endif
21376 #ifdef HAVE_WINDOW_SYSTEM
21377 defsubr (&Stool_bar_lines_needed);
21378 defsubr (&Slookup_image_map);
21379 #endif
21380 defsubr (&Sformat_mode_line);
21381
21382 staticpro (&Qmenu_bar_update_hook);
21383 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21384
21385 staticpro (&Qoverriding_terminal_local_map);
21386 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21387
21388 staticpro (&Qoverriding_local_map);
21389 Qoverriding_local_map = intern ("overriding-local-map");
21390
21391 staticpro (&Qwindow_scroll_functions);
21392 Qwindow_scroll_functions = intern ("window-scroll-functions");
21393
21394 staticpro (&Qredisplay_end_trigger_functions);
21395 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21396
21397 staticpro (&Qinhibit_point_motion_hooks);
21398 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21399
21400 QCdata = intern (":data");
21401 staticpro (&QCdata);
21402 Qdisplay = intern ("display");
21403 staticpro (&Qdisplay);
21404 Qspace_width = intern ("space-width");
21405 staticpro (&Qspace_width);
21406 Qraise = intern ("raise");
21407 staticpro (&Qraise);
21408 Qspace = intern ("space");
21409 staticpro (&Qspace);
21410 Qmargin = intern ("margin");
21411 staticpro (&Qmargin);
21412 Qpointer = intern ("pointer");
21413 staticpro (&Qpointer);
21414 Qleft_margin = intern ("left-margin");
21415 staticpro (&Qleft_margin);
21416 Qright_margin = intern ("right-margin");
21417 staticpro (&Qright_margin);
21418 QCalign_to = intern (":align-to");
21419 staticpro (&QCalign_to);
21420 QCrelative_width = intern (":relative-width");
21421 staticpro (&QCrelative_width);
21422 QCrelative_height = intern (":relative-height");
21423 staticpro (&QCrelative_height);
21424 QCeval = intern (":eval");
21425 staticpro (&QCeval);
21426 QCpropertize = intern (":propertize");
21427 staticpro (&QCpropertize);
21428 QCfile = intern (":file");
21429 staticpro (&QCfile);
21430 Qfontified = intern ("fontified");
21431 staticpro (&Qfontified);
21432 Qfontification_functions = intern ("fontification-functions");
21433 staticpro (&Qfontification_functions);
21434 Qtrailing_whitespace = intern ("trailing-whitespace");
21435 staticpro (&Qtrailing_whitespace);
21436 Qimage = intern ("image");
21437 staticpro (&Qimage);
21438 QCmap = intern (":map");
21439 staticpro (&QCmap);
21440 QCpointer = intern (":pointer");
21441 staticpro (&QCpointer);
21442 Qrect = intern ("rect");
21443 staticpro (&Qrect);
21444 Qcircle = intern ("circle");
21445 staticpro (&Qcircle);
21446 Qpoly = intern ("poly");
21447 staticpro (&Qpoly);
21448 Qmessage_truncate_lines = intern ("message-truncate-lines");
21449 staticpro (&Qmessage_truncate_lines);
21450 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
21451 staticpro (&Qcursor_in_non_selected_windows);
21452 Qgrow_only = intern ("grow-only");
21453 staticpro (&Qgrow_only);
21454 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
21455 staticpro (&Qinhibit_menubar_update);
21456 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
21457 staticpro (&Qinhibit_eval_during_redisplay);
21458 Qposition = intern ("position");
21459 staticpro (&Qposition);
21460 Qbuffer_position = intern ("buffer-position");
21461 staticpro (&Qbuffer_position);
21462 Qobject = intern ("object");
21463 staticpro (&Qobject);
21464 Qbar = intern ("bar");
21465 staticpro (&Qbar);
21466 Qhbar = intern ("hbar");
21467 staticpro (&Qhbar);
21468 Qbox = intern ("box");
21469 staticpro (&Qbox);
21470 Qhollow = intern ("hollow");
21471 staticpro (&Qhollow);
21472 Qhand = intern ("hand");
21473 staticpro (&Qhand);
21474 Qarrow = intern ("arrow");
21475 staticpro (&Qarrow);
21476 Qtext = intern ("text");
21477 staticpro (&Qtext);
21478 Qrisky_local_variable = intern ("risky-local-variable");
21479 staticpro (&Qrisky_local_variable);
21480 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
21481 staticpro (&Qinhibit_free_realized_faces);
21482
21483 list_of_error = Fcons (intern ("error"), Qnil);
21484 staticpro (&list_of_error);
21485
21486 last_arrow_position = Qnil;
21487 last_arrow_string = Qnil;
21488 staticpro (&last_arrow_position);
21489 staticpro (&last_arrow_string);
21490
21491 echo_buffer[0] = echo_buffer[1] = Qnil;
21492 staticpro (&echo_buffer[0]);
21493 staticpro (&echo_buffer[1]);
21494
21495 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
21496 staticpro (&echo_area_buffer[0]);
21497 staticpro (&echo_area_buffer[1]);
21498
21499 Vmessages_buffer_name = build_string ("*Messages*");
21500 staticpro (&Vmessages_buffer_name);
21501
21502 mode_line_proptrans_alist = Qnil;
21503 staticpro (&mode_line_proptrans_alist);
21504
21505 mode_line_string_list = Qnil;
21506 staticpro (&mode_line_string_list);
21507
21508 help_echo_string = Qnil;
21509 staticpro (&help_echo_string);
21510 help_echo_object = Qnil;
21511 staticpro (&help_echo_object);
21512 help_echo_window = Qnil;
21513 staticpro (&help_echo_window);
21514 previous_help_echo_string = Qnil;
21515 staticpro (&previous_help_echo_string);
21516 help_echo_pos = -1;
21517
21518 #ifdef HAVE_WINDOW_SYSTEM
21519 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
21520 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
21521 For example, if a block cursor is over a tab, it will be drawn as
21522 wide as that tab on the display. */);
21523 x_stretch_cursor_p = 0;
21524 #endif
21525
21526 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
21527 doc: /* Non-nil means highlight trailing whitespace.
21528 The face used for trailing whitespace is `trailing-whitespace'. */);
21529 Vshow_trailing_whitespace = Qnil;
21530
21531 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
21532 doc: /* The pointer shape to show in void text areas.
21533 Nil means to show the text pointer. Other options are `arrow', `text',
21534 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
21535 Vvoid_text_area_pointer = Qarrow;
21536
21537 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
21538 doc: /* Non-nil means don't actually do any redisplay.
21539 This is used for internal purposes. */);
21540 Vinhibit_redisplay = Qnil;
21541
21542 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
21543 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
21544 Vglobal_mode_string = Qnil;
21545
21546 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
21547 doc: /* Marker for where to display an arrow on top of the buffer text.
21548 This must be the beginning of a line in order to work.
21549 See also `overlay-arrow-string'. */);
21550 Voverlay_arrow_position = Qnil;
21551
21552 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
21553 doc: /* String to display as an arrow. See also `overlay-arrow-position'. */);
21554 Voverlay_arrow_string = Qnil;
21555
21556 DEFVAR_INT ("scroll-step", &scroll_step,
21557 doc: /* *The number of lines to try scrolling a window by when point moves out.
21558 If that fails to bring point back on frame, point is centered instead.
21559 If this is zero, point is always centered after it moves off frame.
21560 If you want scrolling to always be a line at a time, you should set
21561 `scroll-conservatively' to a large value rather than set this to 1. */);
21562
21563 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
21564 doc: /* *Scroll up to this many lines, to bring point back on screen.
21565 A value of zero means to scroll the text to center point vertically
21566 in the window. */);
21567 scroll_conservatively = 0;
21568
21569 DEFVAR_INT ("scroll-margin", &scroll_margin,
21570 doc: /* *Number of lines of margin at the top and bottom of a window.
21571 Recenter the window whenever point gets within this many lines
21572 of the top or bottom of the window. */);
21573 scroll_margin = 0;
21574
21575 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
21576 doc: /* Pixels per inch on current display.
21577 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
21578 Vdisplay_pixels_per_inch = make_float (72.0);
21579
21580 #if GLYPH_DEBUG
21581 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
21582 #endif
21583
21584 DEFVAR_BOOL ("truncate-partial-width-windows",
21585 &truncate_partial_width_windows,
21586 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
21587 truncate_partial_width_windows = 1;
21588
21589 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
21590 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
21591 Any other value means to use the appropriate face, `mode-line',
21592 `header-line', or `menu' respectively. */);
21593 mode_line_inverse_video = 1;
21594
21595 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
21596 doc: /* *Maximum buffer size for which line number should be displayed.
21597 If the buffer is bigger than this, the line number does not appear
21598 in the mode line. A value of nil means no limit. */);
21599 Vline_number_display_limit = Qnil;
21600
21601 DEFVAR_INT ("line-number-display-limit-width",
21602 &line_number_display_limit_width,
21603 doc: /* *Maximum line width (in characters) for line number display.
21604 If the average length of the lines near point is bigger than this, then the
21605 line number may be omitted from the mode line. */);
21606 line_number_display_limit_width = 200;
21607
21608 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
21609 doc: /* *Non-nil means highlight region even in nonselected windows. */);
21610 highlight_nonselected_windows = 0;
21611
21612 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
21613 doc: /* Non-nil if more than one frame is visible on this display.
21614 Minibuffer-only frames don't count, but iconified frames do.
21615 This variable is not guaranteed to be accurate except while processing
21616 `frame-title-format' and `icon-title-format'. */);
21617
21618 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
21619 doc: /* Template for displaying the title bar of visible frames.
21620 \(Assuming the window manager supports this feature.)
21621 This variable has the same structure as `mode-line-format' (which see),
21622 and is used only on frames for which no explicit name has been set
21623 \(see `modify-frame-parameters'). */);
21624
21625 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
21626 doc: /* Template for displaying the title bar of an iconified frame.
21627 \(Assuming the window manager supports this feature.)
21628 This variable has the same structure as `mode-line-format' (which see),
21629 and is used only on frames for which no explicit name has been set
21630 \(see `modify-frame-parameters'). */);
21631 Vicon_title_format
21632 = Vframe_title_format
21633 = Fcons (intern ("multiple-frames"),
21634 Fcons (build_string ("%b"),
21635 Fcons (Fcons (empty_string,
21636 Fcons (intern ("invocation-name"),
21637 Fcons (build_string ("@"),
21638 Fcons (intern ("system-name"),
21639 Qnil)))),
21640 Qnil)));
21641
21642 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
21643 doc: /* Maximum number of lines to keep in the message log buffer.
21644 If nil, disable message logging. If t, log messages but don't truncate
21645 the buffer when it becomes large. */);
21646 Vmessage_log_max = make_number (50);
21647
21648 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
21649 doc: /* Functions called before redisplay, if window sizes have changed.
21650 The value should be a list of functions that take one argument.
21651 Just before redisplay, for each frame, if any of its windows have changed
21652 size since the last redisplay, or have been split or deleted,
21653 all the functions in the list are called, with the frame as argument. */);
21654 Vwindow_size_change_functions = Qnil;
21655
21656 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
21657 doc: /* List of Functions to call before redisplaying a window with scrolling.
21658 Each function is called with two arguments, the window
21659 and its new display-start position. Note that the value of `window-end'
21660 is not valid when these functions are called. */);
21661 Vwindow_scroll_functions = Qnil;
21662
21663 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
21664 doc: /* *Non-nil means autoselect window with mouse pointer. */);
21665 mouse_autoselect_window = 0;
21666
21667 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
21668 doc: /* *Non-nil means automatically resize tool-bars.
21669 This increases a tool-bar's height if not all tool-bar items are visible.
21670 It decreases a tool-bar's height when it would display blank lines
21671 otherwise. */);
21672 auto_resize_tool_bars_p = 1;
21673
21674 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
21675 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
21676 auto_raise_tool_bar_buttons_p = 1;
21677
21678 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
21679 doc: /* *Margin around tool-bar buttons in pixels.
21680 If an integer, use that for both horizontal and vertical margins.
21681 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
21682 HORZ specifying the horizontal margin, and VERT specifying the
21683 vertical margin. */);
21684 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
21685
21686 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
21687 doc: /* *Relief thickness of tool-bar buttons. */);
21688 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
21689
21690 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
21691 doc: /* List of functions to call to fontify regions of text.
21692 Each function is called with one argument POS. Functions must
21693 fontify a region starting at POS in the current buffer, and give
21694 fontified regions the property `fontified'. */);
21695 Vfontification_functions = Qnil;
21696 Fmake_variable_buffer_local (Qfontification_functions);
21697
21698 DEFVAR_BOOL ("unibyte-display-via-language-environment",
21699 &unibyte_display_via_language_environment,
21700 doc: /* *Non-nil means display unibyte text according to language environment.
21701 Specifically this means that unibyte non-ASCII characters
21702 are displayed by converting them to the equivalent multibyte characters
21703 according to the current language environment. As a result, they are
21704 displayed according to the current fontset. */);
21705 unibyte_display_via_language_environment = 0;
21706
21707 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
21708 doc: /* *Maximum height for resizing mini-windows.
21709 If a float, it specifies a fraction of the mini-window frame's height.
21710 If an integer, it specifies a number of lines. */);
21711 Vmax_mini_window_height = make_float (0.25);
21712
21713 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
21714 doc: /* *How to resize mini-windows.
21715 A value of nil means don't automatically resize mini-windows.
21716 A value of t means resize them to fit the text displayed in them.
21717 A value of `grow-only', the default, means let mini-windows grow
21718 only, until their display becomes empty, at which point the windows
21719 go back to their normal size. */);
21720 Vresize_mini_windows = Qgrow_only;
21721
21722 DEFVAR_LISP ("cursor-in-non-selected-windows",
21723 &Vcursor_in_non_selected_windows,
21724 doc: /* *Cursor type to display in non-selected windows.
21725 t means to use hollow box cursor. See `cursor-type' for other values. */);
21726 Vcursor_in_non_selected_windows = Qt;
21727
21728 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
21729 doc: /* Alist specifying how to blink the cursor off.
21730 Each element has the form (ON-STATE . OFF-STATE). Whenever the
21731 `cursor-type' frame-parameter or variable equals ON-STATE,
21732 comparing using `equal', Emacs uses OFF-STATE to specify
21733 how to blink it off. */);
21734 Vblink_cursor_alist = Qnil;
21735
21736 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
21737 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
21738 automatic_hscrolling_p = 1;
21739
21740 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
21741 doc: /* *How many columns away from the window edge point is allowed to get
21742 before automatic hscrolling will horizontally scroll the window. */);
21743 hscroll_margin = 5;
21744
21745 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
21746 doc: /* *How many columns to scroll the window when point gets too close to the edge.
21747 When point is less than `automatic-hscroll-margin' columns from the window
21748 edge, automatic hscrolling will scroll the window by the amount of columns
21749 determined by this variable. If its value is a positive integer, scroll that
21750 many columns. If it's a positive floating-point number, it specifies the
21751 fraction of the window's width to scroll. If it's nil or zero, point will be
21752 centered horizontally after the scroll. Any other value, including negative
21753 numbers, are treated as if the value were zero.
21754
21755 Automatic hscrolling always moves point outside the scroll margin, so if
21756 point was more than scroll step columns inside the margin, the window will
21757 scroll more than the value given by the scroll step.
21758
21759 Note that the lower bound for automatic hscrolling specified by `scroll-left'
21760 and `scroll-right' overrides this variable's effect. */);
21761 Vhscroll_step = make_number (0);
21762
21763 DEFVAR_LISP ("image-types", &Vimage_types,
21764 doc: /* List of supported image types.
21765 Each element of the list is a symbol for a supported image type. */);
21766 Vimage_types = Qnil;
21767
21768 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
21769 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
21770 Bind this around calls to `message' to let it take effect. */);
21771 message_truncate_lines = 0;
21772
21773 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
21774 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
21775 Can be used to update submenus whose contents should vary. */);
21776 Vmenu_bar_update_hook = Qnil;
21777
21778 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
21779 doc: /* Non-nil means don't update menu bars. Internal use only. */);
21780 inhibit_menubar_update = 0;
21781
21782 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
21783 doc: /* Non-nil means don't eval Lisp during redisplay. */);
21784 inhibit_eval_during_redisplay = 0;
21785
21786 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
21787 doc: /* Non-nil means don't free realized faces. Internal use only. */);
21788 inhibit_free_realized_faces = 0;
21789
21790 #if GLYPH_DEBUG
21791 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
21792 doc: /* Inhibit try_window_id display optimization. */);
21793 inhibit_try_window_id = 0;
21794
21795 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
21796 doc: /* Inhibit try_window_reusing display optimization. */);
21797 inhibit_try_window_reusing = 0;
21798
21799 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
21800 doc: /* Inhibit try_cursor_movement display optimization. */);
21801 inhibit_try_cursor_movement = 0;
21802 #endif /* GLYPH_DEBUG */
21803 }
21804
21805
21806 /* Initialize this module when Emacs starts. */
21807
21808 void
21809 init_xdisp ()
21810 {
21811 Lisp_Object root_window;
21812 struct window *mini_w;
21813
21814 current_header_line_height = current_mode_line_height = -1;
21815
21816 CHARPOS (this_line_start_pos) = 0;
21817
21818 mini_w = XWINDOW (minibuf_window);
21819 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
21820
21821 if (!noninteractive)
21822 {
21823 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
21824 int i;
21825
21826 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
21827 set_window_height (root_window,
21828 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
21829 0);
21830 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
21831 set_window_height (minibuf_window, 1, 0);
21832
21833 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
21834 mini_w->total_cols = make_number (FRAME_COLS (f));
21835
21836 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
21837 scratch_glyph_row.glyphs[TEXT_AREA + 1]
21838 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
21839
21840 /* The default ellipsis glyphs `...'. */
21841 for (i = 0; i < 3; ++i)
21842 default_invis_vector[i] = make_number ('.');
21843 }
21844
21845 {
21846 /* Allocate the buffer for frame titles.
21847 Also used for `format-mode-line'. */
21848 int size = 100;
21849 frame_title_buf = (char *) xmalloc (size);
21850 frame_title_buf_end = frame_title_buf + size;
21851 frame_title_ptr = NULL;
21852 }
21853
21854 help_echo_showing_p = 0;
21855 }
21856
21857
21858 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
21859 (do not change this comment) */